Mercurial > crates > nonstick
comparison src/macros.rs @ 56:daa2cde64601
Big big refactor. Probably should have been multiple changes.
- Makes FFI safer by explicitly specifying c_int in calls.
- Uses ToPrimitive/FromPrimitive to make this easier.
- Pulls PamFlag variables into a bitflags! struct.
- Pulls PamMessageStyle variables into an enum.
- Renames ResultCode to ErrorCode.
- Switches from PAM_SUCCESS to using a Result<(), ErrorCode>.
- Uses thiserror to make ErrorCode into an Error.
- Gets rid of pam_try! because now we have Results.
- Expands some names (e.g. Conv to Conversation).
- Adds more doc comments.
- Returns passwords as a SecureString, to avoid unnecessarily
keeping it around in memory.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sun, 04 May 2025 02:56:55 -0400 |
| parents | a921b72743e4 |
| children | 3f4a77aa88be |
comparison
equal
deleted
inserted
replaced
| 55:676675c3d434 | 56:daa2cde64601 |
|---|---|
| 5 /// ## Examples: | 5 /// ## Examples: |
| 6 /// | 6 /// |
| 7 /// Here is full example of a PAM module that would authenticate and authorize everybody: | 7 /// Here is full example of a PAM module that would authenticate and authorize everybody: |
| 8 /// | 8 /// |
| 9 /// ``` | 9 /// ``` |
| 10 /// #[macro_use] extern crate pam; | 10 /// #[macro_use] extern crate nonstick; |
| 11 /// | 11 /// |
| 12 /// use pam::module::{PamHooks, PamHandle}; | 12 /// use nonstick::module::{PamHooks, PamHandle}; |
| 13 /// use pam::constants::{PamResultCode, PamFlag}; | 13 /// use nonstick::constants::{PamResult, Flags}; |
| 14 /// use std::ffi::CStr; | 14 /// use std::ffi::CStr; |
| 15 /// | 15 /// |
| 16 /// # fn main() {} | 16 /// # fn main() {} |
| 17 /// struct MyPamModule; | 17 /// struct MyPamModule; |
| 18 /// pam_hooks!(MyPamModule); | 18 /// pam_hooks!(MyPamModule); |
| 19 /// | 19 /// |
| 20 /// impl PamHooks for MyPamModule { | 20 /// impl PamHooks for MyPamModule { |
| 21 /// fn sm_authenticate(pamh: &mut PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { | 21 /// fn acct_mgmt(pamh: &mut PamHandle, args: Vec<&CStr>, flags: Flags) -> PamResult<()> { |
| 22 /// println!("Everybody is authenticated!"); | 22 /// println!("Everybody is authorized!"); |
| 23 /// PamResultCode::PAM_SUCCESS | 23 /// Ok(()) |
| 24 /// } | 24 /// } |
| 25 /// | 25 /// |
| 26 /// fn acct_mgmt(pamh: &mut PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { | 26 /// fn sm_authenticate(pamh: &mut PamHandle, args: Vec<&CStr>, flags: Flags) -> PamResult<()> { |
| 27 /// println!("Everybody is authorized!"); | 27 /// println!("Everybody is authenticated!"); |
| 28 /// PamResultCode::PAM_SUCCESS | 28 /// Ok(()) |
| 29 /// } | 29 /// } |
| 30 /// } | 30 /// } |
| 31 /// ``` | 31 /// ``` |
| 32 #[macro_export] | 32 #[macro_export] |
| 33 macro_rules! pam_hooks { | 33 macro_rules! pam_hooks { |
| 34 ($ident:ident) => { | 34 ($ident:ident) => { |
| 35 pub use self::pam_hooks_scope::*; | 35 pub use self::pam_hooks_scope::*; |
| 36 mod pam_hooks_scope { | 36 mod pam_hooks_scope { |
| 37 use std::ffi::CStr; | 37 use std::ffi::CStr; |
| 38 use std::os::raw::{c_char, c_int}; | 38 use std::os::raw::{c_char, c_int}; |
| 39 use $crate::constants::{PamFlag, PamResultCode}; | 39 use $crate::constants::{Flags, ErrorCode}; |
| 40 use $crate::module::{PamHandle, PamHooks}; | 40 use $crate::module::{PamHandle, PamHooks}; |
| 41 | 41 |
| 42 fn extract_argv<'a>(argc: c_int, argv: *const *const c_char) -> Vec<&'a CStr> { | 42 fn extract_argv<'a>(argc: c_int, argv: *const *const c_char) -> Vec<&'a CStr> { |
| 43 (0..argc) | 43 (0..argc) |
| 44 .map(|o| unsafe { CStr::from_ptr(*argv.offset(o as isize) as *const c_char) }) | 44 .map(|o| unsafe { CStr::from_ptr(*argv.offset(o as isize) as *const c_char) }) |
| 46 } | 46 } |
| 47 | 47 |
| 48 #[no_mangle] | 48 #[no_mangle] |
| 49 pub extern "C" fn pam_sm_acct_mgmt( | 49 pub extern "C" fn pam_sm_acct_mgmt( |
| 50 pamh: &mut PamHandle, | 50 pamh: &mut PamHandle, |
| 51 flags: PamFlag, | 51 flags: Flags, |
| 52 argc: c_int, | 52 argc: c_int, |
| 53 argv: *const *const c_char, | 53 argv: *const *const c_char, |
| 54 ) -> PamResultCode { | 54 ) -> c_int { |
| 55 let args = extract_argv(argc, argv); | 55 let args = extract_argv(argc, argv); |
| 56 super::$ident::acct_mgmt(pamh, args, flags) | 56 ErrorCode::result_to_c(super::$ident::acct_mgmt(pamh, args, flags)) |
| 57 } | 57 } |
| 58 | 58 |
| 59 #[no_mangle] | 59 #[no_mangle] |
| 60 pub extern "C" fn pam_sm_authenticate( | 60 pub extern "C" fn pam_sm_authenticate( |
| 61 pamh: &mut PamHandle, | 61 pamh: &mut PamHandle, |
| 62 flags: PamFlag, | 62 flags: Flags, |
| 63 argc: c_int, | 63 argc: c_int, |
| 64 argv: *const *const c_char, | 64 argv: *const *const c_char, |
| 65 ) -> PamResultCode { | 65 ) -> c_int { |
| 66 let args = extract_argv(argc, argv); | 66 let args = extract_argv(argc, argv); |
| 67 super::$ident::sm_authenticate(pamh, args, flags) | 67 ErrorCode::result_to_c(super::$ident::sm_authenticate(pamh, args, flags)) |
| 68 } | 68 } |
| 69 | 69 |
| 70 #[no_mangle] | 70 #[no_mangle] |
| 71 pub extern "C" fn pam_sm_chauthtok( | 71 pub extern "C" fn pam_sm_chauthtok( |
| 72 pamh: &mut PamHandle, | 72 pamh: &mut PamHandle, |
| 73 flags: PamFlag, | 73 flags: Flags, |
| 74 argc: c_int, | 74 argc: c_int, |
| 75 argv: *const *const c_char, | 75 argv: *const *const c_char, |
| 76 ) -> PamResultCode { | 76 ) -> c_int { |
| 77 let args = extract_argv(argc, argv); | 77 let args = extract_argv(argc, argv); |
| 78 super::$ident::sm_chauthtok(pamh, args, flags) | 78 ErrorCode::result_to_c(super::$ident::sm_chauthtok(pamh, args, flags)) |
| 79 } | 79 } |
| 80 | 80 |
| 81 #[no_mangle] | 81 #[no_mangle] |
| 82 pub extern "C" fn pam_sm_close_session( | 82 pub extern "C" fn pam_sm_close_session( |
| 83 pamh: &mut PamHandle, | 83 pamh: &mut PamHandle, |
| 84 flags: PamFlag, | 84 flags: Flags, |
| 85 argc: c_int, | 85 argc: c_int, |
| 86 argv: *const *const c_char, | 86 argv: *const *const c_char, |
| 87 ) -> PamResultCode { | 87 ) -> c_int { |
| 88 let args = extract_argv(argc, argv); | 88 let args = extract_argv(argc, argv); |
| 89 super::$ident::sm_close_session(pamh, args, flags) | 89 ErrorCode::result_to_c(super::$ident::sm_close_session(pamh, args, flags)) |
| 90 } | 90 } |
| 91 | 91 |
| 92 #[no_mangle] | 92 #[no_mangle] |
| 93 pub extern "C" fn pam_sm_open_session( | 93 pub extern "C" fn pam_sm_open_session( |
| 94 pamh: &mut PamHandle, | 94 pamh: &mut PamHandle, |
| 95 flags: PamFlag, | 95 flags: Flags, |
| 96 argc: c_int, | 96 argc: c_int, |
| 97 argv: *const *const c_char, | 97 argv: *const *const c_char, |
| 98 ) -> PamResultCode { | 98 ) -> c_int { |
| 99 let args = extract_argv(argc, argv); | 99 let args = extract_argv(argc, argv); |
| 100 super::$ident::sm_open_session(pamh, args, flags) | 100 ErrorCode::result_to_c(super::$ident::sm_open_session(pamh, args, flags)) |
| 101 } | 101 } |
| 102 | 102 |
| 103 #[no_mangle] | 103 #[no_mangle] |
| 104 pub extern "C" fn pam_sm_setcred( | 104 pub extern "C" fn pam_sm_setcred( |
| 105 pamh: &mut PamHandle, | 105 pamh: &mut PamHandle, |
| 106 flags: PamFlag, | 106 flags: Flags, |
| 107 argc: c_int, | 107 argc: c_int, |
| 108 argv: *const *const c_char, | 108 argv: *const *const c_char, |
| 109 ) -> PamResultCode { | 109 ) -> c_int { |
| 110 let args = extract_argv(argc, argv); | 110 let args = extract_argv(argc, argv); |
| 111 super::$ident::sm_setcred(pamh, args, flags) | 111 ErrorCode::result_to_c(super::$ident::sm_setcred(pamh, args, flags)) |
| 112 } | 112 } |
| 113 } | |
| 114 }; | |
| 115 } | |
| 116 | |
| 117 #[macro_export] | |
| 118 macro_rules! pam_try { | |
| 119 ($r:expr) => { | |
| 120 match $r { | |
| 121 Ok(t) => t, | |
| 122 Err(e) => return e, | |
| 123 } | |
| 124 }; | |
| 125 ($r:expr, $e:expr) => { | |
| 126 match $r { | |
| 127 Ok(t) => t, | |
| 128 Err(_) => return $e, | |
| 129 } | 113 } |
| 130 }; | 114 }; |
| 131 } | 115 } |
| 132 | 116 |
| 133 #[cfg(test)] | 117 #[cfg(test)] |
