Mercurial > crates > nonstick
diff src/libpam/module.rs @ 166:2f5913131295
Separate flag/action flags into flags and action.
This also individualizes the type of flag for each PAM function,
so that you can only call a function with the right flags and values.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Tue, 15 Jul 2025 00:32:24 -0400 |
parents | 1bc52025156b |
children | e27c5c667a5a |
line wrap: on
line diff
--- a/src/libpam/module.rs Mon Jul 14 18:56:55 2025 -0400 +++ b/src/libpam/module.rs Tue Jul 15 00:32:24 2025 -0400 @@ -11,7 +11,7 @@ /// /// ```no_run /// use nonstick::{ -/// pam_hooks, ConversationAdapter, Flags, LibPamTransaction, ModuleClient, PamModule, +/// pam_hooks, ConversationAdapter, AuthnFlags, LibPamTransaction, ModuleClient, PamModule, /// Result as PamResult, /// }; /// use std::ffi::CStr; @@ -21,7 +21,7 @@ /// pam_hooks!(MyPamModule); /// /// impl<T: ModuleClient> PamModule<T> for MyPamModule { -/// fn authenticate(handle: &mut T, args: Vec<&CStr>, flags: Flags) -> PamResult<()> { +/// fn authenticate(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> PamResult<()> { /// let password = handle.authtok(Some("what's your password?".as_ref()))?; /// let response = /// format!("If you say your password is {password:?}, who am I to disagree?"); @@ -29,7 +29,7 @@ /// Ok(()) /// } /// -/// fn account_management(handle: &mut T, args: Vec<&CStr>, flags: Flags) -> PamResult<()> { +/// fn account_management(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> PamResult<()> { /// let username = handle.username(None)?; /// let response = format!("Hello {username:?}! I trust you unconditionally."); /// handle.info_msg(&response); @@ -42,96 +42,98 @@ ($ident:ident) => { mod _pam_hooks_scope { use std::ffi::{c_char, c_int, c_void, CStr}; - use $crate::{ErrorCode, Flags, LibPamHandle, PamModule}; + use $crate::{ + AuthnFlags, AuthtokAction, BaseFlags, CredAction, ErrorCode, LibPamHandle, + PamModule, + }; + + macro_rules! handle { + ($pamh:ident) => { + match unsafe { $pamh.cast::<LibPamHandle>().as_mut() } { + Some(handle) => handle, + None => return ErrorCode::Ignore.into(), + } + }; + } #[no_mangle] extern "C" fn pam_sm_acct_mgmt( pamh: *mut c_void, - flags: Flags, + flags: AuthnFlags, argc: c_int, argv: *const *const c_char, ) -> c_int { - if let Some(handle) = unsafe { pamh.cast::<LibPamHandle>().as_mut() } { - let args = extract_argv(argc, argv); - ErrorCode::result_to_c(super::$ident::account_management(handle, args, flags)) - } else { - ErrorCode::Ignore as c_int - } + let handle = handle!(pamh); + let args = extract_argv(argc, argv); + ErrorCode::result_to_c(super::$ident::account_management(handle, args, flags)) } #[no_mangle] extern "C" fn pam_sm_authenticate( pamh: *mut c_void, - flags: Flags, + flags: AuthnFlags, argc: c_int, argv: *const *const c_char, ) -> c_int { - if let Some(handle) = unsafe { pamh.cast::<LibPamHandle>().as_mut() } { - let args = extract_argv(argc, argv); - ErrorCode::result_to_c(super::$ident::authenticate(handle, args, flags)) - } else { - ErrorCode::Ignore as c_int - } + let handle = handle!(pamh); + let args = extract_argv(argc, argv); + ErrorCode::result_to_c(super::$ident::authenticate(handle, args, flags)) } #[no_mangle] extern "C" fn pam_sm_chauthtok( pamh: *mut c_void, - flags: Flags, + flags: c_int, argc: c_int, argv: *const *const c_char, ) -> c_int { - if let Some(handle) = unsafe { pamh.cast::<LibPamHandle>().as_mut() } { - let args = extract_argv(argc, argv); - ErrorCode::result_to_c(super::$ident::change_authtok(handle, args, flags)) - } else { - ErrorCode::Ignore as c_int - } + let handle = handle!(pamh); + let (action, flags) = match AuthtokAction::extract(flags) { + Ok(val) => val, + Err(e) => return e.into(), + }; + let args = extract_argv(argc, argv); + ErrorCode::result_to_c(super::$ident::change_authtok(handle, args, action, flags)) } #[no_mangle] extern "C" fn pam_sm_close_session( pamh: *mut c_void, - flags: Flags, + flags: BaseFlags, argc: c_int, argv: *const *const c_char, ) -> c_int { - if let Some(handle) = unsafe { pamh.cast::<LibPamHandle>().as_mut() } { - let args = extract_argv(argc, argv); - ErrorCode::result_to_c(super::$ident::close_session(handle, args, flags)) - } else { - ErrorCode::Ignore as c_int - } + let handle = handle!(pamh); + let args = extract_argv(argc, argv); + ErrorCode::result_to_c(super::$ident::close_session(handle, args, flags)) } #[no_mangle] extern "C" fn pam_sm_open_session( pamh: *mut c_void, - flags: Flags, + flags: BaseFlags, argc: c_int, argv: *const *const c_char, ) -> c_int { + let handle = handle!(pamh); let args = extract_argv(argc, argv); - if let Some(handle) = unsafe { pamh.cast::<LibPamHandle>().as_mut() } { - ErrorCode::result_to_c(super::$ident::open_session(handle, args, flags)) - } else { - ErrorCode::Ignore as c_int - } + ErrorCode::result_to_c(super::$ident::open_session(handle, args, flags)) } #[no_mangle] extern "C" fn pam_sm_setcred( pamh: *mut c_void, - flags: Flags, + flags: c_int, argc: c_int, argv: *const *const c_char, ) -> c_int { + let handle = handle!(pamh); + let (action, flags) = match CredAction::extract(flags) { + Ok(val) => val, + Err(e) => return e.into(), + }; let args = extract_argv(argc, argv); - if let Some(handle) = unsafe { pamh.cast::<LibPamHandle>().as_mut() } { - ErrorCode::result_to_c(super::$ident::set_credentials(handle, args, flags)) - } else { - ErrorCode::Ignore as c_int - } + ErrorCode::result_to_c(super::$ident::set_credentials(handle, args, action, flags)) } /// Turns `argc`/`argv` into a [Vec] of [CStr]s.