From 4aebf53980372d6072a18061ffaf6205da3af2fe Mon Sep 17 00:00:00 2001 From: Dominik George <dominik.george@teckids.org> Date: Wed, 12 May 2021 21:59:44 +0200 Subject: [PATCH] Revert "[Cache] Get rid of global state" This reverts commit b5bfa1280dc0c3f6b5032d7e16b608d7a25aa9de. --- src/cache.rs | 29 ++++++++++++++++++----------- src/nss.rs | 17 +++++++++-------- src/pam.rs | 12 +++++------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index b51043c..f254d50 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -15,10 +15,11 @@ */ use crate::BASE_NAME; - use crate::unix::getpwnam_safe; +use lazy_static::lazy_static; use std::collections::HashMap; +use std::sync::{RwLock, RwLockReadGuard}; use libc::{geteuid, seteuid, uid_t}; @@ -39,19 +40,17 @@ const USER_TOKEN_FILENAME: &str = "user_token.json"; pub struct Cache { user_tokens: HashMap<String, BasicTokenResponse>, original_euid: uid_t, - prefix: String } impl Cache { - pub fn new(prefix: &str) -> Cache { + pub fn new() -> Cache { let euid; unsafe { euid = geteuid(); }; Cache { user_tokens: HashMap::new(), - original_euid: euid, - prefix: prefix.to_string() + original_euid: euid } } @@ -145,7 +144,7 @@ impl Cache { } } - pub fn load_user_token(&mut self, owner: &String) -> Option<&BasicTokenResponse> { + pub fn load_user_token(&self, owner: &String) -> Option<&BasicTokenResponse> { if !self.user_tokens.contains_key(owner) { debug!("No token for {} in memory, trying to load from file", owner); @@ -161,7 +160,7 @@ impl Cache { match new_token { Some(t) => { - self.user_tokens.insert(owner.to_string(), t); + CACHE.write().unwrap().user_tokens.insert(owner.to_string(), t); self.user_tokens.get(owner) }, None => None @@ -172,8 +171,8 @@ impl Cache { } } - pub fn save_user_token(&mut self, owner: &String, token: BasicTokenResponse) -> Result<(), io::Error> { - self.user_tokens.insert(owner.to_string(), token.clone()); + pub fn save_user_token(&self, owner: &String, token: BasicTokenResponse) -> Result<(), io::Error> { + CACHE.write().unwrap().user_tokens.insert(owner.to_string(), token.clone()); debug!("Saved token for {} in memory", owner); // Try to write user's token cache file @@ -191,8 +190,8 @@ impl Cache { return res; } - pub fn delete_user_token(&mut self, owner: &String) { - self.user_tokens.remove(owner); + 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 @@ -226,3 +225,11 @@ fn save_json<O: Serialize>(path: PathBuf, obj: O) -> Result<(), io::Error> { fs::write(path, json) } + +lazy_static! { + static ref CACHE: RwLock<Cache> = RwLock::new(Cache::new()); +} + +pub fn get_cache() -> RwLockReadGuard<'static, Cache> { + CACHE.read().unwrap() +} diff --git a/src/nss.rs b/src/nss.rs index 598c8b6..402af6e 100644 --- a/src/nss.rs +++ b/src/nss.rs @@ -19,7 +19,7 @@ use crate::config::{ get_or_error }; use config::Config; -use crate::cache::Cache; +use crate::cache::get_cache; use crate::logging::setup_log; @@ -46,7 +46,7 @@ struct PasswdDef { } #[derive(Deserialize)] struct PasswdHelper(#[serde(with = "PasswdDef")] Passwd); -fn nss_hook_prepare() -> (Cache, Config) { +fn nss_hook_prepare() -> Config { let conf = get_config(None); let mut log_level = log::LevelFilter::Error; @@ -55,9 +55,7 @@ fn nss_hook_prepare() -> (Cache, Config) { } setup_log(log_level); - let cache = Cache::new("nss"); - - return (cache, conf); + return conf; } fn get_current_user() -> String { @@ -79,7 +77,8 @@ struct OidcPasswd; impl PasswdHooks for OidcPasswd { fn get_all_entries() -> Response<Vec<Passwd>> { - let (mut cache, conf) = nss_hook_prepare(); + let conf = nss_hook_prepare(); + let mut cache = get_cache(); let user = get_current_user(); let ctc; @@ -112,7 +111,8 @@ impl PasswdHooks for OidcPasswd { } fn get_entry_by_uid(uid: libc::uid_t) -> Response<Passwd> { - let (mut cache, conf) = nss_hook_prepare(); + let conf = nss_hook_prepare(); + let mut cache = get_cache(); let user = get_current_user(); let ctc; @@ -145,7 +145,8 @@ impl PasswdHooks for OidcPasswd { } fn get_entry_by_name(name: String) -> Response<Passwd> { - let (mut cache, conf) = nss_hook_prepare(); + let conf = nss_hook_prepare(); + let mut cache = get_cache(); let user = get_current_user(); let ctc; diff --git a/src/pam.rs b/src/pam.rs index 1042ade..2133f7f 100644 --- a/src/pam.rs +++ b/src/pam.rs @@ -24,11 +24,11 @@ use crate::oauth::get_access_token_password; use crate::logging::setup_log; -use crate::cache::Cache; +use crate::cache::get_cache; use pamsm::{PamServiceModule, Pam, PamFlag, PamError, PamLibExt}; -fn pam_sm_prepare(argv: &Vec<String>) -> (Cache, Config) { +fn pam_sm_prepare(argv: &Vec<String>) -> Config { let conf_args = argv_to_config(argv); let conf = get_config(Some(conf_args)); @@ -38,16 +38,14 @@ fn pam_sm_prepare(argv: &Vec<String>) -> (Cache, Config) { } setup_log(log_level); - let cache = Cache::new("pam"); - - return (cache, conf); + return conf; } struct PamOidc; impl PamServiceModule for PamOidc { fn authenticate(pamh: Pam, _: PamFlag, argv: Vec<String>) -> PamError { - let (mut cache, conf) = pam_sm_prepare(&argv); + let conf = pam_sm_prepare(&argv); if conf.get_str("pam.flow").unwrap() == "password" { debug!("Starting Resource Owner Password Credentials OAuth flow"); @@ -92,7 +90,7 @@ impl PamServiceModule for PamOidc { match get_access_token_password(&conf, "pam", username.to_string(), password.to_string(), PamError::SERVICE_ERR, PamError::AUTH_ERR) { Ok(t) => { info!("Authenticated {} using Resource Owner Password Grant", username); - cache.save_user_token(&username.to_string(), t.into()); + get_cache().save_user_token(&username.to_string(), t.into()); return PamError::SUCCESS; }, Err(e) => { -- GitLab