diff --git a/src/cache.rs b/src/cache.rs
index dcdaeb35bb5f7ba89f00aaf52cc1f2fc4c67b5bf..5698a928a541ac0204fd055165294636cf5b6cc6 100644
--- a/src/cache.rs
+++ b/src/cache.rs
@@ -398,6 +398,7 @@ fn get_original_euid() -> uid_t {
     unsafe {
         if !original_euid_set {
             original_euid = geteuid();
+            debug!("Original EUID stored as {}", original_euid);
             original_euid_set = true;
         }
         original_euid
@@ -412,5 +413,8 @@ lazy_static! {
     static ref CONTEXT_USER: Mutex<UserInfo> = Mutex::new(UserInfo::new());
 }
 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()
 }
diff --git a/src/pam.rs b/src/pam.rs
index d7637ed2c7938459969dd4fce51cdcd75c790181..487caae9654a65c5477e838713dc412130ae6251 100644
--- a/src/pam.rs
+++ b/src/pam.rs
@@ -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) {
                 Ok(t) => {
                     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);
+                    // 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());
                     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());
                     }
-                    get_context_user().set_access_token(t);
+                    // 5. ...unlock getpwnam again (somewhat unnecessary)
                     set_is_getpwnam_safe(true);
                     return PamError::SUCCESS;
                 },