Mercurial > crates > nonstick
comparison src/libpam/module.rs @ 173:46e8ce5cd5d1
Miscellaneous doc and code cleanups.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Tue, 29 Jul 2025 16:52:32 -0400 |
| parents | 6727cbe56f4a |
| children | 9e4ce1631bd3 |
comparison
equal
deleted
inserted
replaced
| 172:6727cbe56f4a | 173:46e8ce5cd5d1 |
|---|---|
| 4 use crate::{AuthnFlags, AuthtokAction, BaseFlags, CredAction}; | 4 use crate::{AuthnFlags, AuthtokAction, BaseFlags, CredAction}; |
| 5 use std::ffi::{c_char, c_int, c_void, CStr}; | 5 use std::ffi::{c_char, c_int, c_void, CStr}; |
| 6 | 6 |
| 7 /// Generates the dynamic library entry points for a PAM module | 7 /// Generates the dynamic library entry points for a PAM module |
| 8 /// | 8 /// |
| 9 /// Calling `pam_hooks!(SomeType)` on a type that implements | 9 /// Calling `pam_export!(SomeType)` on a type that implements |
| 10 /// [`PamModule`] will generate the exported | 10 /// [`PamModule`] will generate the exported |
| 11 /// `extern "C"` functions that PAM uses to call into your module. | 11 /// `extern "C"` functions that PAM uses to call into your module. |
| 12 /// | 12 /// |
| 13 /// ## Examples: | 13 /// ## Examples: |
| 14 /// | 14 /// |
| 15 /// Here is full example of a PAM module that would authenticate | 15 /// Here is full example of a PAM module that would authenticate |
| 16 /// and authorize everybody: | 16 /// and authorize everybody: |
| 17 /// | 17 /// |
| 18 /// ```no_run | 18 /// ```no_run |
| 19 /// use nonstick::{ | 19 /// use nonstick::{ |
| 20 /// pam_hooks, ConversationAdapter, AuthnFlags, LibPamTransaction, ModuleClient, PamModule, | 20 /// pam_export, ConversationAdapter, AuthnFlags, LibPamTransaction, ModuleClient, PamModule, |
| 21 /// Result as PamResult, | 21 /// Result as PamResult, |
| 22 /// }; | 22 /// }; |
| 23 /// use std::ffi::CStr; | 23 /// use std::ffi::CStr; |
| 24 /// # fn main() {} | 24 /// # fn main() {} |
| 25 /// | 25 /// |
| 26 /// struct MyPamModule; | 26 /// struct MyPamModule; |
| 27 /// pam_hooks!(MyPamModule); | 27 /// pam_export!(MyPamModule); |
| 28 /// | 28 /// |
| 29 /// impl<T: ModuleClient> PamModule<T> for MyPamModule { | 29 /// impl<T: ModuleClient> PamModule<T> for MyPamModule { |
| 30 /// fn authenticate(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> PamResult<()> { | 30 /// fn authenticate(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> PamResult<()> { |
| 31 /// let password = handle.authtok(Some("what's your password?".as_ref()))?; | 31 /// let password = handle.authtok(Some("what's your password?".as_ref()))?; |
| 32 /// let response = | 32 /// let response = |
| 42 /// Ok(()) | 42 /// Ok(()) |
| 43 /// } | 43 /// } |
| 44 /// } | 44 /// } |
| 45 /// ``` | 45 /// ``` |
| 46 #[macro_export] | 46 #[macro_export] |
| 47 macro_rules! pam_hooks { | 47 macro_rules! pam_export { |
| 48 ($ident:ident) => { | 48 ($ident:ident) => { |
| 49 mod _pam_hooks_scope { | 49 mod __pam_export_scope { |
| 50 use std::ffi::{c_char, c_int, c_void}; | 50 use std::ffi::{c_char, c_int, c_void}; |
| 51 use $crate::constants::{RawFlags, ReturnCode}; | 51 use $crate::constants::{RawFlags, ReturnCode}; |
| 52 use $crate::ModuleExporter; | 52 use $crate::libpam::module; |
| 53 | 53 |
| 54 macro_rules! export { | 54 macro_rules! export { |
| 55 ($func:ident) => { | 55 ($func:ident) => { |
| 56 #[no_mangle] | 56 #[no_mangle] |
| 57 unsafe extern "C" fn $func( | 57 unsafe extern "C" fn $func( |
| 59 flags: RawFlags, | 59 flags: RawFlags, |
| 60 argc: c_int, | 60 argc: c_int, |
| 61 argv: *const *const c_char, | 61 argv: *const *const c_char, |
| 62 ) -> c_int { | 62 ) -> c_int { |
| 63 let ret: ReturnCode = | 63 let ret: ReturnCode = |
| 64 ModuleExporter::$func::<super::$ident>(pamh, flags, argc, argv).into(); | 64 module::$func::<super::$ident>(pamh, flags, argc, argv).into(); |
| 65 ret.into() | 65 ret.into() |
| 66 } | 66 } |
| 67 }; | 67 }; |
| 68 } | 68 } |
| 69 | 69 |
| 76 } | 76 } |
| 77 }; | 77 }; |
| 78 } | 78 } |
| 79 | 79 |
| 80 #[doc(hidden)] | 80 #[doc(hidden)] |
| 81 pub struct ModuleExporter; | 81 pub unsafe fn pam_sm_acct_mgmt<M: PamModule<LibPamHandle>>( |
| 82 pamh: *mut c_void, | |
| 83 flags: RawFlags, | |
| 84 argc: c_int, | |
| 85 argv: *const *const c_char, | |
| 86 ) -> Result<()> { | |
| 87 let handle = wrap(pamh)?; | |
| 88 let args = extract_argv(argc, argv); | |
| 89 M::account_management(handle, args, AuthnFlags::from(flags)) | |
| 90 } | |
| 82 | 91 |
| 83 // All of the below are only intended to be called directly from C. | 92 #[doc(hidden)] |
| 84 #[allow(clippy::missing_safety_doc)] | 93 pub unsafe fn pam_sm_authenticate<M: PamModule<LibPamHandle>>( |
| 85 impl ModuleExporter { | 94 pamh: *mut c_void, |
| 86 pub unsafe fn pam_sm_acct_mgmt<M: PamModule<LibPamHandle>>( | 95 flags: RawFlags, |
| 87 pamh: *mut c_void, | 96 argc: c_int, |
| 88 flags: RawFlags, | 97 argv: *const *const c_char, |
| 89 argc: c_int, | 98 ) -> Result<()> { |
| 90 argv: *const *const c_char, | 99 let handle = wrap(pamh)?; |
| 91 ) -> Result<()> { | 100 let args = extract_argv(argc, argv); |
| 92 let handle = wrap(pamh)?; | 101 M::authenticate(handle, args, AuthnFlags::from(flags)) |
| 93 let args = extract_argv(argc, argv); | 102 } |
| 94 M::account_management(handle, args, AuthnFlags::from(flags)) | |
| 95 } | |
| 96 | 103 |
| 97 pub unsafe fn pam_sm_authenticate<M: PamModule<LibPamHandle>>( | 104 #[doc(hidden)] |
| 98 pamh: *mut c_void, | 105 pub unsafe fn pam_sm_chauthtok<M: PamModule<LibPamHandle>>( |
| 99 flags: RawFlags, | 106 pamh: *mut c_void, |
| 100 argc: c_int, | 107 flags: RawFlags, |
| 101 argv: *const *const c_char, | 108 argc: c_int, |
| 102 ) -> Result<()> { | 109 argv: *const *const c_char, |
| 103 let handle = wrap(pamh)?; | 110 ) -> Result<()> { |
| 104 let args = extract_argv(argc, argv); | 111 let handle = wrap(pamh)?; |
| 105 M::authenticate(handle, args, AuthnFlags::from(flags)) | 112 let (action, flags) = AuthtokAction::extract(flags)?; |
| 106 } | 113 let args = extract_argv(argc, argv); |
| 114 M::change_authtok(handle, args, action, flags) | |
| 115 } | |
| 107 | 116 |
| 108 pub unsafe fn pam_sm_chauthtok<M: PamModule<LibPamHandle>>( | 117 #[doc(hidden)] |
| 109 pamh: *mut c_void, | 118 pub unsafe fn pam_sm_close_session<M: PamModule<LibPamHandle>>( |
| 110 flags: RawFlags, | 119 pamh: *mut c_void, |
| 111 argc: c_int, | 120 flags: RawFlags, |
| 112 argv: *const *const c_char, | 121 argc: c_int, |
| 113 ) -> Result<()> { | 122 argv: *const *const c_char, |
| 114 let handle = wrap(pamh)?; | 123 ) -> Result<()> { |
| 115 let (action, flags) = AuthtokAction::extract(flags)?; | 124 let handle = wrap(pamh)?; |
| 116 let args = extract_argv(argc, argv); | 125 let args = extract_argv(argc, argv); |
| 117 M::change_authtok(handle, args, action, flags) | 126 M::close_session(handle, args, BaseFlags::from(flags)) |
| 118 } | 127 } |
| 119 | 128 |
| 120 pub unsafe fn pam_sm_close_session<M: PamModule<LibPamHandle>>( | 129 #[doc(hidden)] |
| 121 pamh: *mut c_void, | 130 pub unsafe fn pam_sm_open_session<M: PamModule<LibPamHandle>>( |
| 122 flags: RawFlags, | 131 pamh: *mut c_void, |
| 123 argc: c_int, | 132 flags: RawFlags, |
| 124 argv: *const *const c_char, | 133 argc: c_int, |
| 125 ) -> Result<()> { | 134 argv: *const *const c_char, |
| 126 let handle = wrap(pamh)?; | 135 ) -> Result<()> { |
| 127 let args = extract_argv(argc, argv); | 136 let handle = wrap(pamh)?; |
| 128 M::close_session(handle, args, BaseFlags::from(flags)) | 137 let args = extract_argv(argc, argv); |
| 129 } | 138 M::open_session(handle, args, BaseFlags::from(flags)) |
| 139 } | |
| 130 | 140 |
| 131 pub unsafe fn pam_sm_open_session<M: PamModule<LibPamHandle>>( | 141 #[doc(hidden)] |
| 132 pamh: *mut c_void, | 142 pub unsafe fn pam_sm_setcred<M: PamModule<LibPamHandle>>( |
| 133 flags: RawFlags, | 143 pamh: *mut c_void, |
| 134 argc: c_int, | 144 flags: RawFlags, |
| 135 argv: *const *const c_char, | 145 argc: c_int, |
| 136 ) -> Result<()> { | 146 argv: *const *const c_char, |
| 137 let handle = wrap(pamh)?; | 147 ) -> Result<()> { |
| 138 let args = extract_argv(argc, argv); | 148 let handle = wrap(pamh)?; |
| 139 M::open_session(handle, args, BaseFlags::from(flags)) | 149 let (action, flags) = CredAction::extract(flags)?; |
| 140 } | 150 let args = extract_argv(argc, argv); |
| 141 | 151 M::set_credentials(handle, args, action, flags) |
| 142 pub unsafe fn pam_sm_setcred<M: PamModule<LibPamHandle>>( | |
| 143 pamh: *mut c_void, | |
| 144 flags: RawFlags, | |
| 145 argc: c_int, | |
| 146 argv: *const *const c_char, | |
| 147 ) -> Result<()> { | |
| 148 let handle = wrap(pamh)?; | |
| 149 let (action, flags) = CredAction::extract(flags)?; | |
| 150 let args = extract_argv(argc, argv); | |
| 151 M::set_credentials(handle, args, action, flags) | |
| 152 } | |
| 153 } | 152 } |
| 154 | 153 |
| 155 /// Turns `argc`/`argv` into a [Vec] of [CStr]s. | 154 /// Turns `argc`/`argv` into a [Vec] of [CStr]s. |
| 156 /// | 155 /// |
| 157 /// # Safety | 156 /// # Safety |
| 180 // Compile-time test that the `pam_hooks` macro compiles. | 179 // Compile-time test that the `pam_hooks` macro compiles. |
| 181 use crate::{ModuleClient, PamModule}; | 180 use crate::{ModuleClient, PamModule}; |
| 182 struct Foo; | 181 struct Foo; |
| 183 impl<T: ModuleClient> PamModule<T> for Foo {} | 182 impl<T: ModuleClient> PamModule<T> for Foo {} |
| 184 | 183 |
| 185 pam_hooks!(Foo); | 184 pam_export!(Foo); |
| 186 } | 185 } |
