Mercurial > crates > nonstick
comparison src/module.rs @ 166:2f5913131295
Separate flag/action flags into flags and action.
This also individualizes the type of flag for each PAM function,
so that you can only call a function with the right flags and values.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Tue, 15 Jul 2025 00:32:24 -0400 |
parents | 1bc52025156b |
children | e27c5c667a5a |
comparison
equal
deleted
inserted
replaced
165:c4b1e280463c | 166:2f5913131295 |
---|---|
1 //! Functions and types useful for implementing a PAM module. | 1 //! Functions and types useful for implementing a PAM module. |
2 | 2 |
3 // Temporarily allowed until we get the actual conversation functions hooked up. | 3 // Temporarily allowed until we get the actual conversation functions hooked up. |
4 #![allow(dead_code)] | 4 #![allow(dead_code)] |
5 | 5 |
6 use crate::constants::{ErrorCode, Flags, Result}; | 6 use crate::constants::{ |
7 AuthnFlags, AuthtokAction, AuthtokFlags, BaseFlags, CredAction, ErrorCode, Result, | |
8 }; | |
7 use crate::handle::ModuleClient; | 9 use crate::handle::ModuleClient; |
8 use std::ffi::CStr; | 10 use std::ffi::CStr; |
9 | 11 |
10 /// A trait for a PAM module to implement. | 12 /// A trait for a PAM module to implement. |
11 /// | 13 /// |
33 /// and verify them against something. | 35 /// and verify them against something. |
34 /// | 36 /// |
35 /// See [the Module Writer's Guide entry for `pam_sm_authenticate`][mwg] | 37 /// See [the Module Writer's Guide entry for `pam_sm_authenticate`][mwg] |
36 /// for more information. | 38 /// for more information. |
37 /// | 39 /// |
38 /// # Valid flags | |
39 /// | |
40 /// This function may be called with the following flags set: | |
41 /// | |
42 /// - [`Flags::SILENT`] | |
43 /// - [`Flags::DISALLOW_NULL_AUTHTOK`] | |
44 /// | |
45 /// # Returns | 40 /// # Returns |
46 /// | 41 /// |
47 /// If the password check was successful, return `Ok(())`. | 42 /// If the password check was successful, return `Ok(())`. |
48 /// | 43 /// |
49 /// Sensible error codes to return include: | 44 /// Sensible error codes to return include: |
57 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. | 52 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. |
58 /// - [`ErrorCode::MaxTries`]: The user has tried authenticating too many times. | 53 /// - [`ErrorCode::MaxTries`]: The user has tried authenticating too many times. |
59 /// They should not try again. | 54 /// They should not try again. |
60 /// | 55 /// |
61 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-auth.html#mwg-pam_sm_authenticate | 56 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-auth.html#mwg-pam_sm_authenticate |
62 fn authenticate(handle: &mut T, args: Vec<&CStr>, flags: Flags) -> Result<()> { | 57 fn authenticate(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> Result<()> { |
63 Err(ErrorCode::Ignore) | 58 Err(ErrorCode::Ignore) |
64 } | 59 } |
65 | 60 |
66 /// Perform "account management". | 61 /// Perform "account management". |
67 /// | 62 /// |
76 /// and alert that the user change it before continuing, | 71 /// and alert that the user change it before continuing, |
77 /// or really do whatever you want. | 72 /// or really do whatever you want. |
78 /// | 73 /// |
79 /// See [the Module Writer's Guide entry for `pam_sm_acct_mgmt`][mwg] | 74 /// See [the Module Writer's Guide entry for `pam_sm_acct_mgmt`][mwg] |
80 /// for more information. | 75 /// for more information. |
81 /// | |
82 /// # Valid flags | |
83 /// | |
84 /// This function may be called with the following flags set: | |
85 /// | |
86 /// - [`Flags::SILENT`] | |
87 /// - [`Flags::DISALLOW_NULL_AUTHTOK`] | |
88 /// | 76 /// |
89 /// # Returns | 77 /// # Returns |
90 /// | 78 /// |
91 /// If the user should be allowed to log in, return `Ok(())`. | 79 /// If the user should be allowed to log in, return `Ok(())`. |
92 /// | 80 /// |
99 /// this module in [`Self::change_authtok`]. | 87 /// this module in [`Self::change_authtok`]. |
100 /// - [`ErrorCode::PermissionDenied`]: This one is pretty self-explanatory. | 88 /// - [`ErrorCode::PermissionDenied`]: This one is pretty self-explanatory. |
101 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. | 89 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. |
102 /// | 90 /// |
103 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-acct.html#mwg-pam_sm_acct_mgmt | 91 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-acct.html#mwg-pam_sm_acct_mgmt |
104 fn account_management(handle: &mut T, args: Vec<&CStr>, flags: Flags) -> Result<()> { | 92 fn account_management(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> Result<()> { |
105 Err(ErrorCode::Ignore) | 93 Err(ErrorCode::Ignore) |
106 } | 94 } |
107 | 95 |
108 /// Set credentials on this session. | 96 /// Set credentials on this session. |
109 /// | 97 /// |
135 /// - [`ErrorCode::CredentialsExpired`]: The credentials have expired. | 123 /// - [`ErrorCode::CredentialsExpired`]: The credentials have expired. |
136 /// - [`ErrorCode::CredentialsError`]: Some other error occurred when setting credentials. | 124 /// - [`ErrorCode::CredentialsError`]: Some other error occurred when setting credentials. |
137 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. | 125 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. |
138 /// | 126 /// |
139 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-auth.html#mwg-pam_sm_setcred | 127 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-auth.html#mwg-pam_sm_setcred |
140 fn set_credentials(handle: &mut T, args: Vec<&CStr>, flags: Flags) -> Result<()> { | 128 fn set_credentials( |
129 handle: &mut T, | |
130 args: Vec<&CStr>, | |
131 action: CredAction, | |
132 flags: BaseFlags, | |
133 ) -> Result<()> { | |
141 Err(ErrorCode::Ignore) | 134 Err(ErrorCode::Ignore) |
142 } | 135 } |
143 | 136 |
144 // Function for chauthtok modules. | 137 // Function for chauthtok modules. |
145 | 138 |
152 /// 2. After the preliminary check succeeds, [`Flags::UPDATE_AUTHTOK`] | 145 /// 2. After the preliminary check succeeds, [`Flags::UPDATE_AUTHTOK`] |
153 /// will be set. On this call, actually update the stored auth token. | 146 /// will be set. On this call, actually update the stored auth token. |
154 /// | 147 /// |
155 /// See [the Module Writer's Guide entry for `pam_sm_chauthtok`][mwg] | 148 /// See [the Module Writer's Guide entry for `pam_sm_chauthtok`][mwg] |
156 /// for more information. | 149 /// for more information. |
157 /// | |
158 /// # Valid flags | |
159 /// | |
160 /// This function may be called with the following flags set: | |
161 /// | |
162 /// - [`Flags::SILENT`] | |
163 /// - [`Flags::CHANGE_EXPIRED_AUTHTOK`]: This module should only change | |
164 /// any expired passwords, and leave non-expired passwords alone. | |
165 /// If present, it _must_ be combined with one of the following. | |
166 /// - [`Flags::PRELIMINARY_CHECK`]: Don't actually change the password, | |
167 /// just check if the new one is valid. | |
168 /// - [`Flags::UPDATE_AUTHTOK`]: Do actually change the password. | |
169 /// | 150 /// |
170 /// # Returns | 151 /// # Returns |
171 /// | 152 /// |
172 /// If the authentication token was changed successfully | 153 /// If the authentication token was changed successfully |
173 /// (or the check passed), return `Ok(())`. | 154 /// (or the check passed), return `Ok(())`. |
183 /// - [`ErrorCode::TryAgain`]: When the preliminary check is unsuccessful, | 164 /// - [`ErrorCode::TryAgain`]: When the preliminary check is unsuccessful, |
184 /// ask the user for a new authentication token. | 165 /// ask the user for a new authentication token. |
185 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. | 166 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. |
186 /// | 167 /// |
187 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-chauthtok.html#mwg-pam_sm_chauthtok | 168 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-chauthtok.html#mwg-pam_sm_chauthtok |
188 fn change_authtok(handle: &mut T, args: Vec<&CStr>, flags: Flags) -> Result<()> { | 169 fn change_authtok( |
170 handle: &mut T, | |
171 args: Vec<&CStr>, | |
172 action: AuthtokAction, | |
173 flags: AuthtokFlags, | |
174 ) -> Result<()> { | |
189 Err(ErrorCode::Ignore) | 175 Err(ErrorCode::Ignore) |
190 } | 176 } |
191 | 177 |
192 // Functions for session modules. | 178 // Functions for session modules. |
193 | 179 |
194 /// Called when a session is opened. | 180 /// Called when a session is opened. |
195 /// | 181 /// |
196 /// See [the Module Writer's Guide entry for `pam_sm_open_session`][mwg] | 182 /// See [the Module Writer's Guide entry for `pam_sm_open_session`][mwg] |
197 /// for more information. | 183 /// for more information. |
198 /// | 184 /// |
199 /// # Valid flags | |
200 /// | |
201 /// The only valid flag is [`Flags::SILENT`]. | |
202 /// | |
203 /// # Returns | 185 /// # Returns |
204 /// | 186 /// |
205 /// If the session was opened successfully, return `Ok(())`. | 187 /// If the session was opened successfully, return `Ok(())`. |
206 /// | 188 /// |
207 /// A sensible error code to return is: | 189 /// A sensible error code to return is: |
208 /// | 190 /// |
209 /// - [`ErrorCode::SessionError`]: Cannot make an entry for this session. | 191 /// - [`ErrorCode::SessionError`]: Cannot make an entry for this session. |
210 /// | 192 /// |
211 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-session.html#mwg-pam_sm_open_session | 193 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-session.html#mwg-pam_sm_open_session |
212 fn open_session(handle: &mut T, args: Vec<&CStr>, flags: Flags) -> Result<()> { | 194 fn open_session(handle: &mut T, args: Vec<&CStr>, flags: BaseFlags) -> Result<()> { |
213 Err(ErrorCode::Ignore) | 195 Err(ErrorCode::Ignore) |
214 } | 196 } |
215 | 197 |
216 /// Called when a session is being terminated. | 198 /// Called when a session is being terminated. |
217 /// | 199 /// |
218 /// See [the Module Writer's Guide entry for `pam_sm_close_session`][mwg] | 200 /// See [the Module Writer's Guide entry for `pam_sm_close_session`][mwg] |
219 /// for more information. | 201 /// for more information. |
220 /// | 202 /// |
221 /// # Valid flags | |
222 /// | |
223 /// The only valid flag is [`Flags::SILENT`]. | |
224 /// | |
225 /// # Returns | 203 /// # Returns |
226 /// | 204 /// |
227 /// If the session was closed successfully, return `Ok(())`. | 205 /// If the session was closed successfully, return `Ok(())`. |
228 /// | 206 /// |
229 /// A sensible error code to return is: | 207 /// A sensible error code to return is: |
230 /// | 208 /// |
231 /// - [`ErrorCode::SessionError`]: Cannot remove an entry for this session. | 209 /// - [`ErrorCode::SessionError`]: Cannot remove an entry for this session. |
232 /// | 210 /// |
233 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-session.html#mwg-pam_sm_close_session | 211 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-session.html#mwg-pam_sm_close_session |
234 fn close_session(handle: &mut T, args: Vec<&CStr>, flags: Flags) -> Result<()> { | 212 fn close_session(handle: &mut T, args: Vec<&CStr>, flags: BaseFlags) -> Result<()> { |
235 Err(ErrorCode::Ignore) | 213 Err(ErrorCode::Ignore) |
236 } | 214 } |
237 } | 215 } |