Mercurial > crates > nonstick
view src/constants.rs @ 58:868a278a362c
Added tag v0.0.4 for changeset 2a5c83d04b93
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Mon, 05 May 2025 00:16:04 -0400 |
parents | daa2cde64601 |
children | 3f4a77aa88be |
line wrap: on
line source
use bitflags::bitflags; use libc::{c_int, c_uint}; use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive}; // TODO: Import constants from C header file at compile time. // The Linux-PAM flags // see /usr/include/security/_pam_types.h bitflags! { #[derive(Debug, PartialEq)] #[repr(transparent)] pub struct Flags: c_uint { const SILENT = 0x8000; const DISALLOW_NULL_AUTHTOK = 0x0001; const ESTABLISH_CRED = 0x0002; const DELETE_CRED = 0x0004; const REINITIALIZE_CRED = 0x0008; const REFRESH_CRED = 0x0010; const CHANGE_EXPIRED_AUTHTOK= 0x0020; } } /// Styles of message that are shown to the user. #[derive(Debug, PartialEq, FromPrimitive, ToPrimitive)] #[non_exhaustive] // non-exhaustive because C might give us back anything! pub enum MessageStyle { /// Requests information from the user; will be masked when typing. PromptEchoOff = 1, /// Requests information from the user; will not be masked. PromptEchoOn = 2, /// An error message. ErrorMsg = 3, /// An informational message. TextInfo = 4, /// Yes/No/Maybe conditionals. Linux-PAM specific. RadioType = 5, /// For server–client non-human interaction. /// NOT part of the X/Open PAM specification. BinaryPrompt = 7, } impl From<MessageStyle> for c_int { fn from(val: MessageStyle) -> Self { val.to_i32().unwrap_or(0) } } /// The Linux-PAM error return values. /// Success is instead represented by the `Ok` entry of a `Result`. /// Most abbreviations (except `AuthTok` and `Max`) are now full words. /// For more detailed information, see /// `/usr/include/security/_pam_types.h`. #[allow(non_camel_case_types, dead_code)] #[derive(Copy, Clone, Debug, PartialEq, thiserror::Error, FromPrimitive, ToPrimitive)] #[non_exhaustive] // C might give us anything! pub enum ErrorCode { #[error("dlopen() failure when dynamically loading a service module")] OpenError = 1, #[error("symbol not found")] SymbolError = 2, #[error("error in service module")] ServiceError = 3, #[error("system error")] SystemError = 4, #[error("memory buffer error")] BufferError = 5, #[error("permission denied")] PermissionDenied = 6, #[error("authentication failure")] AuthenticationError = 7, #[error("cannot access authentication data due to insufficient credentials")] CredentialsInsufficient = 8, #[error("underlying authentication service cannot retrieve authentication information")] AuthInfoUnavailable = 9, #[error("user not known to the underlying authentication module")] UserUnknown = 10, #[error("retry limit reached; do not attempt further")] MaxTries = 11, #[error("new authentication token required")] NewAuthTokRequired = 12, #[error("user account has expired")] AccountExpired = 13, #[error("cannot make/remove an entry for the specified session")] SessionError = 14, #[error("underlying authentication service cannot retrieve user credentials")] CredentialsUnavailable = 15, #[error("user credentials expired")] CredentialsExpired = 16, #[error("failure setting user credentials")] CredentialsError = 17, #[error("no module-specific data is present")] NoModuleData = 18, #[error("conversation error")] ConversationError = 19, #[error("authentication token manipulation error")] AuthTokError = 20, #[error("authentication information cannot be recovered")] AuthTokRecoveryError = 21, #[error("authentication token lock busy")] AuthTokLockBusy = 22, #[error("authentication token aging disabled")] AuthTokDisableAging = 23, #[error("preliminary check by password service")] TryAgain = 24, #[error("ignore underlying account module, regardless of control flag")] Ignore = 25, #[error("critical error; this module should fail now")] Abort = 26, #[error("authentication token has expired")] AuthTokExpired = 27, #[error("module is not known")] ModuleUnknown = 28, #[error("bad item passed to pam_[whatever]_item")] BadItem = 29, #[error("conversation function is event-driven and data is not available yet")] ConversationAgain = 30, #[error("call this function again to complete authentication stack")] Incomplete = 31, } pub type PamResult<T> = Result<T, ErrorCode>; impl ErrorCode { /// Converts a PamResult into the result code that C wants. pub fn result_to_c(value: PamResult<()>) -> c_int { match value { Ok(_) => 0, // PAM_SUCCESS Err(otherwise) => otherwise.into(), } } /// Converts a C result code into a PamResult, with success as Ok. pub fn result_from(value: c_int) -> PamResult<()> { match value { 0 => Ok(()), value => Err(Self::from_i64(value as i64).unwrap_or(Self::ConversationError)) } } } impl From<ErrorCode> for c_int { fn from(val: ErrorCode) -> Self { val.to_i32().unwrap_or(0) } }