Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
N
nss-pam-webapi
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Monitor
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
magicfelix
nss-pam-webapi
Commits
7583deeb
Verified
Commit
7583deeb
authored
4 years ago
by
Nik | Klampfradler
Browse files
Options
Downloads
Patches
Plain Diff
Cache all user information as early as possible and re-use without lookup if needed
parent
4aebf539
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/cache.rs
+171
-98
171 additions, 98 deletions
src/cache.rs
src/nss.rs
+21
-48
21 additions, 48 deletions
src/nss.rs
src/pam.rs
+2
-1
2 additions, 1 deletion
src/pam.rs
with
194 additions
and
147 deletions
src/cache.rs
+
171
−
98
View file @
7583deeb
...
@@ -15,11 +15,10 @@
...
@@ -15,11 +15,10 @@
*/
*/
use
crate
::
BASE_NAME
;
use
crate
::
BASE_NAME
;
use
crate
::
unix
::
getpwnam_safe
;
use
crate
::
unix
::
{
Passwd
,
getpwnam_safe
,
getpwuid_safe
}
;
use
lazy_static
::
lazy_static
;
use
lazy_static
::
lazy_static
;
use
std
::
collections
::
HashMap
;
use
std
::
sync
::{
Mutex
,
MutexGuard
};
use
std
::
sync
::{
RwLock
,
RwLockReadGuard
};
use
libc
::{
geteuid
,
seteuid
,
uid_t
};
use
libc
::{
geteuid
,
seteuid
,
uid_t
};
...
@@ -37,119 +36,211 @@ use serde_json;
...
@@ -37,119 +36,211 @@ use serde_json;
const
USER_TOKEN_FILENAME
:
&
str
=
"user_token.json"
;
const
USER_TOKEN_FILENAME
:
&
str
=
"user_token.json"
;
struct
UserInfo
{
uid
:
Option
<
uid_t
>
,
username
:
Option
<
String
>
,
passwd
:
Option
<
Passwd
>
,
access_token
:
Option
<
BasicTokenResponse
>
}
pub
struct
Cache
{
pub
struct
Cache
{
user_tokens
:
HashMap
<
String
,
BasicTokenResponse
>
,
pub
context_user
:
UserInfo
original_euid
:
uid_t
,
}
}
impl
Cache
{
impl
Cache
{
pub
fn
new
()
->
Cache
{
pub
fn
new
()
->
Cache
{
let
euid
;
let
euid
=
unsafe
{
unsafe
{
geteuid
()
euid
=
geteuid
();
};
};
Cache
{
Cache
{
user_tokens
:
HashMap
::
new
(),
context_user
:
UserInfo
{
original_euid
:
euid
uid
:
None
,
username
:
None
,
passwd
:
None
,
access_token
:
None
}
}
}
}
}
}
impl
UserInfo
{
pub
fn
set_current_user
(
&
mut
self
)
{
self
.set_uid
(
original_euid
);
}
pub
fn
is_initialized
(
&
self
)
->
bool
{
self
.uid
.is_some
()
||
self
.username
.is_some
()
}
fn
drop_privileges
(
&
self
,
username
:
&
String
)
->
Result
<
uid_t
,
io
::
Error
>
{
fn
try_resolve
(
&
mut
self
)
->
Result
<&
Passwd
,
io
::
Error
>
{
let
current_euid
;
// If we already have a full passwd struct, return it as without resolving
unsafe
{
if
self
.passwd
.is_some
()
{
current_euid
=
geteuid
();
debug!
(
"passwd entry for context user already resolved"
);
return
Ok
(
self
.passwd
.as_ref
()
.unwrap
());
}
// If we cannot call getpwnam safely, return error (see `is_get_pwnam_safe`)
if
!
is_getpwnam_safe
()
{
let
msg
=
"Context user cannot be resolved safely right now"
;
warn!
(
"{}"
,
msg
);
return
Err
(
io
::
Error
::
new
(
io
::
ErrorKind
::
WouldBlock
,
msg
));
}
// Try one of the partial information to resolve
let
res
=
match
self
.uid
{
Some
(
uid
)
=>
getpwuid_safe
(
uid
),
None
=>
match
&
self
.username
{
Some
(
username
)
=>
getpwnam_safe
(
username
.to_string
()),
None
=>
{
let
msg
=
"No partial information set to use for getpwnam / getpwuid"
;
warn!
(
"{}"
,
msg
);
Err
(
io
::
Error
::
new
(
io
::
ErrorKind
::
InvalidInput
,
msg
))
}
}
};
};
match
res
{
Ok
(
passwd
)
=>
{
debug!
(
"Successfully resolved context user's passwd entry"
);
self
.passwd
=
Some
(
passwd
);
Ok
(
self
.passwd
.as_ref
()
.unwrap
())
},
Err
(
e
)
=>
Err
(
e
)
}
}
pub
fn
get_uid
(
&
mut
self
)
->
Result
<
uid_t
,
io
::
Error
>
{
match
self
.try_resolve
()
{
Ok
(
passwd
)
=>
Ok
(
passwd
.pw_uid
),
Err
(
e
)
=>
match
self
.uid
{
Some
(
uid
)
=>
Ok
(
uid
),
None
=>
Err
(
e
)
}
}
}
pub
fn
set_uid
(
&
mut
self
,
uid
:
uid_t
)
{
self
.uid
=
Some
(
uid
);
self
.username
=
None
;
self
.passwd
=
None
;
self
.try_resolve
();
}
let
pw
=
match
getpwnam_safe
(
username
.to_string
())
{
pub
fn
get_username
(
&
mut
self
)
->
Result
<
String
,
io
::
Error
>
{
Ok
(
p
)
=>
p
,
match
self
.try_resolve
()
{
Ok
(
passwd
)
=>
Ok
(
&
passwd
.pw_name
),
Err
(
e
)
=>
match
self
.username
{
Some
(
username
)
=>
Ok
(
username
),
None
=>
Err
(
e
)
}
}
}
pub
fn
set_username
(
&
mut
self
,
username
:
String
)
{
self
.username
=
Some
(
username
);
self
.uid
=
None
;
self
.passwd
=
None
;
self
.try_resolve
();
}
pub
fn
get_home_directory
(
&
mut
self
)
->
Result
<
String
,
io
::
Error
>
{
match
self
.try_resolve
()
{
Ok
(
passwd
)
=>
Ok
(
passwd
.pw_dir
),
Err
(
e
)
=>
Err
(
e
)
}
}
fn
drop_privileges
(
&
self
)
->
Result
<
uid_t
,
io
::
Error
>
{
let
current_euid
=
unsafe
{
geteuid
()
};
let
target_euid
=
match
self
.get_uid
()
{
Ok
(
uid
)
=>
uid
,
Err
(
e
)
=>
{
Err
(
e
)
=>
{
error!
(
"
Failed to lookup user {}: {}"
,
username
,
e
);
error!
(
"
Could not drop privileges because target UID is not resolved"
);
return
Err
(
e
);
return
Err
(
e
);
}
}
};
};
debug!
(
"Lookup for user {} returned UID {}, GID {}"
,
username
,
pw
.pw_uid
,
pw
.pw_gid
);
let
target_euid
=
pw
.pw_uid
;
if
target_euid
==
current_euid
{
if
target_euid
==
current_euid
{
debug!
(
"No need to drop privileges, already running as {}"
,
username
);
debug!
(
"No need to drop privileges, already running as {}"
,
current_euid
);
return
Ok
(
current_euid
);
return
Ok
(
current_euid
);
}
}
let
res
;
let
res
=
unsafe
{
unsafe
{
seteuid
(
target_euid
)
res
=
seteuid
(
target_euid
);
};
};
if
res
==
0
{
if
res
==
0
{
debug!
(
"Successfully dropped privileges to {}"
,
username
);
debug!
(
"Successfully dropped privileges to {}"
,
target_euid
);
return
Ok
(
target_euid
);
return
Ok
(
target_euid
);
}
else
{
}
else
{
let
e
=
io
::
Error
::
last_os_error
();
let
e
=
io
::
Error
::
last_os_error
();
error!
(
"Could not drop privileges to {}"
,
username
);
error!
(
"Could not drop privileges to {}"
,
target_euid
);
return
Err
(
e
);
return
Err
(
e
);
}
}
}
}
fn
restore_privileges
(
&
self
)
{
fn
restore_privileges
(
&
self
)
{
let
current_euid
;
let
current_euid
=
unsafe
{
unsafe
{
geteuid
()
current_euid
=
geteuid
();
};
};
if
current_euid
!=
self
.
original_euid
{
if
current_euid
!=
original_euid
{
debug!
(
"Restoring privileges"
);
debug!
(
"Restoring privileges"
);
let
res
;
let
res
=
unsafe
{
unsafe
{
seteuid
(
original_euid
)
res
=
seteuid
(
self
.original_euid
);
};
};
if
res
!=
0
{
if
res
!=
0
{
panic!
(
"Could not restore privileges to {}"
,
self
.
original_euid
);
panic!
(
"Could not restore privileges to {}"
,
original_euid
);
}
}
}
else
{
}
else
{
debug!
(
"No need to restore privileges, already running as original user"
);
debug!
(
"No need to restore privileges, already running as original user"
);
}
}
}
}
fn
get_user_xdg_base_directories
(
&
self
,
username
:
&
String
)
->
Result
<
BaseDirectories
,
io
::
Error
>
{
fn
get_user_xdg_base_directories
(
&
mut
self
)
->
Result
<
BaseDirectories
,
io
::
Error
>
{
// Save original $HOME for later restore
let
saved_home
=
env
::
var_os
(
"HOME"
);
let
saved_home
=
env
::
var_os
(
"HOME"
);
let
pw
=
match
getpwnam_safe
(
username
.to_string
())
{
// Determine user ID to find out whether we should override $HOME
Ok
(
p
)
=>
p
,
let
uid
=
self
.get_uid
()
?
;
Err
(
e
)
=>
{
if
uid
!=
original_euid
{
error!
(
"Failed to lookup user {}: {}"
,
username
,
e
);
let
user_home
=
self
.get_home_directory
()
?
;
return
Err
(
e
);
env
::
set_var
(
"HOME"
,
user_home
);
}
debug!
(
"Home directory for UID {} is {}"
,
uid
,
user_home
);
};
}
debug!
(
"Lookup for user {} returned UID {}, GID {}"
,
username
,
pw
.pw_uid
,
pw
.pw_gid
);
let
user_home
=
pw
.pw_dir
;
env
::
set_var
(
"HOME"
,
&
user_home
);
debug!
(
"Home directory for {} is {}"
,
username
,
user_home
);
// Determine XDG directories now
let
base_dirs
=
match
BaseDirectories
::
with_prefix
(
BASE_NAME
)
{
let
base_dirs
=
match
BaseDirectories
::
with_prefix
(
BASE_NAME
)
{
Ok
(
b
)
=>
b
,
Ok
(
b
)
=>
b
,
Err
(
e
)
=>
return
Err
(
io
::
Error
::
new
(
io
::
ErrorKind
::
Other
,
e
))
Err
(
e
)
=>
return
Err
(
io
::
Error
::
new
(
io
::
ErrorKind
::
Other
,
e
))
};
};
if
saved_home
!=
None
{
env
::
set_var
(
"HOME"
,
saved_home
.unwrap
());
// Restore $HOME to original if we changed it earlier
}
else
{
if
uid
!=
original_euid
{
env
::
remove_var
(
"HOME"
);
if
saved_home
!=
None
{
env
::
set_var
(
"HOME"
,
saved_home
.unwrap
());
}
else
{
env
::
remove_var
(
"HOME"
);
}
}
}
return
Ok
(
base_dirs
);
return
Ok
(
base_dirs
);
}
}
fn
place_user_cache_file
(
&
self
,
username
:
&
String
,
filename
:
String
)
->
Result
<
PathBuf
,
io
::
Error
>
{
fn
place_user_cache_file
(
&
mut
self
,
filename
:
String
)
->
Result
<
PathBuf
,
io
::
Error
>
{
match
self
.get_user_xdg_base_directories
(
username
)
{
match
self
.get_user_xdg_base_directories
()
{
Ok
(
b
)
=>
b
.place_cache_file
(
filename
),
Ok
(
b
)
=>
b
.place_cache_file
(
filename
),
Err
(
e
)
=>
Err
(
io
::
Error
::
new
(
io
::
ErrorKind
::
NotFound
,
e
)
)
Err
(
e
)
=>
Err
(
e
)
}
}
}
}
pub
fn
load_user_token
(
&
self
,
owner
:
&
String
)
->
Option
<
&
BasicTokenResponse
>
{
pub
fn
get_access_token
(
&
mut
self
)
->
Option
<
BasicTokenResponse
>
{
if
!
self
.user_tokens
.contains_key
(
owner
)
{
// Try to load our acess token if none is known
debug!
(
"No token for {} in memory, trying to load from file"
,
owner
);
if
self
.access_token
.is_none
()
{
debug!
(
"No token in memory, trying to load from file"
);
self
.drop_privileges
(
owner
)
.ok
();
self
.drop_privileges
()
.ok
();
let
new
_token
=
match
self
.place_user_cache_file
(
owner
,
USER_TOKEN_FILENAME
.to_string
())
{
self
.access
_token
=
match
self
.place_user_cache_file
(
USER_TOKEN_FILENAME
.to_string
())
{
Ok
(
path
)
=>
match
load_json
(
path
)
{
Ok
(
path
)
=>
match
load_json
(
path
)
{
Ok
(
read_token
)
=>
Some
(
read_token
),
Ok
(
read_token
)
=>
Some
(
read_token
),
Err
(
_
)
=>
None
Err
(
_
)
=>
None
...
@@ -157,55 +248,29 @@ impl Cache {
...
@@ -157,55 +248,29 @@ impl Cache {
Err
(
_
)
=>
None
Err
(
_
)
=>
None
};
};
self
.restore_privileges
();
self
.restore_privileges
();
match
new_token
{
Some
(
t
)
=>
{
CACHE
.write
()
.unwrap
()
.user_tokens
.insert
(
owner
.to_string
(),
t
);
self
.user_tokens
.get
(
owner
)
},
None
=>
None
}
}
else
{
debug!
(
"Found token for {} in memory"
,
owner
);
self
.user_tokens
.get
(
owner
)
}
}
return
self
.access_token
;
}
}
pub
fn
s
ave_user_token
(
&
self
,
owner
:
&
String
,
token
:
BasicTokenResponse
)
->
Result
<
(),
io
::
Error
>
{
pub
fn
s
et_access_token
(
&
mut
self
,
token
:
BasicTokenResponse
)
->
Result
<
(),
io
::
Error
>
{
CACHE
.write
()
.unwrap
()
.user_tokens
.insert
(
owner
.to_string
(),
token
.clone
());
self
.access_token
=
Some
(
token
.clone
());
debug!
(
"Saved token for
{}
in memory"
,
owner
);
debug!
(
"Saved token for in memory"
);
// Try to write user's token cache file
// Try to write user's token cache file
let
res
=
match
self
.drop_privileges
(
owner
)
{
let
res
=
match
self
.drop_privileges
()
{
Ok
(
_
)
=>
match
self
.place_user_cache_file
(
owner
,
USER_TOKEN_FILENAME
.to_string
())
{
Ok
(
_
)
=>
match
self
.place_user_cache_file
(
USER_TOKEN_FILENAME
.to_string
())
{
Ok
(
path
)
=>
{
Ok
(
path
)
=>
{
debug!
(
"Storing token for
{}
in cache file"
,
owner
);
debug!
(
"Storing token for in cache file"
);
save_json
(
path
,
token
)
save_json
(
path
,
token
)
},
},
Err
(
e
)
=>
Err
(
e
)
Err
(
e
)
=>
Err
(
e
)
},
},
Err
(
e
)
=>
Err
(
io
::
Error
::
new
(
io
::
ErrorKind
::
PermissionDenied
,
e
)
)
Err
(
e
)
=>
Err
(
e
)
};
};
self
.restore_privileges
();
self
.restore_privileges
();
return
res
;
return
res
;
}
}
pub
fn
delete_user_token
(
&
self
,
owner
:
&
String
)
{
CACHE
.write
()
.unwrap
()
.user_tokens
.remove
(
owner
);
debug!
(
"Token for {} removed from memory"
,
owner
);
// Try to remove user's token cache file
self
.drop_privileges
(
owner
)
.ok
();
match
self
.place_user_cache_file
(
owner
,
USER_TOKEN_FILENAME
.to_string
())
{
Ok
(
path
)
=>
{
debug!
(
"Deleting cache file for {}"
,
owner
);
fs
::
remove_file
(
path
)
.ok
();
()
},
Err
(
e
)
=>
()
};
self
.restore_privileges
();
}
}
}
fn
load_json
<
O
:
DeserializeOwned
>
(
path
:
PathBuf
)
->
Result
<
O
,
io
::
Error
>
{
fn
load_json
<
O
:
DeserializeOwned
>
(
path
:
PathBuf
)
->
Result
<
O
,
io
::
Error
>
{
...
@@ -226,10 +291,18 @@ fn save_json<O: Serialize>(path: PathBuf, obj: O) -> Result<(), io::Error> {
...
@@ -226,10 +291,18 @@ fn save_json<O: Serialize>(path: PathBuf, obj: O) -> Result<(), io::Error> {
fs
::
write
(
path
,
json
)
fs
::
write
(
path
,
json
)
}
}
lazy_static!
{
fn
is_getpwnam_safe
()
->
bool
{
static
ref
CACHE
:
RwLock
<
Cache
>
=
RwLock
::
new
(
Cache
::
new
());
// FIXME Implement real logic
return
true
;
}
}
pub
fn
get_cache
()
->
RwLockReadGuard
<
'static
,
Cache
>
{
static
original_euid
:
uid_t
=
unsafe
{
CACHE
.read
()
.unwrap
()
geteuid
()
};
lazy_static!
{
static
ref
CACHE
:
Mutex
<
Cache
>
=
Mutex
::
new
(
Cache
::
new
());
}
pub
fn
get_cache
()
->
MutexGuard
<
'static
,
Cache
>
{
CACHE
.lock
()
.unwrap
()
}
}
This diff is collapsed.
Click to expand it.
src/nss.rs
+
21
−
48
View file @
7583deeb
...
@@ -16,7 +16,6 @@
...
@@ -16,7 +16,6 @@
use
crate
::
config
::{
use
crate
::
config
::{
get_config
,
get_config
,
get_optional
,
get_optional
,
get_or_error
};
};
use
config
::
Config
;
use
config
::
Config
;
use
crate
::
cache
::
get_cache
;
use
crate
::
cache
::
get_cache
;
...
@@ -26,10 +25,6 @@ use crate::logging::setup_log;
...
@@ -26,10 +25,6 @@ use crate::logging::setup_log;
use
crate
::
oauth
::{
get_access_token_client
,
get_data_jq
};
use
crate
::
oauth
::{
get_access_token_client
,
get_data_jq
};
use
serde
::{
Serialize
,
Deserialize
};
use
serde
::{
Serialize
,
Deserialize
};
use
std
::
ffi
::
CStr
;
use
libc
::
geteuid
;
use
crate
::
unix
::
getpwuid_safe
;
use
libnss
::
interop
::
Response
;
use
libnss
::
interop
::
Response
;
use
libnss
::
passwd
::{
PasswdHooks
,
Passwd
};
use
libnss
::
passwd
::{
PasswdHooks
,
Passwd
};
...
@@ -58,40 +53,25 @@ fn nss_hook_prepare() -> Config {
...
@@ -58,40 +53,25 @@ fn nss_hook_prepare() -> Config {
return
conf
;
return
conf
;
}
}
fn
get_current_user
()
->
String
{
let
euid
;
unsafe
{
euid
=
geteuid
();
};
match
getpwuid_safe
(
euid
)
{
Ok
(
p
)
=>
p
.pw_name
,
Err
(
e
)
=>
{
error!
(
"Failed to lookup username for UID {}: {}"
,
euid
,
e
);
/* FIXME: return something (empty string?) to make the caller bail out early */
"nobody"
.to_string
()
}
}
}
struct
OidcPasswd
;
struct
OidcPasswd
;
impl
PasswdHooks
for
OidcPasswd
{
impl
PasswdHooks
for
OidcPasswd
{
fn
get_all_entries
()
->
Response
<
Vec
<
Passwd
>>
{
fn
get_all_entries
()
->
Response
<
Vec
<
Passwd
>>
{
let
conf
=
nss_hook_prepare
();
let
conf
=
nss_hook_prepare
();
let
mut
cache
=
get_cache
();
let
user
=
get_current_user
();
// Set the context user to the current user, but only if not already set
let
ctc
;
// When doing PAM, we might get called back into by libc to do some NSS
let
token
=
match
cache
.load_user_token
(
&
user
)
{
// lookup, and we want to keep the PAM login user context in that case
if
!
get_cache
()
.context_user
.is_initialized
()
{
get_cache
()
.context_user
.set_current_user
();
}
let
token
=
match
get_cache
()
.context_user
.get_access_token
()
{
Some
(
t
)
=>
t
,
Some
(
t
)
=>
t
,
None
=>
{
None
=>
{
// FIXME Implement caching of system token
// FIXME Implement caching of system token
debug!
(
"Could not find a user token
for {}
to request NSS data; trying client credentials"
,
user
);
debug!
(
"Could not find a user token to request NSS data; trying client credentials"
);
match
get_access_token_client
(
&
conf
,
"nss"
,
""
,
""
)
{
match
get_access_token_client
(
&
conf
,
"nss"
,
""
,
""
)
{
Ok
(
ct
)
=>
{
Ok
(
ct
)
=>
ct
,
ctc
=
ct
.clone
();
&
ctc
},
Err
(
e
)
=>
{
Err
(
e
)
=>
{
error!
(
"Failed to get access token with client credentials: {}"
,
e
);
error!
(
"Failed to get access token with client credentials: {}"
,
e
);
return
Response
::
Unavail
;
return
Response
::
Unavail
;
...
@@ -112,20 +92,17 @@ impl PasswdHooks for OidcPasswd {
...
@@ -112,20 +92,17 @@ impl PasswdHooks for OidcPasswd {
fn
get_entry_by_uid
(
uid
:
libc
::
uid_t
)
->
Response
<
Passwd
>
{
fn
get_entry_by_uid
(
uid
:
libc
::
uid_t
)
->
Response
<
Passwd
>
{
let
conf
=
nss_hook_prepare
();
let
conf
=
nss_hook_prepare
();
let
mut
cache
=
get_cache
();
let
user
=
get_current_user
();
if
!
get_cache
()
.context_user
.is_initialized
()
{
let
ctc
;
get_cache
()
.context_user
.set_current_user
();
let
token
=
match
cache
.load_user_token
(
&
user
)
{
}
let
token
=
match
get_cache
()
.context_user
.get_access_token
()
{
Some
(
t
)
=>
t
,
Some
(
t
)
=>
t
,
None
=>
{
None
=>
{
// FIXME Implement caching of system token
// FIXME Implement caching of system token
debug!
(
"Could not find a user token
for {}
to request NSS data; trying client credentials"
,
user
);
debug!
(
"Could not find a user token to request NSS data; trying client credentials"
);
match
get_access_token_client
(
&
conf
,
"nss"
,
""
,
""
)
{
match
get_access_token_client
(
&
conf
,
"nss"
,
""
,
""
)
{
Ok
(
ct
)
=>
{
Ok
(
ct
)
=>
ct
,
ctc
=
ct
.clone
();
&
ctc
},
Err
(
e
)
=>
{
Err
(
e
)
=>
{
error!
(
"Failed to get access token with client credentials: {}"
,
e
);
error!
(
"Failed to get access token with client credentials: {}"
,
e
);
return
Response
::
Unavail
;
return
Response
::
Unavail
;
...
@@ -146,20 +123,16 @@ impl PasswdHooks for OidcPasswd {
...
@@ -146,20 +123,16 @@ impl PasswdHooks for OidcPasswd {
fn
get_entry_by_name
(
name
:
String
)
->
Response
<
Passwd
>
{
fn
get_entry_by_name
(
name
:
String
)
->
Response
<
Passwd
>
{
let
conf
=
nss_hook_prepare
();
let
conf
=
nss_hook_prepare
();
let
mut
cache
=
get_cache
();
if
!
get_cache
()
.context_user
.is_initialized
()
{
get_cache
()
.context_user
.set_current_user
();
let
user
=
get_current_user
();
}
let
ctc
;
let
token
=
match
get_cache
()
.context_user
.get_access_token
()
{
let
token
=
match
cache
.load_user_token
(
&
user
)
{
Some
(
t
)
=>
t
,
Some
(
t
)
=>
t
,
None
=>
{
None
=>
{
// FIXME Implement caching of system token
// FIXME Implement caching of system token
debug!
(
"Could not find a user token for
{}
to request NSS data; trying client credentials"
,
user
);
debug!
(
"Could not find a user token for to request NSS data; trying client credentials"
);
match
get_access_token_client
(
&
conf
,
"nss"
,
""
,
""
)
{
match
get_access_token_client
(
&
conf
,
"nss"
,
""
,
""
)
{
Ok
(
ct
)
=>
{
Ok
(
ct
)
=>
ct
,
ctc
=
ct
.clone
();
&
ctc
},
Err
(
e
)
=>
{
Err
(
e
)
=>
{
error!
(
"Failed to get access token with client credentials: {}"
,
e
);
error!
(
"Failed to get access token with client credentials: {}"
,
e
);
return
Response
::
Unavail
;
return
Response
::
Unavail
;
...
...
This diff is collapsed.
Click to expand it.
src/pam.rs
+
2
−
1
View file @
7583deeb
...
@@ -90,7 +90,8 @@ impl PamServiceModule for PamOidc {
...
@@ -90,7 +90,8 @@ impl PamServiceModule for PamOidc {
match
get_access_token_password
(
&
conf
,
"pam"
,
username
.to_string
(),
password
.to_string
(),
PamError
::
SERVICE_ERR
,
PamError
::
AUTH_ERR
)
{
match
get_access_token_password
(
&
conf
,
"pam"
,
username
.to_string
(),
password
.to_string
(),
PamError
::
SERVICE_ERR
,
PamError
::
AUTH_ERR
)
{
Ok
(
t
)
=>
{
Ok
(
t
)
=>
{
info!
(
"Authenticated {} using Resource Owner Password Grant"
,
username
);
info!
(
"Authenticated {} using Resource Owner Password Grant"
,
username
);
get_cache
()
.save_user_token
(
&
username
.to_string
(),
t
.into
());
get_cache
()
.context_user
.set_username
(
username
.to_string
());
get_cache
()
.context_user
.set_access_token
(
t
);
return
PamError
::
SUCCESS
;
return
PamError
::
SUCCESS
;
},
},
Err
(
e
)
=>
{
Err
(
e
)
=>
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment