Mercurial > crates > nonstick
diff pam/src/macros.rs @ 22:4263c1d83d5b
Refactor PamHooks into modules mod
author | Anthony Nowell <anthony@algorithmia.com> |
---|---|
date | Tue, 26 Sep 2017 02:30:03 -0600 |
parents | |
children | ec70822cbdef |
line wrap: on
line diff
--- /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