From 93ccf6902ea3e2b80b257c5498410391902917ad Mon Sep 17 00:00:00 2001 From: Dominik George <dominik.george@teckids.org> Date: Wed, 19 May 2021 13:32:55 +0200 Subject: [PATCH] [PAM] Implement authorization stage --- etc/nss_pam_webapi.example.toml | 10 ++++++++ src/pam.rs | 43 ++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/etc/nss_pam_webapi.example.toml b/etc/nss_pam_webapi.example.toml index d2467b1..d163e2d 100644 --- a/etc/nss_pam_webapi.example.toml +++ b/etc/nss_pam_webapi.example.toml @@ -28,6 +28,16 @@ client_secret = "" # Defaults to only /run persist_token = { run = true, home = true } +# Endpoint URL to retrieve to check current authorization to use the system +# +# If set, the mapping program below must convert the response to a bool +# If unset, authorization is always granted +# urls.authz = "" + +# Mapping program (using jq) that converts the response from the authorization +# endpoint to a boolean +# maps.authz = "." + [nss] # Client ID and secret for acquiring OAuth tokens # You might want to put these into a separate file nss_pam_webapi.secret.toml! diff --git a/src/pam.rs b/src/pam.rs index 2ef3a2b..364c98d 100644 --- a/src/pam.rs +++ b/src/pam.rs @@ -22,7 +22,7 @@ use crate::config::{ }; use config::Config; -use crate::oauth::get_access_token_password; +use crate::oauth::{get_access_token_password, get_data_jq}; use crate::logging::setup_log; @@ -130,6 +130,47 @@ impl PamServiceModule for PamOidc { error!("Unknown flow for authentication"); return PamError::SERVICE_ERR; } + + fn acct_mgmt(pamh: Pam, _: PamFlag, argv: Vec<String>) -> PamError { + let conf = pam_sm_prepare(&argv); + + if conf.get_str("pam.urls.authz").unwrap_or_default() == "" { + info!("Authorization endpoint not set, granting access by default"); + return PamError::SUCCESS; + } + + debug!("Checking authorization with server"); + + // Retrieve access token (as acquired in the auth stage, probably) + set_is_getpwnam_safe(false); + // FIXME implement fallback to system token + let res = get_context_user().get_access_token(); + set_is_getpwnam_safe(true); + let token = match res { + Some(t) => t, + None => return PamError::CRED_UNAVAIL + }; + + // Get and transform data from API + let data: bool = match get_data_jq(&conf, "pam", "authz", "".to_string(), &token, true) { + Ok(d) => d, + Err(e) => { + error!("Could not load JSON data for authorization: {}", e); + return PamError::SERVICE_ERR; + } + }; + + match data { + true => { + info!("Authorization granted"); + PamError::SUCCESS + }, + false => { + info!("Authorization denied"); + PamError::PERM_DENIED + } + } + } } pam_module!(PamOidc); -- GitLab