diff src/macros.rs @ 45:ce47901aab7a

Rename to “nonstick”, move to root, update docs and license. - Renames the crate to “nonstick”. - Moves the main library to the root of the repository. - Removes the example PAM modules. - Updates copyright information in LICENSE file. - Updates the README.
author Paul Fisher <paul@pfish.zone>
date Tue, 15 Apr 2025 00:50:23 -0400
parents pam/src/macros.rs@ec70822cbdef
children a921b72743e4
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/macros.rs	Tue Apr 15 00:50:23 2025 -0400
@@ -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);
+}