Mercurial > crates > nonstick
comparison src/module.rs @ 193:5074d8e00560
Doc improvements.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sat, 02 Aug 2025 19:49:21 -0400 |
parents | 46e8ce5cd5d1 |
children |
comparison
equal
deleted
inserted
replaced
192:4c39eaa4a5ae | 193:5074d8e00560 |
---|---|
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::_doc::{guide, linklist, stdlinks}; | |
6 use crate::constants::{ | 7 use crate::constants::{ |
7 AuthnFlags, AuthtokAction, AuthtokFlags, BaseFlags, CredAction, ErrorCode, Result, | 8 AuthnFlags, AuthtokAction, AuthtokFlags, BaseFlags, CredAction, ErrorCode, Result, |
8 }; | 9 }; |
9 use crate::handle::ModuleClient; | 10 use crate::handle::ModuleClient; |
10 use std::ffi::CStr; | 11 use std::ffi::CStr; |
12 | |
13 macro_rules! sm_refs { | |
14 ($sym:ident: $guide:literal) => { | |
15 concat!( | |
16 linklist!($sym: mwg, _std), | |
17 "\n\n", | |
18 guide!(mwg: $guide), | |
19 "\n", | |
20 stdlinks!(3 $sym), | |
21 ) | |
22 } | |
23 } | |
11 | 24 |
12 /// A trait for a PAM module to implement. | 25 /// A trait for a PAM module to implement. |
13 /// | 26 /// |
14 /// The default implementations of all these hooks tell PAM to ignore them | 27 /// The default implementations of all these hooks tell PAM to ignore them |
15 /// (i.e., behave as if this module does not exist) by returning [`ErrorCode::Ignore`]. | 28 /// (i.e., behave as if this module does not exist) by returning [`ErrorCode::Ignore`]. |
16 /// Override any functions you wish to handle in your module. | 29 /// Override any functions you wish to handle in your module. |
17 /// After implementing this trait, use the [`pam_export!`](crate::pam_export!) macro | 30 /// After implementing this trait, use the [`pam_export!`](crate::pam_export!) macro |
18 /// to make the functions available to PAM. | 31 /// to make the functions available to PAM. |
19 /// | 32 /// |
20 /// For more information, see [`pam(3)`’s root manual page][manpage] | 33 /// For more information about how to write a module, see "[What is expected |
21 /// and the [PAM Module Writer’s Guide][mwg]. | 34 /// of a module?][what]" in the Module Writers' Guide. |
22 /// | 35 #[doc = ""] |
23 /// [manpage]: https://www.man7.org/linux/man-pages/man3/pam.3.html | 36 #[doc = guide!(what: "mwg-expected-of-module-overview.html")] |
24 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/Linux-PAM_MWG.html | |
25 #[allow(unused_variables)] | 37 #[allow(unused_variables)] |
26 pub trait PamModule<T: ModuleClient> { | 38 pub trait PamModule<T: ModuleClient> { |
27 // Functions for auth modules. | 39 // Functions for auth modules. |
28 | 40 |
29 /// Authenticate the user. | 41 /// Authenticate the user. |
31 /// This is probably the first thing you want to implement. | 43 /// This is probably the first thing you want to implement. |
32 /// In most cases, you will want to get the user and password, | 44 /// In most cases, you will want to get the user and password, |
33 /// using [`PamShared::username`](crate::PamShared::username) | 45 /// using [`PamShared::username`](crate::PamShared::username) |
34 /// and [`ModuleClient::authtok`], | 46 /// and [`ModuleClient::authtok`], |
35 /// and verify them against something. | 47 /// and verify them against something. |
36 /// | |
37 /// See [the Module Writer's Guide entry for `pam_sm_authenticate`][mwg] | |
38 /// for more information. | |
39 /// | 48 /// |
40 /// # Returns | 49 /// # Returns |
41 /// | 50 /// |
42 /// If the password check was successful, return `Ok(())`. | 51 /// If the password check was successful, return `Ok(())`. |
43 /// | 52 /// |
51 /// the authentication information, for instance due to a network failure. | 60 /// the authentication information, for instance due to a network failure. |
52 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. | 61 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. |
53 /// - [`ErrorCode::MaxTries`]: The user has tried authenticating too many times. | 62 /// - [`ErrorCode::MaxTries`]: The user has tried authenticating too many times. |
54 /// They should not try again. | 63 /// They should not try again. |
55 /// | 64 /// |
56 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-auth.html#mwg-pam_sm_authenticate | 65 /// # References |
66 #[doc = sm_refs!(pam_sm_authenticate: "mwg-expected-of-module-auth.html#mwg-pam_sm_authenticate")] | |
57 fn authenticate(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> Result<()> { | 67 fn authenticate(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> Result<()> { |
58 Err(ErrorCode::Ignore) | 68 Err(ErrorCode::Ignore) |
59 } | 69 } |
60 | 70 |
61 /// Perform "account management". | 71 /// Perform "account management". |
68 /// - Remote host (only let employees log in from the office) | 78 /// - Remote host (only let employees log in from the office) |
69 /// | 79 /// |
70 /// You can also check things like, e.g., password expiration, | 80 /// You can also check things like, e.g., password expiration, |
71 /// and alert that the user change it before continuing, | 81 /// and alert that the user change it before continuing, |
72 /// or really do whatever you want. | 82 /// or really do whatever you want. |
73 /// | |
74 /// See [the Module Writer's Guide entry for `pam_sm_acct_mgmt`][mwg] | |
75 /// for more information. | |
76 /// | 83 /// |
77 /// # Returns | 84 /// # Returns |
78 /// | 85 /// |
79 /// If the user should be allowed to log in, return `Ok(())`. | 86 /// If the user should be allowed to log in, return `Ok(())`. |
80 /// | 87 /// |
86 /// PAM will ask the user to set a new authentication token, which may be handled by | 93 /// PAM will ask the user to set a new authentication token, which may be handled by |
87 /// this module in [`Self::change_authtok`]. | 94 /// this module in [`Self::change_authtok`]. |
88 /// - [`ErrorCode::PermissionDenied`]: This one is pretty self-explanatory. | 95 /// - [`ErrorCode::PermissionDenied`]: This one is pretty self-explanatory. |
89 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. | 96 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. |
90 /// | 97 /// |
91 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-acct.html#mwg-pam_sm_acct_mgmt | 98 /// # References |
99 #[doc = sm_refs!(pam_sm_acct_mgmt: "mwg-expected-of-module-acct.html#mwg-pam_sm_acct_mgmt")] | |
92 fn account_management(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> Result<()> { | 100 fn account_management(handle: &mut T, args: Vec<&CStr>, flags: AuthnFlags) -> Result<()> { |
93 Err(ErrorCode::Ignore) | 101 Err(ErrorCode::Ignore) |
94 } | 102 } |
95 | 103 |
96 /// Set credentials on this session. | 104 /// Set credentials on this session. |
100 /// that information to the application. It should only be called after | 108 /// that information to the application. It should only be called after |
101 /// authentication but before a session is established. | 109 /// authentication but before a session is established. |
102 /// | 110 /// |
103 /// The module should perform the specified `action`. | 111 /// The module should perform the specified `action`. |
104 /// | 112 /// |
105 /// See [the Module Writer's Guide entry for `pam_sm_setcred`][mwg] | |
106 /// for more information. | |
107 /// | |
108 /// # Returns | 113 /// # Returns |
109 /// | 114 /// |
110 /// If credentials were set successfully, return `Ok(())`. | 115 /// If credentials were set successfully, return `Ok(())`. |
111 /// | 116 /// |
112 /// Sensible error codes to return include: | 117 /// Sensible error codes to return include: |
114 /// - [`ErrorCode::CredentialsUnavailable`]: The credentials cannot be retrieved. | 119 /// - [`ErrorCode::CredentialsUnavailable`]: The credentials cannot be retrieved. |
115 /// - [`ErrorCode::CredentialsExpired`]: The credentials have expired. | 120 /// - [`ErrorCode::CredentialsExpired`]: The credentials have expired. |
116 /// - [`ErrorCode::CredentialsError`]: Some other error occurred when setting credentials. | 121 /// - [`ErrorCode::CredentialsError`]: Some other error occurred when setting credentials. |
117 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. | 122 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. |
118 /// | 123 /// |
119 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-auth.html#mwg-pam_sm_setcred | 124 /// # References |
125 #[doc = sm_refs!(pam_sm_setcred: "mwg-expected-of-module-auth.html#mwg-pam_sm_setcred")] | |
120 fn set_credentials( | 126 fn set_credentials( |
121 handle: &mut T, | 127 handle: &mut T, |
122 args: Vec<&CStr>, | 128 args: Vec<&CStr>, |
123 action: CredAction, | 129 action: CredAction, |
124 flags: BaseFlags, | 130 flags: BaseFlags, |
142 /// The new authentication token will be available in | 148 /// The new authentication token will be available in |
143 /// [`authtok`](ModuleClient::authtok), | 149 /// [`authtok`](ModuleClient::authtok), |
144 /// and the previous authentication token will be available in | 150 /// and the previous authentication token will be available in |
145 /// [`old_authtok`](ModuleClient::old_authtok). | 151 /// [`old_authtok`](ModuleClient::old_authtok). |
146 /// | 152 /// |
147 /// See [the Module Writer's Guide entry for `pam_sm_chauthtok`][mwg] | |
148 /// for more information. | |
149 /// | |
150 /// # Returns | 153 /// # Returns |
151 /// | 154 /// |
152 /// If the authentication token was changed successfully | 155 /// If the authentication token was changed successfully |
153 /// (or the check passed), return `Ok(())`. | 156 /// (or the check passed), return `Ok(())`. |
154 /// | 157 /// |
162 /// - [`ErrorCode::PermissionDenied`]: What it says on the tin. | 165 /// - [`ErrorCode::PermissionDenied`]: What it says on the tin. |
163 /// - [`ErrorCode::TryAgain`]: When the preliminary check is unsuccessful, | 166 /// - [`ErrorCode::TryAgain`]: When the preliminary check is unsuccessful, |
164 /// ask the user for a new authentication token. | 167 /// ask the user for a new authentication token. |
165 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. | 168 /// - [`ErrorCode::UserUnknown`]: The supplied username is not known by this service. |
166 /// | 169 /// |
167 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-chauthtok.html#mwg-pam_sm_chauthtok | 170 /// # References |
171 #[doc = sm_refs!(pam_sm_chauthtok: "mwg-expected-of-module-acct.html#mwg-pam_sm_chauthtok")] | |
168 fn change_authtok( | 172 fn change_authtok( |
169 handle: &mut T, | 173 handle: &mut T, |
170 args: Vec<&CStr>, | 174 args: Vec<&CStr>, |
171 action: AuthtokAction, | 175 action: AuthtokAction, |
172 flags: AuthtokFlags, | 176 flags: AuthtokFlags, |
176 | 180 |
177 // Functions for session modules. | 181 // Functions for session modules. |
178 | 182 |
179 /// Called when a session is opened. | 183 /// Called when a session is opened. |
180 /// | 184 /// |
181 /// See [the Module Writer's Guide entry for `pam_sm_open_session`][mwg] | |
182 /// for more information. | |
183 /// | |
184 /// # Returns | 185 /// # Returns |
185 /// | 186 /// |
186 /// If the session was opened successfully, return `Ok(())`. | 187 /// If the session was opened successfully, return `Ok(())`. |
187 /// | 188 /// |
188 /// A sensible error code to return is: | 189 /// A sensible error code to return is: |
189 /// | 190 /// |
190 /// - [`ErrorCode::SessionError`]: Cannot make an entry for this session. | 191 /// - [`ErrorCode::SessionError`]: Cannot make an entry for this session. |
191 /// | 192 /// |
192 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-session.html#mwg-pam_sm_open_session | 193 /// # References |
194 #[doc = sm_refs!(pam_sm_open_session: "mwg-expected-of-module-session.html#mwg-pam_sm_open_session")] | |
193 fn open_session(handle: &mut T, args: Vec<&CStr>, flags: BaseFlags) -> Result<()> { | 195 fn open_session(handle: &mut T, args: Vec<&CStr>, flags: BaseFlags) -> Result<()> { |
194 Err(ErrorCode::Ignore) | 196 Err(ErrorCode::Ignore) |
195 } | 197 } |
196 | 198 |
197 /// Called when a session is being terminated. | 199 /// Called when a session is being terminated. |
198 /// | 200 /// |
199 /// See [the Module Writer's Guide entry for `pam_sm_close_session`][mwg] | |
200 /// for more information. | |
201 /// | |
202 /// # Returns | 201 /// # Returns |
203 /// | 202 /// |
204 /// If the session was closed successfully, return `Ok(())`. | 203 /// If the session was closed successfully, return `Ok(())`. |
205 /// | 204 /// |
206 /// A sensible error code to return is: | 205 /// A sensible error code to return is: |
207 /// | 206 /// |
208 /// - [`ErrorCode::SessionError`]: Cannot remove an entry for this session. | 207 /// - [`ErrorCode::SessionError`]: Cannot remove an entry for this session. |
209 /// | 208 /// |
210 /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-of-module-session.html#mwg-pam_sm_close_session | 209 /// # References |
210 #[doc = sm_refs!(pam_sm_close_session: "mwg-expected-of-module-session.html#mwg-pam_sm_close_session")] | |
211 fn close_session(handle: &mut T, args: Vec<&CStr>, flags: BaseFlags) -> Result<()> { | 211 fn close_session(handle: &mut T, args: Vec<&CStr>, flags: BaseFlags) -> Result<()> { |
212 Err(ErrorCode::Ignore) | 212 Err(ErrorCode::Ignore) |
213 } | 213 } |
214 } | 214 } |