diff --git a/src/cache.rs b/src/cache.rs
index 065862f307f4b73af94b06440dc49e6c577de285..475e7b0d85048ccead1f2d15748352ce71be06f5 100644
--- a/src/cache.rs
+++ b/src/cache.rs
@@ -36,9 +36,9 @@ use serde_json;
 
 const USER_TOKEN_FILENAME: &str = "user_token.json";
 
-struct UserInfo<'a> {
+pub struct UserInfo<'a> {
     uid: Option<uid_t>,
-    username: Option<&'a str>,
+    username: Option<String>,
     passwd: Option<Passwd<'a>>,
     access_token: Option<BasicTokenResponse>
 }
@@ -65,18 +65,18 @@ impl Cache<'_> {
 
 impl <'a>UserInfo<'a> {
     pub fn set_current_user(&mut self) {
-        self.set_uid(original_euid);
+        self.set_uid(get_original_euid());
     }
 
     pub fn is_initialized(&self) -> bool {
         self.uid.is_some() || self.username.is_some()
     }
 
-    fn try_resolve(&mut self) -> Result<&Passwd, io::Error> {
-        // If we already have a full passwd struct, return it as without resolving
+    fn try_resolve(&mut self) -> Result<(), io::Error> {
+        // If we already have a full passwd struct, do nothing
         if self.passwd.is_some() {
             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`)
@@ -102,18 +102,19 @@ impl <'a>UserInfo<'a> {
             Ok(passwd) => {
                 debug!("Successfully resolved context user's passwd entry");
                 self.passwd = Some(passwd);
-                Ok(self.passwd.as_ref().unwrap())
+                Ok(())
             },
             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 {
+        self.try_resolve();
+        match &self.passwd {
+            Some(passwd) => Ok(passwd.pw_uid),
+            None => match self.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> {
         self.try_resolve();
     }
 
-    pub fn get_username(&mut self) -> Result<&str, io::Error> {
-        match self.try_resolve() {
-            Ok(passwd) => Ok(passwd.pw_name),
-            Err(e) => match self.username {
-                Some(username) => Ok(username),
-                None => Err(e)
+    pub fn get_username(&mut self) -> Result<String, io::Error> {
+        self.try_resolve();
+        match &self.passwd {
+            Some(passwd) => Ok(passwd.pw_name.to_string()),
+            None => match &self.username {
+                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.uid = None;
         self.passwd = None;
@@ -143,13 +145,14 @@ impl <'a>UserInfo<'a> {
     }
 
     pub fn get_home_directory(&mut self) -> Result<&str, io::Error> {
-        match self.try_resolve() {
-            Ok(passwd) => Ok(passwd.pw_dir),
-            Err(e) => Err(e)
+        self.try_resolve();
+        match &self.passwd {
+            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 {
             geteuid()
         };
@@ -185,13 +188,13 @@ impl <'a>UserInfo<'a> {
             geteuid()
         };
 
-        if current_euid != original_euid {
+        if current_euid != get_original_euid() {
             debug!("Restoring privileges");
             let res = unsafe {
-                seteuid(original_euid)
+                seteuid(get_original_euid())
             };
             if res != 0 {
-                panic!("Could not restore privileges to {}", original_euid);
+                panic!("Could not restore privileges to {}", get_original_euid());
             }
         } else {
             debug!("No need to restore privileges, already running as original user");
@@ -204,7 +207,7 @@ impl <'a>UserInfo<'a> {
 
         // Determine user ID to find out whether we should override $HOME
         let uid = self.get_uid()?;
-        if uid != original_euid {
+        if uid != get_original_euid() {
             let user_home = self.get_home_directory()?;
             env::set_var("HOME", user_home);
             debug!("Home directory for UID {} is {}", uid, user_home);
@@ -217,7 +220,7 @@ impl <'a>UserInfo<'a> {
         };
 
         // Restore $HOME to original if we changed it earlier
-        if uid != original_euid {
+        if uid != get_original_euid() {
             if saved_home != None {
                 env::set_var("HOME", saved_home.unwrap());
             } else {
@@ -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
         if self.access_token.is_none() {
             debug!("No token in memory, trying to load from file");
@@ -250,7 +253,7 @@ impl <'a>UserInfo<'a> {
             self.restore_privileges();
         }
 
-        return self.access_token;
+        return &self.access_token;
     }
 
     pub fn set_access_token(&mut self, token: BasicTokenResponse) -> Result<(), io::Error> {
@@ -296,9 +299,17 @@ fn is_getpwnam_safe() -> bool {
     return true;
 }
 
-static original_euid: uid_t = unsafe {
-    geteuid()
-};
+static mut original_euid: uid_t = uid_t::MAX;
+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! {
     static ref CACHE: Mutex<Cache<'static>> = Mutex::new(Cache::new());
diff --git a/src/nss.rs b/src/nss.rs
index c8af522a616bcb29a563e3b9d054d3ceb6c40362..21fa3b400ef9167858ed39259fb7bfdb0b0ccbc2 100644
--- a/src/nss.rs
+++ b/src/nss.rs
@@ -65,12 +65,17 @@ impl PasswdHooks for OidcPasswd {
         if !get_cache().context_user.is_initialized() {
             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,
             None => {
-                // FIXME Implement caching of system token
                 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,
                     Err(e) => {
                         error!("Failed to get access token with client credentials: {}", e);
@@ -96,12 +101,17 @@ impl PasswdHooks for OidcPasswd {
         if !get_cache().context_user.is_initialized() {
             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,
             None => {
-                // FIXME Implement caching of system token
                 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,
                     Err(e) => {
                         error!("Failed to get access token with client credentials: {}", e);
@@ -126,12 +136,17 @@ impl PasswdHooks for OidcPasswd {
         if !get_cache().context_user.is_initialized() {
             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,
             None => {
-                // FIXME Implement caching of system token
-                debug!("Could not find a user token for to request NSS data; trying client credentials");
-                match get_access_token_client(&conf, "nss", "", "") {
+                debug!("Could not find a user token to request NSS data; trying client credentials");
+                match system_token_res {
                     Ok(ct) => ct,
                     Err(e) => {
                         error!("Failed to get access token with client credentials: {}", e);
diff --git a/src/pam.rs b/src/pam.rs
index f721a508db9662a1015abd8d50151db5ecb8d7fd..e98a1faa3a98eea3fb8cbd9f7d2441678fed4437 100644
--- a/src/pam.rs
+++ b/src/pam.rs
@@ -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) {
                 Ok(t) => {
                     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);
                     return PamError::SUCCESS;
                 },