1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
/// 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::constants::{PamFlag, PamResultCode};
/// use pam::module::{PamHandle, PamHooks};
/// 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 std::ffi::CStr;
use std::os::raw::{c_char, c_int};
use $crate::pam::constants::{PamFlag, PamResultCode};
use $crate::pam::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: &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)
}
}
};
}