diff --git a/src/nss.rs b/src/nss.rs
index 66ab75f44d94f3d8f08f4e4f54f78ae61d9b12a8..c4be7f1a5425cc98bfe99336888961c26527e0b7 100644
--- a/src/nss.rs
+++ b/src/nss.rs
@@ -23,7 +23,7 @@ use crate::cache::get_cache;
 
 use crate::logging::setup_log;
 
-use crate::oauth::get_data_jq;
+use crate::oauth::{get_access_token_client, get_data_jq};
 use serde::{Serialize, Deserialize};
 
 use libc::{getpwuid, geteuid};
@@ -75,16 +75,26 @@ impl PasswdHooks for OidcPasswd {
         let mut cache = get_cache();
 
         let user = get_current_user();
+        let ctc;
         let token = match cache.load_user_token(&user) {
             Some(t) => t,
             None => {
-                // FIXME Implement fallback to system token
-                error!("Could not find a user token for {} to request NSS data", user);
-                return Response::Unavail;
+                // FIXME Implement caching of system token
+                debug!("Could not find a user token for {} to request NSS data; trying client credentials", user);
+                match get_access_token_client(&conf, "nss", "", "") {
+                    Ok(ct) => {
+                        ctc = ct.clone();
+                        &ctc
+                    },
+                    Err(_) => {
+                        error!("Failed to get access token with client credentials");
+                        return Response::Unavail;
+                    }
+                }
             }
         };
 
-        let data: Vec<PasswdHelper> = match get_data_jq(&conf, "nss", "passwd", token, true) {
+        let data: Vec<PasswdHelper> = match get_data_jq(&conf, "nss", "passwd", &token, true) {
             Ok(d) => d,
             Err(_) => {
                 error!("Could not load JSON data for passwd");
diff --git a/src/oauth.rs b/src/oauth.rs
index 385d41f983b5603541727aabba6e8c9e8d0f3580..14d18824fd4c9d25f8a83a1b168f3c1964f3d6e2 100644
--- a/src/oauth.rs
+++ b/src/oauth.rs
@@ -49,7 +49,7 @@ fn full_key(parts: Vec<&str>) -> String {
     parts.join(".")
 }
 
-fn get_client<E: Copy>(conf: Config, prefix: &str, error_value: E) -> Result<BasicClient, E> {
+fn get_client<E: Copy>(conf: &Config, prefix: &str, error_value: E) -> Result<BasicClient, E> {
     let client_id = ClientId::new(get_or_error(&conf, &full_key(vec![prefix, "client_id"]), error_value)?);
     let client_secret = match get_optional(&conf, &full_key(vec![prefix, "client_secret"])) {
         Some(v) => Some(ClientSecret::new(v)),
@@ -77,7 +77,7 @@ fn get_client<E: Copy>(conf: Config, prefix: &str, error_value: E) -> Result<Bas
     return Ok(client);
 }
 
-pub fn get_access_token_client<E: Copy>(conf: Config, prefix: &str, error_value: E, unauth_value: E) -> Result<BasicTokenResponse, E> {
+pub fn get_access_token_client<E: Copy>(conf: &Config, prefix: &str, error_value: E, unauth_value: E) -> Result<BasicTokenResponse, E> {
     let scopes: Vec<String> = match get_optional(&conf, &full_key(vec![prefix, "scopes"])) {
         Some(v) => v,
         None => vec![]
@@ -105,7 +105,7 @@ pub fn get_access_token_client<E: Copy>(conf: Config, prefix: &str, error_value:
         }
 }
 
-pub fn get_access_token_password<E: Copy>(conf: Config, prefix: &str, username: String, password: String, error_value: E, unauth_value: E) -> Result<BasicTokenResponse, E> {
+pub fn get_access_token_password<E: Copy>(conf: &Config, prefix: &str, username: String, password: String, error_value: E, unauth_value: E) -> Result<BasicTokenResponse, E> {
     let scopes: Vec<String> = match get_optional(&conf, &full_key(vec![prefix, "scopes"])) {
         Some(v) => v,
         None => vec![]
diff --git a/src/pam.rs b/src/pam.rs
index 461d71c2fbcba78a51bd5a2d41597566d7dc91d5..2133f7f38594ea4febf1b5af693a342d28914199 100644
--- a/src/pam.rs
+++ b/src/pam.rs
@@ -87,7 +87,7 @@ impl PamServiceModule for PamOidc {
             };
             debug!("Successfully got password");
 
-            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) => {
                     info!("Authenticated {} using Resource Owner Password Grant", username);
                     get_cache().save_user_token(&username.to_string(), t.into());