feat: clone from: https://github.com/anowell/pam-rs
This commit is contained in:
141
pam/src/macros.rs
Normal file
141
pam/src/macros.rs
Normal file
@@ -0,0 +1,141 @@
|
||||
/// 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: &mut PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode {
|
||||
/// println!("Everybody is authenticated!");
|
||||
/// PamResultCode::PAM_SUCCESS
|
||||
/// }
|
||||
///
|
||||
/// fn acct_mgmt(pamh: &mut 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 std::ffi::CStr;
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use $crate::constants::{PamFlag, PamResultCode};
|
||||
use $crate::module::{PamHandle, PamHooks};
|
||||
|
||||
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: &mut 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: &mut 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: &mut 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: &mut 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: &mut 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: &mut 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)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! pam_try {
|
||||
($r:expr) => {
|
||||
match $r {
|
||||
Ok(t) => t,
|
||||
Err(e) => return e,
|
||||
}
|
||||
};
|
||||
($r:expr, $e:expr) => {
|
||||
match $r {
|
||||
Ok(t) => t,
|
||||
Err(_) => return $e,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use module::PamHooks;
|
||||
|
||||
struct Foo;
|
||||
impl PamHooks for Foo {}
|
||||
|
||||
pam_hooks!(Foo);
|
||||
}
|
||||
Reference in New Issue
Block a user