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 }