Mercurial > crates > nonstick
view src/macros.rs @ 59:3f4a77aa88be
Fix string copyting and improve error situation.
This change is too big and includes several things:
- Fix copying strings from PAM by fixing const and mut on pam funcs.
- Improve error enums by simplifying conversions and removing
unnecessary and ambiguous "success" variants.
- Make a bunch of casts nicer.
- Assorted other cleanup.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Wed, 21 May 2025 00:27:18 -0400 |
parents | daa2cde64601 |
children |
line wrap: on
line source
/// 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 nonstick; /// /// use nonstick::module::{PamHooks, PamHandle}; /// use nonstick::constants::{PamResult, Flags}; /// use std::ffi::CStr; /// /// # fn main() {} /// struct MyPamModule; /// pam_hooks!(MyPamModule); /// /// impl PamHooks for MyPamModule { /// fn acct_mgmt(pamh: &mut PamHandle, args: Vec<&CStr>, flags: Flags) -> PamResult<()> { /// println!("Everybody is authorized!"); /// Ok(()) /// } /// /// fn sm_authenticate(pamh: &mut PamHandle, args: Vec<&CStr>, flags: Flags) -> PamResult<()> { /// println!("Everybody is authenticated!"); /// Ok(()) /// } /// } /// ``` #[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::{ErrorCode, Flags}; 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: Flags, argc: c_int, argv: *const *const c_char, ) -> c_int { let args = extract_argv(argc, argv); ErrorCode::result_to_c(super::$ident::acct_mgmt(pamh, args, flags)) } #[no_mangle] pub extern "C" fn pam_sm_authenticate( pamh: &mut PamHandle, flags: Flags, argc: c_int, argv: *const *const c_char, ) -> c_int { let args = extract_argv(argc, argv); ErrorCode::result_to_c(super::$ident::sm_authenticate(pamh, args, flags)) } #[no_mangle] pub extern "C" fn pam_sm_chauthtok( pamh: &mut PamHandle, flags: Flags, argc: c_int, argv: *const *const c_char, ) -> c_int { let args = extract_argv(argc, argv); ErrorCode::result_to_c(super::$ident::sm_chauthtok(pamh, args, flags)) } #[no_mangle] pub extern "C" fn pam_sm_close_session( pamh: &mut PamHandle, flags: Flags, argc: c_int, argv: *const *const c_char, ) -> c_int { let args = extract_argv(argc, argv); ErrorCode::result_to_c(super::$ident::sm_close_session(pamh, args, flags)) } #[no_mangle] pub extern "C" fn pam_sm_open_session( pamh: &mut PamHandle, flags: Flags, argc: c_int, argv: *const *const c_char, ) -> c_int { let args = extract_argv(argc, argv); ErrorCode::result_to_c(super::$ident::sm_open_session(pamh, args, flags)) } #[no_mangle] pub extern "C" fn pam_sm_setcred( pamh: &mut PamHandle, flags: Flags, argc: c_int, argv: *const *const c_char, ) -> c_int { let args = extract_argv(argc, argv); ErrorCode::result_to_c(super::$ident::sm_setcred(pamh, args, flags)) } } }; } #[cfg(test)] pub mod test { use crate::module::PamHooks; struct Foo; impl PamHooks for Foo {} pam_hooks!(Foo); }