From 91132875be2358d67a62b4d4f0a5ba7d3a79e088 Mon Sep 17 00:00:00 2001
From: Dominik George <dominik.george@teckids.org>
Date: Sat, 8 May 2021 13:12:30 +0200
Subject: [PATCH] [Cache] Implemetn stub for persistence

This implements privilege dropping to handle files in uer homes.
---
 README.md    |  5 +++++
 src/cache.rs | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 8b444bc..8755bc8 100644
--- a/README.md
+++ b/README.md
@@ -107,3 +107,8 @@ from the API up to date. It handles the following data:
 
  * User access tokens (using corresponding refresh tokens, if available)
  * NSS data
+
+## Credits
+
+Special thanks to mirabilos in his position as Senior Unix System Development
+Consultant.
diff --git a/src/cache.rs b/src/cache.rs
index 47aef19..cb707c2 100644
--- a/src/cache.rs
+++ b/src/cache.rs
@@ -18,6 +18,9 @@ use std::collections::HashMap;
 use std::convert::From;
 use std::time::SystemTime;
 
+use libc::{geteuid, seteuid, getpwnam};
+use std::ffi::CString;
+
 use oauth2::basic::BasicTokenResponse;
 
 const TOKEN_DEFAULT_EXPIRES: u64 = 24 * 60 * 60;
@@ -73,10 +76,36 @@ impl Cache {
         self.user_tokens.insert(owner, token);
     }
 
+    pub fn delete_user_token(&self, owner: String) {
+        self.user_tokens.remove(&owner);
+
+        // Try to remove user's token cache file
+        let original_euid = geteuid();
+        let target_euid = (*getpwnam(CStr::new(owner).ok().unwrap().as_ptr())).pw_uid;
+
+        if original_euid != target_euid {
+            // We are not already running as the target user
+            if original_euid == 0 {
+                // If we are root, try dropping privileges to the target user
+                seteuid(target_euid);
+            } else {
+                // Bail out silently if we are not root
+                return;
+            }
+        }
+
+        // FIXME Add delete code here
+
+        if original_euid != target_euid {
+            // Restore original privileges if we dropped them earlier
+            seteuid(original_euid);
+        }
+    }
+
     pub fn cleanup_tokens(&self) {
         for (owner, token) in self.user_tokens {
             if token.is_expired() {
-                self.user_tokens.remove(&owner);
+                self.delete_user_token(owner);
             }
         }
     }
-- 
GitLab