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

[Cache] Fix some more reference passing, and access to original_euid

parent 169f0d9d
No related branches found
No related tags found
No related merge requests found
...@@ -36,9 +36,9 @@ use serde_json; ...@@ -36,9 +36,9 @@ use serde_json;
const USER_TOKEN_FILENAME: &str = "user_token.json"; const USER_TOKEN_FILENAME: &str = "user_token.json";
struct UserInfo<'a> { pub struct UserInfo<'a> {
uid: Option<uid_t>, uid: Option<uid_t>,
username: Option<&'a str>, username: Option<String>,
passwd: Option<Passwd<'a>>, passwd: Option<Passwd<'a>>,
access_token: Option<BasicTokenResponse> access_token: Option<BasicTokenResponse>
} }
...@@ -65,18 +65,18 @@ impl Cache<'_> { ...@@ -65,18 +65,18 @@ impl Cache<'_> {
impl <'a>UserInfo<'a> { impl <'a>UserInfo<'a> {
pub fn set_current_user(&mut self) { pub fn set_current_user(&mut self) {
self.set_uid(original_euid); self.set_uid(get_original_euid());
} }
pub fn is_initialized(&self) -> bool { pub fn is_initialized(&self) -> bool {
self.uid.is_some() || self.username.is_some() self.uid.is_some() || self.username.is_some()
} }
fn try_resolve(&mut self) -> Result<&Passwd, io::Error> { fn try_resolve(&mut self) -> Result<(), io::Error> {
// If we already have a full passwd struct, return it as without resolving // If we already have a full passwd struct, do nothing
if self.passwd.is_some() { if self.passwd.is_some() {
debug!("passwd entry for context user already resolved"); debug!("passwd entry for context user already resolved");
return Ok(self.passwd.as_ref().unwrap()); return Ok(());
} }
// If we cannot call getpwnam safely, return error (see `is_get_pwnam_safe`) // If we cannot call getpwnam safely, return error (see `is_get_pwnam_safe`)
...@@ -102,18 +102,19 @@ impl <'a>UserInfo<'a> { ...@@ -102,18 +102,19 @@ impl <'a>UserInfo<'a> {
Ok(passwd) => { Ok(passwd) => {
debug!("Successfully resolved context user's passwd entry"); debug!("Successfully resolved context user's passwd entry");
self.passwd = Some(passwd); self.passwd = Some(passwd);
Ok(self.passwd.as_ref().unwrap()) Ok(())
}, },
Err(e) => Err(e) Err(e) => Err(e)
} }
} }
pub fn get_uid(&mut self) -> Result<uid_t, io::Error> { pub fn get_uid(&mut self) -> Result<uid_t, io::Error> {
match self.try_resolve() { self.try_resolve();
Ok(passwd) => Ok(passwd.pw_uid), match &self.passwd {
Err(e) => match self.uid { Some(passwd) => Ok(passwd.pw_uid),
None => match self.uid {
Some(uid) => Ok(uid), Some(uid) => Ok(uid),
None => Err(e) None => Err(io::Error::new(io::ErrorKind::InvalidInput, "foo"))
} }
} }
} }
...@@ -125,17 +126,18 @@ impl <'a>UserInfo<'a> { ...@@ -125,17 +126,18 @@ impl <'a>UserInfo<'a> {
self.try_resolve(); self.try_resolve();
} }
pub fn get_username(&mut self) -> Result<&str, io::Error> { pub fn get_username(&mut self) -> Result<String, io::Error> {
match self.try_resolve() { self.try_resolve();
Ok(passwd) => Ok(passwd.pw_name), match &self.passwd {
Err(e) => match self.username { Some(passwd) => Ok(passwd.pw_name.to_string()),
Some(username) => Ok(username), None => match &self.username {
None => Err(e) Some(username) => Ok(username.to_string()),
None => Err(io::Error::new(io::ErrorKind::InvalidInput, "foo"))
} }
} }
} }
pub fn set_username(&mut self, username: &'a str) { pub fn set_username(&mut self, username: String) {
self.username = Some(username); self.username = Some(username);
self.uid = None; self.uid = None;
self.passwd = None; self.passwd = None;
...@@ -143,13 +145,14 @@ impl <'a>UserInfo<'a> { ...@@ -143,13 +145,14 @@ impl <'a>UserInfo<'a> {
} }
pub fn get_home_directory(&mut self) -> Result<&str, io::Error> { pub fn get_home_directory(&mut self) -> Result<&str, io::Error> {
match self.try_resolve() { self.try_resolve();
Ok(passwd) => Ok(passwd.pw_dir), match &self.passwd {
Err(e) => Err(e) Some(passwd) => Ok(passwd.pw_dir),
None => Err(io::Error::new(io::ErrorKind::InvalidInput, "foo"))
} }
} }
fn drop_privileges(&self) -> Result<uid_t, io::Error> { fn drop_privileges(&mut self) -> Result<uid_t, io::Error> {
let current_euid = unsafe { let current_euid = unsafe {
geteuid() geteuid()
}; };
...@@ -185,13 +188,13 @@ impl <'a>UserInfo<'a> { ...@@ -185,13 +188,13 @@ impl <'a>UserInfo<'a> {
geteuid() geteuid()
}; };
if current_euid != original_euid { if current_euid != get_original_euid() {
debug!("Restoring privileges"); debug!("Restoring privileges");
let res = unsafe { let res = unsafe {
seteuid(original_euid) seteuid(get_original_euid())
}; };
if res != 0 { if res != 0 {
panic!("Could not restore privileges to {}", original_euid); panic!("Could not restore privileges to {}", get_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");
...@@ -204,7 +207,7 @@ impl <'a>UserInfo<'a> { ...@@ -204,7 +207,7 @@ impl <'a>UserInfo<'a> {
// Determine user ID to find out whether we should override $HOME // Determine user ID to find out whether we should override $HOME
let uid = self.get_uid()?; let uid = self.get_uid()?;
if uid != original_euid { if uid != get_original_euid() {
let user_home = self.get_home_directory()?; let user_home = self.get_home_directory()?;
env::set_var("HOME", user_home); env::set_var("HOME", user_home);
debug!("Home directory for UID {} is {}", uid, user_home); debug!("Home directory for UID {} is {}", uid, user_home);
...@@ -217,7 +220,7 @@ impl <'a>UserInfo<'a> { ...@@ -217,7 +220,7 @@ impl <'a>UserInfo<'a> {
}; };
// Restore $HOME to original if we changed it earlier // Restore $HOME to original if we changed it earlier
if uid != original_euid { if uid != get_original_euid() {
if saved_home != None { if saved_home != None {
env::set_var("HOME", saved_home.unwrap()); env::set_var("HOME", saved_home.unwrap());
} else { } else {
...@@ -235,7 +238,7 @@ impl <'a>UserInfo<'a> { ...@@ -235,7 +238,7 @@ impl <'a>UserInfo<'a> {
} }
} }
pub fn get_access_token(&mut self) -> Option<BasicTokenResponse> { pub fn get_access_token(&mut self) -> &Option<BasicTokenResponse> {
// Try to load our acess token if none is known // Try to load our acess token if none is known
if self.access_token.is_none() { if self.access_token.is_none() {
debug!("No token in memory, trying to load from file"); debug!("No token in memory, trying to load from file");
...@@ -250,7 +253,7 @@ impl <'a>UserInfo<'a> { ...@@ -250,7 +253,7 @@ impl <'a>UserInfo<'a> {
self.restore_privileges(); self.restore_privileges();
} }
return self.access_token; return &self.access_token;
} }
pub fn set_access_token(&mut self, token: BasicTokenResponse) -> Result<(), io::Error> { pub fn set_access_token(&mut self, token: BasicTokenResponse) -> Result<(), io::Error> {
...@@ -296,9 +299,17 @@ fn is_getpwnam_safe() -> bool { ...@@ -296,9 +299,17 @@ fn is_getpwnam_safe() -> bool {
return true; return true;
} }
static original_euid: uid_t = unsafe { static mut original_euid: uid_t = uid_t::MAX;
geteuid() static mut original_euid_set: bool = false;
}; fn get_original_euid() -> uid_t {
unsafe {
if !original_euid_set {
original_euid = geteuid();
original_euid_set = true;
}
original_euid
}
}
lazy_static! { lazy_static! {
static ref CACHE: Mutex<Cache<'static>> = Mutex::new(Cache::new()); static ref CACHE: Mutex<Cache<'static>> = Mutex::new(Cache::new());
......
...@@ -65,12 +65,17 @@ impl PasswdHooks for OidcPasswd { ...@@ -65,12 +65,17 @@ impl PasswdHooks for OidcPasswd {
if !get_cache().context_user.is_initialized() { if !get_cache().context_user.is_initialized() {
get_cache().context_user.set_current_user(); get_cache().context_user.set_current_user();
} }
let token = match get_cache().context_user.get_access_token() {
let mut cache = get_cache();
let user_token_res = cache.context_user.get_access_token();
// FIXME Implement caching of system token
let system_token_res = get_access_token_client(&conf, "nss", "", "");
let system_token_res = system_token_res.as_ref();
let token = match user_token_res {
Some(t) => t, Some(t) => t,
None => { None => {
// FIXME Implement caching of system token
debug!("Could not find a user token to request NSS data; trying client credentials"); debug!("Could not find a user token to request NSS data; trying client credentials");
match get_access_token_client(&conf, "nss", "", "") { match system_token_res {
Ok(ct) => ct, Ok(ct) => ct,
Err(e) => { Err(e) => {
error!("Failed to get access token with client credentials: {}", e); error!("Failed to get access token with client credentials: {}", e);
...@@ -96,12 +101,17 @@ impl PasswdHooks for OidcPasswd { ...@@ -96,12 +101,17 @@ impl PasswdHooks for OidcPasswd {
if !get_cache().context_user.is_initialized() { if !get_cache().context_user.is_initialized() {
get_cache().context_user.set_current_user(); get_cache().context_user.set_current_user();
} }
let token = match get_cache().context_user.get_access_token() {
let mut cache = get_cache();
let user_token_res = cache.context_user.get_access_token();
// FIXME Implement caching of system token
let system_token_res = get_access_token_client(&conf, "nss", "", "");
let system_token_res = system_token_res.as_ref();
let token = match user_token_res {
Some(t) => t, Some(t) => t,
None => { None => {
// FIXME Implement caching of system token
debug!("Could not find a user token to request NSS data; trying client credentials"); debug!("Could not find a user token to request NSS data; trying client credentials");
match get_access_token_client(&conf, "nss", "", "") { match system_token_res {
Ok(ct) => ct, Ok(ct) => ct,
Err(e) => { Err(e) => {
error!("Failed to get access token with client credentials: {}", e); error!("Failed to get access token with client credentials: {}", e);
...@@ -126,12 +136,17 @@ impl PasswdHooks for OidcPasswd { ...@@ -126,12 +136,17 @@ impl PasswdHooks for OidcPasswd {
if !get_cache().context_user.is_initialized() { if !get_cache().context_user.is_initialized() {
get_cache().context_user.set_current_user(); get_cache().context_user.set_current_user();
} }
let token = match get_cache().context_user.get_access_token() {
let mut cache = get_cache();
let user_token_res = cache.context_user.get_access_token();
// FIXME Implement caching of system token
let system_token_res = get_access_token_client(&conf, "nss", "", "");
let system_token_res = system_token_res.as_ref();
let token = match user_token_res {
Some(t) => t, Some(t) => t,
None => { None => {
// FIXME Implement caching of system token debug!("Could not find a user token to request NSS data; trying client credentials");
debug!("Could not find a user token for to request NSS data; trying client credentials"); match system_token_res {
match get_access_token_client(&conf, "nss", "", "") {
Ok(ct) => ct, Ok(ct) => ct,
Err(e) => { Err(e) => {
error!("Failed to get access token with client credentials: {}", e); error!("Failed to get access token with client credentials: {}", e);
......
...@@ -90,7 +90,7 @@ impl PamServiceModule for PamOidc { ...@@ -90,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) { 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().context_user.set_username(username); get_cache().context_user.set_username(username.to_string());
get_cache().context_user.set_access_token(t); get_cache().context_user.set_access_token(t);
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