From 832d9e4a5bac96310168f752c083c7616099320b Mon Sep 17 00:00:00 2001 From: Dominik George <dominik.george@teckids.org> Date: Wed, 19 May 2021 11:10:29 +0200 Subject: [PATCH] [Cache] Add `persist` flag to tell `set_access_token` whether to write to $HOME or not --- src/cache.rs | 41 +++++++++++++++++++++++------------------ src/pam.rs | 7 +++---- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 63e792e..b31f4da 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -311,31 +311,36 @@ impl UserInfo { /// /// This will store the token in memory in the `access_token` slot, and attempt to /// write the token to disk afterwards - pub fn set_access_token(&mut self, token: BasicTokenResponse) -> Result<(), io::Error> { + pub fn set_access_token(&mut self, token: BasicTokenResponse, persist: bool) -> Result<(), io::Error> { self.access_token = Some(token.clone()); debug!("Saved token in memory"); - // Try to write user's token cache file - // We need to ensure privileges were dropped successfully to avoid symlink attacks - // cf. https://capec.mitre.org/data/definitions/132.html - let res = match self.drop_privileges() { - Ok(_) => match self.place_user_cache_file(USER_TOKEN_FILENAME.to_string()) { - Ok(path) => { - debug!("Storing token for in cache file"); - save_json(path, token) + if persist { + // Try to write user's token cache file + // We need to ensure privileges were dropped successfully to avoid symlink attacks + // cf. https://capec.mitre.org/data/definitions/132.html + let res = match self.drop_privileges() { + Ok(_) => match self.place_user_cache_file(USER_TOKEN_FILENAME.to_string()) { + Ok(path) => { + debug!("Storing token for in cache file"); + save_json(path, token) + }, + Err(e) => { + error!("Error getting cache path in user home: {}", e); + Err(e) + } }, Err(e) => { - error!("Error getting cache path in user home: {}", e); + error!("Error dropping privileges to store token in user home: {}", e); Err(e) } - }, - Err(e) => { - error!("Error dropping privileges to store token in user home: {}", e); - Err(e) - } - }; - restore_privileges(); - return res; + }; + restore_privileges(); + + res + } else { + Ok(()) + } } } diff --git a/src/pam.rs b/src/pam.rs index 5893989..e3c973d 100644 --- a/src/pam.rs +++ b/src/pam.rs @@ -102,16 +102,15 @@ impl PamServiceModule for PamOidc { // 1. ...mark getpwnam unsafe (prevent cache code from calling it) 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()).ok(); + // 2. ...store the access token in memory + get_context_user().set_access_token(t.clone(), false).ok(); // 3. ...call getpwnam ourselves without having the cache object locked let passwd = getpwnam_safe(username.to_string()); 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_access_token(t.clone()).ok(); + get_context_user().set_access_token(t.clone(), true).ok(); } // 5. ...unlock getpwnam again (somewhat unnecessary) set_is_getpwnam_safe(true); -- GitLab