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 } |