From ddd9971a733104a175b5480ef61b400fbe29e620 Mon Sep 17 00:00:00 2001
From: Dominik George <dominik.george@teckids.org>
Date: Thu, 13 May 2021 13:52:05 +0200
Subject: [PATCH] [PAM] Set global flag to mark getpwnam unsafe during PAM
 authentication

---
 src/cache.rs | 17 ++++++++++++-----
 src/pam.rs   |  4 +++-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/cache.rs b/src/cache.rs
index 475e7b0..cc2e347 100644
--- a/src/cache.rs
+++ b/src/cache.rs
@@ -80,7 +80,7 @@ impl <'a>UserInfo<'a> {
         }
 
         // If we cannot call getpwnam safely, return error (see `is_get_pwnam_safe`)
-        if !is_getpwnam_safe() {
+        if !get_is_getpwnam_safe() {
             let msg = "Context user cannot be resolved safely right now";
             warn!("{}", msg);
             return Err(io::Error::new(io::ErrorKind::WouldBlock, msg));
@@ -160,7 +160,7 @@ impl <'a>UserInfo<'a> {
         let target_euid = match self.get_uid() {
             Ok(uid) => uid,
             Err(e) => {
-                error!("Could not drop privileges because target UID is not resolved");
+                debug!("Could not drop privileges because target UID is not resolved");
                 return Err(e);
             }
         };
@@ -294,9 +294,16 @@ fn save_json<O: Serialize>(path: PathBuf, obj: O) -> Result<(), io::Error> {
     fs::write(path, json)
 }
 
-fn is_getpwnam_safe() -> bool {
-    // FIXME Implement real logic
-    return true;
+static mut is_getpwnam_safe: bool = true;
+fn get_is_getpwnam_safe() -> bool {
+    unsafe {
+        is_getpwnam_safe
+    }
+}
+pub fn set_is_getpwnam_safe(v: bool) {
+    unsafe {
+        is_getpwnam_safe = v
+    }
 }
 
 static mut original_euid: uid_t = uid_t::MAX;
diff --git a/src/pam.rs b/src/pam.rs
index e98a1fa..02b26a7 100644
--- a/src/pam.rs
+++ b/src/pam.rs
@@ -24,7 +24,7 @@ use crate::oauth::get_access_token_password;
 
 use crate::logging::setup_log;
 
-use crate::cache::get_cache;
+use crate::cache::{get_cache, set_is_getpwnam_safe};
 
 use pamsm::{PamServiceModule, Pam, PamFlag, PamError, PamLibExt};
 
@@ -90,8 +90,10 @@ 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);
+                    set_is_getpwnam_safe(false);
                     get_cache().context_user.set_username(username.to_string());
                     get_cache().context_user.set_access_token(t);
+                    set_is_getpwnam_safe(true);
                     return PamError::SUCCESS;
                 },
                 Err(e) => {
-- 
GitLab