Mercurial > crates > nonstick
comparison src/constants.rs @ 170:f052e2417195
Completely avoid using libpam_sys if we're not actually linking.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Wed, 16 Jul 2025 18:45:20 -0400 |
| parents | 2f5913131295 |
| children | e27c5c667a5a |
comparison
equal
deleted
inserted
replaced
| 169:77470e45e397 | 170:f052e2417195 |
|---|---|
| 1 //! Constants and enum values from the PAM library. | 1 //! Constants and enum values from the PAM library. |
| 2 | 2 |
| 3 use crate::_doc::{linklist, man7, manbsd, xsso}; | 3 use crate::_doc::{linklist, man7, manbsd, xsso}; |
| 4 use bitflags::bitflags; | 4 use bitflags::bitflags; |
| 5 use libpam_sys_consts::constants; | |
| 6 use num_enum::{IntoPrimitive, TryFromPrimitive}; | 5 use num_enum::{IntoPrimitive, TryFromPrimitive}; |
| 7 use std::error::Error; | 6 use std::error::Error; |
| 8 use std::ffi::c_int; | 7 use std::ffi::c_int; |
| 9 use std::fmt; | 8 use std::fmt; |
| 10 use std::fmt::{Display, Formatter}; | 9 use std::fmt::{Display, Formatter}; |
| 11 use std::result::Result as StdResult; | 10 use std::result::Result as StdResult; |
| 11 | |
| 12 #[cfg(features = "link")] | |
| 13 use libpam_sys_consts::constants as pam_constants; | |
| 14 | |
| 15 | |
| 16 /// The union of constants available in all versions of PAM. | |
| 17 /// The values here are fictitious and should not be used. | |
| 18 #[cfg(not(features = "link"))] | |
| 19 mod pam_constants { | |
| 20 pub const PAM_SUCCESS: i32 = 0; | |
| 21 | |
| 22 /// Generates a sequence of values. | |
| 23 macro_rules! c_enum { | |
| 24 ($first:ident = $value:expr, $($rest:ident,)*) => { | |
| 25 c_enum!(($value) $first, $($rest,)*); | |
| 26 }; | |
| 27 (($value:expr) $first:ident, $($rest:ident,)*) => { | |
| 28 pub const $first: i32 = $value; | |
| 29 c_enum!(($value+1) $($rest,)*); | |
| 30 }; | |
| 31 (($value:expr)) => {}; | |
| 32 } | |
| 33 | |
| 34 // Since all these values are fictitious, we can start them wherever. | |
| 35 // All the items. | |
| 36 c_enum!( | |
| 37 PAM_SERVICE = 64, | |
| 38 PAM_USER, | |
| 39 PAM_TTY, | |
| 40 PAM_RHOST, | |
| 41 PAM_CONV, | |
| 42 PAM_AUTHTOK, | |
| 43 PAM_OLDAUTHTOK, | |
| 44 PAM_RUSER, | |
| 45 PAM_USER_PROMPT, | |
| 46 // Linux-only items. | |
| 47 PAM_FAIL_DELAY, | |
| 48 PAM_XDISPLAY, | |
| 49 PAM_XAUTHDATA, | |
| 50 PAM_AUTHTOK_TYPE, | |
| 51 // OpenPAM-only items. | |
| 52 PAM_REPOSITORY, | |
| 53 PAM_AUTHTOK_PROMPT, | |
| 54 PAM_OLDAUTHTOK_PROMPT, | |
| 55 PAM_HOST, | |
| 56 // Sun-only items. | |
| 57 PAM_RESOURCE, | |
| 58 PAM_AUSER, | |
| 59 ); | |
| 60 | |
| 61 // Prompt types. | |
| 62 c_enum!( | |
| 63 PAM_PROMPT_ECHO_OFF = 96, | |
| 64 PAM_PROMPT_ECHO_ON, | |
| 65 PAM_ERROR_MSG, | |
| 66 PAM_TEXT_INFO, | |
| 67 PAM_RADIO_TYPE, | |
| 68 PAM_BINARY_PROMPT, | |
| 69 ); | |
| 70 | |
| 71 // Errors. | |
| 72 c_enum!( | |
| 73 PAM_OPEN_ERR = 128, | |
| 74 PAM_SYMBOL_ERR, | |
| 75 PAM_SERVICE_ERR, | |
| 76 PAM_SYSTEM_ERR, | |
| 77 PAM_BUF_ERR, | |
| 78 PAM_PERM_DENIED, | |
| 79 PAM_AUTH_ERR, | |
| 80 PAM_CRED_INSUFFICIENT, | |
| 81 PAM_AUTHINFO_UNAVAIL, | |
| 82 PAM_USER_UNKNOWN, | |
| 83 PAM_MAXTRIES, | |
| 84 PAM_NEW_AUTHTOK_REQD, | |
| 85 PAM_ACCT_EXPIRED, | |
| 86 PAM_SESSION_ERR, | |
| 87 PAM_CRED_UNAVAIL, | |
| 88 PAM_CRED_EXPIRED, | |
| 89 PAM_CRED_ERR, | |
| 90 PAM_NO_MODULE_DATA, | |
| 91 PAM_CONV_ERR, | |
| 92 PAM_AUTHTOK_ERR, | |
| 93 PAM_AUTHTOK_RECOVERY_ERR, | |
| 94 PAM_AUTHTOK_LOCK_BUSY, | |
| 95 PAM_AUTHTOK_DISABLE_AGING, | |
| 96 PAM_TRY_AGAIN, | |
| 97 PAM_IGNORE, | |
| 98 PAM_ABORT, | |
| 99 PAM_AUTHTOK_EXPIRED, | |
| 100 PAM_MODULE_UNKNOWN, | |
| 101 PAM_BAD_ITEM, | |
| 102 PAM_CONV_AGAIN, | |
| 103 PAM_INCOMPLETE, | |
| 104 // OpenPAM-only errors. | |
| 105 PAM_DOMAIN_UNKNOWN, | |
| 106 PAM_BAD_HANDLE, | |
| 107 PAM_BAD_FEATURE, | |
| 108 PAM_BAD_CONSTANT, | |
| 109 ); | |
| 110 | |
| 111 macro_rules! flag_enum { | |
| 112 ($first:ident = $value:expr, $($rest:ident,)*) => { | |
| 113 flag_enum!(($value) $first, $($rest,)*); | |
| 114 }; | |
| 115 (($value:expr) $first:ident, $($rest:ident,)*) => { | |
| 116 pub const $first: i32 = $value; | |
| 117 flag_enum!(($value*2) $($rest,)*); | |
| 118 }; | |
| 119 (($value:expr)) => {}; | |
| 120 } | |
| 121 | |
| 122 flag_enum!( | |
| 123 PAM_SILENT = 256, | |
| 124 PAM_DISALLOW_NULL_AUTHTOK, | |
| 125 PAM_ESTABLISH_CRED, | |
| 126 PAM_DELETE_CRED, | |
| 127 PAM_REINITIALIZE_CRED, | |
| 128 PAM_REFRESH_CRED, | |
| 129 | |
| 130 PAM_CHANGE_EXPIRED_AUTHTOK, | |
| 131 | |
| 132 PAM_PRELIM_CHECK, | |
| 133 PAM_UPDATE_AUTHTOK, | |
| 134 PAM_DATA_REPLACE, | |
| 135 PAM_DATA_SILENT, | |
| 136 ); | |
| 137 } | |
| 12 | 138 |
| 13 /// Creates a bitflags! macro, with an extra SILENT element. | 139 /// Creates a bitflags! macro, with an extra SILENT element. |
| 14 macro_rules! pam_flags { | 140 macro_rules! pam_flags { |
| 15 ( | 141 ( |
| 16 $(#[$m:meta])* | 142 $(#[$m:meta])* |
| 22 $(#[$m])* | 148 $(#[$m])* |
| 23 #[derive(Clone, Copy, Debug, Default, PartialEq)] | 149 #[derive(Clone, Copy, Debug, Default, PartialEq)] |
| 24 #[repr(transparent)] | 150 #[repr(transparent)] |
| 25 pub struct $name: c_int { | 151 pub struct $name: c_int { |
| 26 /// The module should not generate any messages. | 152 /// The module should not generate any messages. |
| 27 const SILENT = constants::PAM_SILENT; | 153 const SILENT = pam_constants::PAM_SILENT; |
| 28 $($inner)* | 154 $($inner)* |
| 29 } | 155 } |
| 30 } | 156 } |
| 31 } | 157 } |
| 32 } | 158 } |
| 35 /// Flags for authentication and account management. | 161 /// Flags for authentication and account management. |
| 36 AuthnFlags { | 162 AuthnFlags { |
| 37 /// The module should return [AuthError](ErrorCode::AuthError) | 163 /// The module should return [AuthError](ErrorCode::AuthError) |
| 38 /// if the user has an empty authentication token, rather than | 164 /// if the user has an empty authentication token, rather than |
| 39 /// allowing them to log in. | 165 /// allowing them to log in. |
| 40 const DISALLOW_NULL_AUTHTOK = constants::PAM_DISALLOW_NULL_AUTHTOK; | 166 const DISALLOW_NULL_AUTHTOK = pam_constants::PAM_DISALLOW_NULL_AUTHTOK; |
| 41 } | 167 } |
| 42 } | 168 } |
| 43 | 169 |
| 44 pam_flags! { | 170 pam_flags! { |
| 45 /// Flags for changing the authentication token. | 171 /// Flags for changing the authentication token. |
| 46 AuthtokFlags { | 172 AuthtokFlags { |
| 47 /// Indicates that the user's authentication token should | 173 /// Indicates that the user's authentication token should |
| 48 /// only be changed if it is expired. If not passed, | 174 /// only be changed if it is expired. If not passed, |
| 49 /// the authentication token should be changed unconditionally. | 175 /// the authentication token should be changed unconditionally. |
| 50 const CHANGE_EXPIRED_AUTHTOK = constants::PAM_CHANGE_EXPIRED_AUTHTOK; | 176 const CHANGE_EXPIRED_AUTHTOK = pam_constants::PAM_CHANGE_EXPIRED_AUTHTOK; |
| 51 | 177 |
| 52 /// Don't check if the password is any good (Sun only). | 178 /// Don't check if the password is any good (Sun only). |
| 53 #[cfg(pam_impl = "Sun")] | 179 #[cfg(pam_impl = "Sun")] |
| 54 const NO_AUTHTOK_CHECK = constants::PAM_NO_AUTHTOK_CHECK; | 180 const NO_AUTHTOK_CHECK = pam_constants::PAM_NO_AUTHTOK_CHECK; |
| 55 } | 181 } |
| 56 } | 182 } |
| 57 | 183 |
| 58 pam_flags! { | 184 pam_flags! { |
| 59 /// Common flag(s) shared by all PAM actions. | 185 /// Common flag(s) shared by all PAM actions. |
| 103 | 229 |
| 104 flag_enum! { | 230 flag_enum! { |
| 105 /// The credential management action that should take place. | 231 /// The credential management action that should take place. |
| 106 CredAction { | 232 CredAction { |
| 107 /// Set the user's credentials from this module. Default if unspecified. | 233 /// Set the user's credentials from this module. Default if unspecified. |
| 108 Establish = constants::PAM_ESTABLISH_CRED, | 234 Establish = pam_constants::PAM_ESTABLISH_CRED, |
| 109 /// Revoke the user's credentials established by this module. | 235 /// Revoke the user's credentials established by this module. |
| 110 Delete = constants::PAM_DELETE_CRED, | 236 Delete = pam_constants::PAM_DELETE_CRED, |
| 111 /// Fully reinitialize the user's credentials from this module. | 237 /// Fully reinitialize the user's credentials from this module. |
| 112 Reinitialize = constants::PAM_REINITIALIZE_CRED, | 238 Reinitialize = pam_constants::PAM_REINITIALIZE_CRED, |
| 113 /// Extend the lifetime of the user's credentials from this module. | 239 /// Extend the lifetime of the user's credentials from this module. |
| 114 Refresh = constants::PAM_REFRESH_CRED, | 240 Refresh = pam_constants::PAM_REFRESH_CRED, |
| 115 } | 241 } |
| 116 } | 242 } |
| 117 | 243 |
| 118 impl CredAction { | 244 impl CredAction { |
| 119 /// Separates this enum from the remaining [`BaseFlags`]. | 245 /// Separates this enum from the remaining [`BaseFlags`]. |
| 131 | 257 |
| 132 flag_enum! { | 258 flag_enum! { |
| 133 AuthtokAction { | 259 AuthtokAction { |
| 134 /// This is a preliminary call to check if we're ready to change passwords | 260 /// This is a preliminary call to check if we're ready to change passwords |
| 135 /// and that the new password is acceptable. | 261 /// and that the new password is acceptable. |
| 136 PreliminaryCheck = constants::PAM_PRELIM_CHECK, | 262 PreliminaryCheck = pam_constants::PAM_PRELIM_CHECK, |
| 137 /// You should actually update the password. | 263 /// You should actually update the password. |
| 138 Update = constants::PAM_UPDATE_AUTHTOK, | 264 Update = pam_constants::PAM_UPDATE_AUTHTOK, |
| 139 } | 265 } |
| 140 } | 266 } |
| 141 | 267 |
| 142 impl AuthtokAction { | 268 impl AuthtokAction { |
| 143 /// Separates this enum from the remaining [`AuthtokFlags`]. | 269 /// Separates this enum from the remaining [`AuthtokFlags`]. |
| 166 #[allow(non_camel_case_types, dead_code)] | 292 #[allow(non_camel_case_types, dead_code)] |
| 167 #[derive(Copy, Clone, Debug, PartialEq, TryFromPrimitive, IntoPrimitive)] | 293 #[derive(Copy, Clone, Debug, PartialEq, TryFromPrimitive, IntoPrimitive)] |
| 168 #[non_exhaustive] // C might give us anything! | 294 #[non_exhaustive] // C might give us anything! |
| 169 #[repr(i32)] | 295 #[repr(i32)] |
| 170 pub enum ErrorCode { | 296 pub enum ErrorCode { |
| 171 OpenError = constants::PAM_OPEN_ERR, | 297 OpenError = pam_constants::PAM_OPEN_ERR, |
| 172 SymbolError = constants::PAM_SYMBOL_ERR, | 298 SymbolError = pam_constants::PAM_SYMBOL_ERR, |
| 173 ServiceError = constants::PAM_SERVICE_ERR, | 299 ServiceError = pam_constants::PAM_SERVICE_ERR, |
| 174 SystemError = constants::PAM_SYSTEM_ERR, | 300 SystemError = pam_constants::PAM_SYSTEM_ERR, |
| 175 BufferError = constants::PAM_BUF_ERR, | 301 BufferError = pam_constants::PAM_BUF_ERR, |
| 176 PermissionDenied = constants::PAM_PERM_DENIED, | 302 PermissionDenied = pam_constants::PAM_PERM_DENIED, |
| 177 AuthenticationError = constants::PAM_AUTH_ERR, | 303 AuthenticationError = pam_constants::PAM_AUTH_ERR, |
| 178 CredentialsInsufficient = constants::PAM_CRED_INSUFFICIENT, | 304 CredentialsInsufficient = pam_constants::PAM_CRED_INSUFFICIENT, |
| 179 AuthInfoUnavailable = constants::PAM_AUTHINFO_UNAVAIL, | 305 AuthInfoUnavailable = pam_constants::PAM_AUTHINFO_UNAVAIL, |
| 180 UserUnknown = constants::PAM_USER_UNKNOWN, | 306 UserUnknown = pam_constants::PAM_USER_UNKNOWN, |
| 181 MaxTries = constants::PAM_MAXTRIES, | 307 MaxTries = pam_constants::PAM_MAXTRIES, |
| 182 NewAuthTokRequired = constants::PAM_NEW_AUTHTOK_REQD, | 308 NewAuthTokRequired = pam_constants::PAM_NEW_AUTHTOK_REQD, |
| 183 AccountExpired = constants::PAM_ACCT_EXPIRED, | 309 AccountExpired = pam_constants::PAM_ACCT_EXPIRED, |
| 184 SessionError = constants::PAM_SESSION_ERR, | 310 SessionError = pam_constants::PAM_SESSION_ERR, |
| 185 CredentialsUnavailable = constants::PAM_CRED_UNAVAIL, | 311 CredentialsUnavailable = pam_constants::PAM_CRED_UNAVAIL, |
| 186 CredentialsExpired = constants::PAM_CRED_EXPIRED, | 312 CredentialsExpired = pam_constants::PAM_CRED_EXPIRED, |
| 187 CredentialsError = constants::PAM_CRED_ERR, | 313 CredentialsError = pam_constants::PAM_CRED_ERR, |
| 188 NoModuleData = constants::PAM_NO_MODULE_DATA, | 314 NoModuleData = pam_constants::PAM_NO_MODULE_DATA, |
| 189 ConversationError = constants::PAM_CONV_ERR, | 315 ConversationError = pam_constants::PAM_CONV_ERR, |
| 190 AuthTokError = constants::PAM_AUTHTOK_ERR, | 316 AuthTokError = pam_constants::PAM_AUTHTOK_ERR, |
| 191 AuthTokRecoveryError = constants::PAM_AUTHTOK_RECOVERY_ERR, | 317 AuthTokRecoveryError = pam_constants::PAM_AUTHTOK_RECOVERY_ERR, |
| 192 AuthTokLockBusy = constants::PAM_AUTHTOK_LOCK_BUSY, | 318 AuthTokLockBusy = pam_constants::PAM_AUTHTOK_LOCK_BUSY, |
| 193 AuthTokDisableAging = constants::PAM_AUTHTOK_DISABLE_AGING, | 319 AuthTokDisableAging = pam_constants::PAM_AUTHTOK_DISABLE_AGING, |
| 194 TryAgain = constants::PAM_TRY_AGAIN, | 320 TryAgain = pam_constants::PAM_TRY_AGAIN, |
| 195 Ignore = constants::PAM_IGNORE, | 321 Ignore = pam_constants::PAM_IGNORE, |
| 196 Abort = constants::PAM_ABORT, | 322 Abort = pam_constants::PAM_ABORT, |
| 197 AuthTokExpired = constants::PAM_AUTHTOK_EXPIRED, | 323 AuthTokExpired = pam_constants::PAM_AUTHTOK_EXPIRED, |
| 198 #[cfg(feature = "basic-ext")] | 324 #[cfg(feature = "basic-ext")] |
| 199 ModuleUnknown = constants::PAM_MODULE_UNKNOWN, | 325 ModuleUnknown = pam_constants::PAM_MODULE_UNKNOWN, |
| 200 #[cfg(feature = "basic-ext")] | 326 #[cfg(feature = "basic-ext")] |
| 201 BadItem = constants::PAM_BAD_ITEM, | 327 BadItem = pam_constants::PAM_BAD_ITEM, |
| 202 #[cfg(feature = "linux-pam-ext")] | 328 #[cfg(feature = "linux-pam-ext")] |
| 203 ConversationAgain = constants::PAM_CONV_AGAIN, | 329 ConversationAgain = pam_constants::PAM_CONV_AGAIN, |
| 204 #[cfg(feature = "linux-pam-ext")] | 330 #[cfg(feature = "linux-pam-ext")] |
| 205 Incomplete = constants::PAM_INCOMPLETE, | 331 Incomplete = pam_constants::PAM_INCOMPLETE, |
| 206 #[cfg(feature = "openpam-ext")] | 332 #[cfg(feature = "openpam-ext")] |
| 207 DomainUnknown = constants::PAM_DOMAIN_UNKNOWN, | 333 DomainUnknown = pam_constants::PAM_DOMAIN_UNKNOWN, |
| 208 #[cfg(feature = "openpam-ext")] | 334 #[cfg(feature = "openpam-ext")] |
| 209 BadHandle = constants::PAM_BAD_HANDLE, | 335 BadHandle = pam_constants::PAM_BAD_HANDLE, |
| 210 #[cfg(feature = "openpam-ext")] | 336 #[cfg(feature = "openpam-ext")] |
| 211 BadFeature = constants::PAM_BAD_FEATURE, | 337 BadFeature = pam_constants::PAM_BAD_FEATURE, |
| 212 #[cfg(feature = "openpam-ext")] | 338 #[cfg(feature = "openpam-ext")] |
| 213 BadConstant = constants::PAM_BAD_CONSTANT, | 339 BadConstant = pam_constants::PAM_BAD_CONSTANT, |
| 214 } | 340 } |
| 215 | 341 |
| 216 /// A PAM-specific Result type with an [ErrorCode] error. | 342 /// A PAM-specific Result type with an [ErrorCode] error. |
| 217 pub type Result<T> = StdResult<T, ErrorCode>; | 343 pub type Result<T> = StdResult<T, ErrorCode>; |
| 218 | 344 |
| 278 | 404 |
| 279 #[test] | 405 #[test] |
| 280 fn test_enums() { | 406 fn test_enums() { |
| 281 assert_eq!(Ok(()), ErrorCode::result_from(0)); | 407 assert_eq!(Ok(()), ErrorCode::result_from(0)); |
| 282 assert_eq!( | 408 assert_eq!( |
| 283 constants::PAM_SESSION_ERR, | 409 pam_constants::PAM_SESSION_ERR, |
| 284 ErrorCode::result_to_c::<()>(Err(ErrorCode::SessionError)) | 410 ErrorCode::result_to_c::<()>(Err(ErrorCode::SessionError)) |
| 285 ); | 411 ); |
| 286 assert_eq!( | 412 assert_eq!( |
| 287 Err(ErrorCode::Abort), | 413 Err(ErrorCode::Abort), |
| 288 ErrorCode::result_from(constants::PAM_ABORT) | 414 ErrorCode::result_from(pam_constants::PAM_ABORT) |
| 289 ); | 415 ); |
| 290 assert_eq!(Err(ErrorCode::SystemError), ErrorCode::result_from(423)); | 416 assert_eq!(Err(ErrorCode::SystemError), ErrorCode::result_from(423)); |
| 291 } | 417 } |
| 292 | 418 |
| 293 #[test] | 419 #[test] |
| 295 AuthtokAction::extract(-1).expect_err("too many set"); | 421 AuthtokAction::extract(-1).expect_err("too many set"); |
| 296 AuthtokAction::extract(0).expect_err("too few set"); | 422 AuthtokAction::extract(0).expect_err("too few set"); |
| 297 assert_eq!( | 423 assert_eq!( |
| 298 Ok(( | 424 Ok(( |
| 299 AuthtokAction::Update, | 425 AuthtokAction::Update, |
| 300 AuthtokFlags::from_bits_retain(0x7fff0000) | 426 AuthtokFlags::from_bits_retain(0x7f000000) |
| 301 )), | 427 )), |
| 302 AuthtokAction::extract(0x7fff0000 | constants::PAM_UPDATE_AUTHTOK) | 428 AuthtokAction::extract(0x7f000000 | pam_constants::PAM_UPDATE_AUTHTOK) |
| 303 ); | 429 ); |
| 304 CredAction::extract(0xffff).expect_err("too many set"); | 430 CredAction::extract(0xffff).expect_err("too many set"); |
| 305 assert_eq!( | 431 assert_eq!( |
| 306 Ok((CredAction::Establish, BaseFlags::empty())), | 432 Ok((CredAction::Establish, BaseFlags::empty())), |
| 307 CredAction::extract(0) | 433 CredAction::extract(0) |
| 308 ); | 434 ); |
| 309 assert_eq!( | 435 assert_eq!( |
| 310 Ok((CredAction::Delete, BaseFlags::from_bits_retain(0x55000000))), | 436 Ok((CredAction::Delete, BaseFlags::from_bits_retain(0x55000000))), |
| 311 CredAction::extract(0x55000000 | constants::PAM_DELETE_CRED) | 437 CredAction::extract(0x55000000 | pam_constants::PAM_DELETE_CRED) |
| 312 ); | 438 ); |
| 313 } | 439 } |
| 314 } | 440 } |
