# HG changeset patch # User Anthony Nowell # Date 1506414603 21600 # Node ID 4263c1d83d5bc9cfae5949121f1c98a45973632c # Parent aa7e8bd083ef4d320c7428fe59eac73e8c826577 Refactor PamHooks into modules mod diff -r aa7e8bd083ef -r 4263c1d83d5b pam-http/src/lib.rs --- a/pam-http/src/lib.rs Tue Sep 26 02:15:28 2017 -0600 +++ b/pam-http/src/lib.rs Tue Sep 26 02:30:03 2017 -0600 @@ -1,10 +1,9 @@ #[macro_use] extern crate pam; extern crate reqwest; -use pam::module::PamHandle; +use pam::module::{PamHandle, PamHooks}; use pam::constants::{PamResultCode, PamFlag, PAM_PROMPT_ECHO_OFF}; use pam::conv::PamConv; -use pam::hooks::PamHooks; use std::collections::HashMap; use std::time::Duration; use reqwest::{Client, StatusCode}; diff -r aa7e8bd083ef -r 4263c1d83d5b pam-sober/src/lib.rs --- a/pam-sober/src/lib.rs Tue Sep 26 02:15:28 2017 -0600 +++ b/pam-sober/src/lib.rs Tue Sep 26 02:30:03 2017 -0600 @@ -1,10 +1,9 @@ #[macro_use] extern crate pam; extern crate rand; -use pam::module::PamHandle; +use pam::module::{PamHandle, PamHooks}; use pam::constants::{PamResultCode, PamFlag, PAM_PROMPT_ECHO_ON}; use pam::conv::PamConv; -use pam::hooks::PamHooks; use rand::Rng; use std::str::FromStr; use std::ffi::CStr; diff -r aa7e8bd083ef -r 4263c1d83d5b pam/src/hooks.rs --- a/pam/src/hooks.rs Tue Sep 26 02:15:28 2017 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -use module::{PamHandle}; -use constants::{PamFlag, PamResultCode}; -use std::ffi::CStr; - -/// Provides functions that are invoked by the entrypoints generated by the -/// [`pam_hooks!` macro](../macro.pam_hooks.html). -/// -/// All of hooks are ignored by PAM dispatch by default given the default return value of `PAM_IGNORE`. -/// Override any functions that you want to handle with your module. See `man pam(3)`. -#[allow(unused_variables)] -pub trait PamHooks { - /// This function performs the task of establishing whether the user is permitted to gain access at - /// this time. It should be understood that the user has previously been validated by an - /// authentication module. This function checks for other things. Such things might be: the time of - /// day or the date, the terminal line, remote hostname, etc. This function may also determine - /// things like the expiration on passwords, and respond that the user change it before continuing. - fn acct_mgmt(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { - PamResultCode::PAM_IGNORE - } - - /// This function performs the task of authenticating the user. - fn sm_authenticate(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { - PamResultCode::PAM_IGNORE - } - - /// This function is used to (re-)set the authentication token of the user. - /// - /// The PAM library calls this function twice in succession. The first time with - /// PAM_PRELIM_CHECK and then, if the module does not return PAM_TRY_AGAIN, subsequently with - /// PAM_UPDATE_AUTHTOK. It is only on the second call that the authorization token is - /// (possibly) changed. - fn sm_chauthtok(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { - PamResultCode::PAM_IGNORE - } - - /// This function is called to terminate a session. - fn sm_close_session(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { - PamResultCode::PAM_IGNORE - } - - /// This function is called to commence a session. - fn sm_open_session(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { - PamResultCode::PAM_IGNORE - } - - /// This function performs the task of altering the credentials of the user with respect to the - /// corresponding authorization scheme. Generally, an authentication module may have access to more - /// information about a user than their authentication token. This function is used to make such - /// information available to the application. It should only be called after the user has been - /// authenticated but before a session has been established. - fn sm_setcred(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { - PamResultCode::PAM_IGNORE - } -} - -/// Macro to generate the `extern "C"` entrypoint bindings needed by PAM -/// -/// You can call `pam_hooks!(SomeType);` for any type that implements `PamHooks` -/// -/// ## Examples: -/// -/// Here is full example of a PAM module that would authenticate and authorize everybody: -/// -/// ``` -/// #[macro_use] extern crate pam; -/// -/// use pam::hooks::PamHooks; -/// use pam::module::PamHandle; -/// use pam::constants::{PamResultCode, PamFlag}; -/// use std::ffi::CStr; -/// -/// # fn main() {} -/// struct MyPamModule; -/// pam_hooks!(MyPamModule); -/// -/// impl PamHooks for MyPamModule { -/// fn sm_authenticate(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { -/// println!("Everybody is authenticated!"); -/// PamResultCode::PAM_SUCCESS -/// } -/// -/// fn acct_mgmt(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { -/// println!("Everybody is authorized!"); -/// PamResultCode::PAM_SUCCESS -/// } -/// } -/// ``` -#[macro_export] -macro_rules! pam_hooks { - ($ident:ident) => ( - pub use self::pam_hooks_scope::*; - mod pam_hooks_scope { - use $crate::module::PamHandle; - use $crate::constants::{PamFlag, PamResultCode}; - use $crate::hooks::PamHooks; - use std::ffi::CStr; - use std::os::raw::{c_char, c_int}; - - fn extract_argv<'a>(argc: c_int, argv: *const *const c_char) -> Vec<&'a CStr> { - (0..argc) - .map(|o| unsafe { - CStr::from_ptr(*argv.offset(o as isize) as *const c_char) - }) - .collect() - } - - #[no_mangle] - pub extern "C" fn pam_sm_acct_mgmt( - pamh: &PamHandle, - flags: PamFlag, - argc: c_int, - argv: *const *const c_char, - ) -> PamResultCode { - let args = extract_argv(argc, argv); - super::$ident::acct_mgmt(pamh, args, flags) - } - - #[no_mangle] - pub extern "C" fn pam_sm_authenticate( - pamh: &PamHandle, - flags: PamFlag, - argc: c_int, - argv: *const *const c_char, - ) -> PamResultCode { - let args = extract_argv(argc, argv); - super::$ident::sm_authenticate(pamh, args, flags) - } - - #[no_mangle] - pub extern "C" fn pam_sm_chauthtok( - pamh: &PamHandle, - flags: PamFlag, - argc: c_int, - argv: *const *const c_char, - ) -> PamResultCode { - let args = extract_argv(argc, argv); - super::$ident::sm_chauthtok(pamh, args, flags) - } - - #[no_mangle] - pub extern "C" fn pam_sm_close_session( - pamh: &PamHandle, - flags: PamFlag, - argc: c_int, - argv: *const *const c_char, - ) -> PamResultCode { - let args = extract_argv(argc, argv); - super::$ident::sm_close_session(pamh, args, flags) - } - - #[no_mangle] - pub extern "C" fn pam_sm_open_session( - pamh: &PamHandle, - flags: PamFlag, - argc: c_int, - argv: *const *const c_char, - ) -> PamResultCode { - let args = extract_argv(argc, argv); - super::$ident::sm_open_session(pamh, args, flags) - } - - #[no_mangle] - pub extern "C" fn pam_sm_setcred( - pamh: &PamHandle, - flags: PamFlag, - argc: c_int, - argv: *const *const c_char, - ) -> PamResultCode { - let args = extract_argv(argc, argv); - super::$ident::sm_setcred(pamh, args, flags) - } - } - ) -} - -#[cfg(test)] -pub mod test { - use super::PamHooks; - - struct Foo; - impl PamHooks for Foo {} - - pam_hooks!(Foo); -} \ No newline at end of file diff -r aa7e8bd083ef -r 4263c1d83d5b pam/src/lib.rs --- a/pam/src/lib.rs Tue Sep 26 02:15:28 2017 -0600 +++ b/pam/src/lib.rs Tue Sep 26 02:30:03 2017 -0600 @@ -26,8 +26,9 @@ extern crate libc; +#[doc(hidden)] +pub mod macros; pub mod conv; pub mod constants; pub mod items; pub mod module; -pub mod hooks; diff -r aa7e8bd083ef -r 4263c1d83d5b pam/src/macros.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pam/src/macros.rs Tue Sep 26 02:30:03 2017 -0600 @@ -0,0 +1,127 @@ +/// Macro to generate the `extern "C"` entrypoint bindings needed by PAM +/// +/// You can call `pam_hooks!(SomeType);` for any type that implements `PamHooks` +/// +/// ## Examples: +/// +/// Here is full example of a PAM module that would authenticate and authorize everybody: +/// +/// ``` +/// #[macro_use] extern crate pam; +/// +/// use pam::module::{PamHooks, PamHandle}; +/// use pam::constants::{PamResultCode, PamFlag}; +/// use std::ffi::CStr; +/// +/// # fn main() {} +/// struct MyPamModule; +/// pam_hooks!(MyPamModule); +/// +/// impl PamHooks for MyPamModule { +/// fn sm_authenticate(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { +/// println!("Everybody is authenticated!"); +/// PamResultCode::PAM_SUCCESS +/// } +/// +/// fn acct_mgmt(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { +/// println!("Everybody is authorized!"); +/// PamResultCode::PAM_SUCCESS +/// } +/// } +/// ``` +#[macro_export] +macro_rules! pam_hooks { + ($ident:ident) => ( + pub use self::pam_hooks_scope::*; + mod pam_hooks_scope { + use $crate::module::{PamHandle, PamHooks}; + use $crate::constants::{PamFlag, PamResultCode}; + use std::ffi::CStr; + use std::os::raw::{c_char, c_int}; + + fn extract_argv<'a>(argc: c_int, argv: *const *const c_char) -> Vec<&'a CStr> { + (0..argc) + .map(|o| unsafe { + CStr::from_ptr(*argv.offset(o as isize) as *const c_char) + }) + .collect() + } + + #[no_mangle] + pub extern "C" fn pam_sm_acct_mgmt( + pamh: &PamHandle, + flags: PamFlag, + argc: c_int, + argv: *const *const c_char, + ) -> PamResultCode { + let args = extract_argv(argc, argv); + super::$ident::acct_mgmt(pamh, args, flags) + } + + #[no_mangle] + pub extern "C" fn pam_sm_authenticate( + pamh: &PamHandle, + flags: PamFlag, + argc: c_int, + argv: *const *const c_char, + ) -> PamResultCode { + let args = extract_argv(argc, argv); + super::$ident::sm_authenticate(pamh, args, flags) + } + + #[no_mangle] + pub extern "C" fn pam_sm_chauthtok( + pamh: &PamHandle, + flags: PamFlag, + argc: c_int, + argv: *const *const c_char, + ) -> PamResultCode { + let args = extract_argv(argc, argv); + super::$ident::sm_chauthtok(pamh, args, flags) + } + + #[no_mangle] + pub extern "C" fn pam_sm_close_session( + pamh: &PamHandle, + flags: PamFlag, + argc: c_int, + argv: *const *const c_char, + ) -> PamResultCode { + let args = extract_argv(argc, argv); + super::$ident::sm_close_session(pamh, args, flags) + } + + #[no_mangle] + pub extern "C" fn pam_sm_open_session( + pamh: &PamHandle, + flags: PamFlag, + argc: c_int, + argv: *const *const c_char, + ) -> PamResultCode { + let args = extract_argv(argc, argv); + super::$ident::sm_open_session(pamh, args, flags) + } + + #[no_mangle] + pub extern "C" fn pam_sm_setcred( + pamh: &PamHandle, + flags: PamFlag, + argc: c_int, + argv: *const *const c_char, + ) -> PamResultCode { + let args = extract_argv(argc, argv); + super::$ident::sm_setcred(pamh, args, flags) + } + } + ) +} + +#[cfg(test)] +pub mod test { + use module::PamHooks; + + struct Foo; + impl PamHooks for Foo {} + + pam_hooks!(Foo); +} \ No newline at end of file diff -r aa7e8bd083ef -r 4263c1d83d5b pam/src/module.rs --- a/pam/src/module.rs Tue Sep 26 02:15:28 2017 -0600 +++ b/pam/src/module.rs Tue Sep 26 02:30:03 2017 -0600 @@ -4,7 +4,7 @@ use std::{mem, ptr}; use std::ffi::{CStr, CString}; -use constants::{PamResultCode, PamItemType}; +use constants::{PamResultCode, PamItemType, PamFlag}; /// Opaque type, used as a pointer when making pam API calls. /// @@ -181,4 +181,55 @@ Err(res) } } +} + +/// Provides functions that are invoked by the entrypoints generated by the +/// [`pam_hooks!` macro](../macro.pam_hooks.html). +/// +/// All of hooks are ignored by PAM dispatch by default given the default return value of `PAM_IGNORE`. +/// Override any functions that you want to handle with your module. See `man pam(3)`. +#[allow(unused_variables)] +pub trait PamHooks { + /// This function performs the task of establishing whether the user is permitted to gain access at + /// this time. It should be understood that the user has previously been validated by an + /// authentication module. This function checks for other things. Such things might be: the time of + /// day or the date, the terminal line, remote hostname, etc. This function may also determine + /// things like the expiration on passwords, and respond that the user change it before continuing. + fn acct_mgmt(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { + PamResultCode::PAM_IGNORE + } + + /// This function performs the task of authenticating the user. + fn sm_authenticate(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { + PamResultCode::PAM_IGNORE + } + + /// This function is used to (re-)set the authentication token of the user. + /// + /// The PAM library calls this function twice in succession. The first time with + /// PAM_PRELIM_CHECK and then, if the module does not return PAM_TRY_AGAIN, subsequently with + /// PAM_UPDATE_AUTHTOK. It is only on the second call that the authorization token is + /// (possibly) changed. + fn sm_chauthtok(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { + PamResultCode::PAM_IGNORE + } + + /// This function is called to terminate a session. + fn sm_close_session(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { + PamResultCode::PAM_IGNORE + } + + /// This function is called to commence a session. + fn sm_open_session(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { + PamResultCode::PAM_IGNORE + } + + /// This function performs the task of altering the credentials of the user with respect to the + /// corresponding authorization scheme. Generally, an authentication module may have access to more + /// information about a user than their authentication token. This function is used to make such + /// information available to the application. It should only be called after the user has been + /// authenticated but before a session has been established. + fn sm_setcred(pamh: &PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { + PamResultCode::PAM_IGNORE + } } \ No newline at end of file