Skip to content
Snippets Groups Projects
Verified Commit 28fa5862 authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

[PAM] Fix and properly document PAM token handling code

parent af019b9a
No related branches found
No related tags found
No related merge requests found
...@@ -398,6 +398,7 @@ fn get_original_euid() -> uid_t { ...@@ -398,6 +398,7 @@ fn get_original_euid() -> uid_t {
unsafe { unsafe {
if !original_euid_set { if !original_euid_set {
original_euid = geteuid(); original_euid = geteuid();
debug!("Original EUID stored as {}", original_euid);
original_euid_set = true; original_euid_set = true;
} }
original_euid original_euid
...@@ -412,5 +413,8 @@ lazy_static! { ...@@ -412,5 +413,8 @@ lazy_static! {
static ref CONTEXT_USER: Mutex<UserInfo> = Mutex::new(UserInfo::new()); static ref CONTEXT_USER: Mutex<UserInfo> = Mutex::new(UserInfo::new());
} }
pub fn get_context_user() -> MutexGuard<'static, UserInfo> { pub fn get_context_user() -> MutexGuard<'static, UserInfo> {
// Ensure original EUID is set before first action on context user
get_original_euid();
CONTEXT_USER.lock().unwrap() CONTEXT_USER.lock().unwrap()
} }
...@@ -92,12 +92,28 @@ impl PamServiceModule for PamOidc { ...@@ -92,12 +92,28 @@ 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);
// Cast a a butt-backwards somersault to get the token where it belongs
// This is because we cannot store the token in the user's home directory
// without resolving the user through getpwnam, and we (probably) cannot
// do getpwnam without having the user's access token, and we (certainly)
// cannot do getpwnam form inside the UserInfo cache object while having
// the UserInfo cache object locked for PAM. Therefore...
// 1. ...mark getpwnam unsafe (prevent cache code from calling it)
set_is_getpwnam_safe(false); set_is_getpwnam_safe(false);
// 2. ...store the access token (will not go through to $HOME, as getpwnam
// is locked)
get_context_user().set_access_token(t.clone());
// 3. ...call getpwnam ourselves without having the cache object locked
let passwd = getpwnam_safe(username.to_string()); let passwd = getpwnam_safe(username.to_string());
if passwd.is_ok() { if passwd.is_ok() {
// 4. ...if getpwnam was successful, store the token again (this time,
// modulo other errors, it will go through to $HOME)
get_context_user().set_passwd(passwd.unwrap()); get_context_user().set_passwd(passwd.unwrap());
get_context_user().set_access_token(t.clone());
} }
get_context_user().set_access_token(t); // 5. ...unlock getpwnam again (somewhat unnecessary)
set_is_getpwnam_safe(true); set_is_getpwnam_safe(true);
return PamError::SUCCESS; return PamError::SUCCESS;
}, },
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment