changeset 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 77470e45e397
children e27c5c667a5a
files libpam-sys/libpam-sys-consts/src/constants.rs src/constants.rs
diffstat 2 files changed, 180 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/libpam-sys/libpam-sys-consts/src/constants.rs	Tue Jul 15 01:32:21 2025 -0400
+++ b/libpam-sys/libpam-sys-consts/src/constants.rs	Wed Jul 16 18:45:20 2025 -0400
@@ -70,6 +70,9 @@
     PAM_MAX_RESP_SIZE = 512;
 );
 
+/// A flag for `pam_authenticate`.
+pub const PAM_DISALLOW_NULL_AUTHTOK: i32 = 0x1;
+
 #[cfg(pam_impl = "LinuxPam")]
 pub use linux_pam::*;
 #[cfg(pam_impl = "LinuxPam")]
@@ -113,7 +116,6 @@
     define!(
         /// A flag value.
         PAM_SILENT = 0x8000;
-        PAM_DISALLOW_NULL_AUTHTOK = 0x0001;
         PAM_ESTABLISH_CRED = 0x0002;
         PAM_DELETE_CRED = 0x0004;
         PAM_REINITIALIZE_CRED = 0x0008;
@@ -213,9 +215,6 @@
     /// A general flag for PAM operations.
     pub const PAM_SILENT: i32 = 0x80000000u32 as i32;
 
-    /// A flag for `pam_authenticate`.
-    pub const PAM_DISALLOW_NULL_AUTHTOK: i32 = 0b1;
-
     define!(
         /// A flag for `pam_setcred`.
         PAM_ESTABLISH_CRED = 0b0001;
--- a/src/constants.rs	Tue Jul 15 01:32:21 2025 -0400
+++ b/src/constants.rs	Wed Jul 16 18:45:20 2025 -0400
@@ -2,7 +2,6 @@
 
 use crate::_doc::{linklist, man7, manbsd, xsso};
 use bitflags::bitflags;
-use libpam_sys_consts::constants;
 use num_enum::{IntoPrimitive, TryFromPrimitive};
 use std::error::Error;
 use std::ffi::c_int;
@@ -10,6 +9,133 @@
 use std::fmt::{Display, Formatter};
 use std::result::Result as StdResult;
 
+#[cfg(features = "link")]
+use libpam_sys_consts::constants as pam_constants;
+
+
+/// The union of constants available in all versions of PAM.
+/// The values here are fictitious and should not be used.
+#[cfg(not(features = "link"))]
+mod pam_constants {
+    pub const PAM_SUCCESS: i32 = 0;
+
+    /// Generates a sequence of values.
+    macro_rules! c_enum {
+        ($first:ident = $value:expr, $($rest:ident,)*) => {
+            c_enum!(($value) $first, $($rest,)*);
+        };
+        (($value:expr) $first:ident, $($rest:ident,)*) => {
+            pub const $first: i32 = $value;
+            c_enum!(($value+1) $($rest,)*);
+        };
+        (($value:expr)) => {};
+    }
+
+    // Since all these values are fictitious, we can start them wherever.
+    // All the items.
+    c_enum!(
+        PAM_SERVICE = 64,
+        PAM_USER,
+        PAM_TTY,
+        PAM_RHOST,
+        PAM_CONV,
+        PAM_AUTHTOK,
+        PAM_OLDAUTHTOK,
+        PAM_RUSER,
+        PAM_USER_PROMPT,
+        // Linux-only items.
+        PAM_FAIL_DELAY,
+        PAM_XDISPLAY,
+        PAM_XAUTHDATA,
+        PAM_AUTHTOK_TYPE,
+        // OpenPAM-only items.
+        PAM_REPOSITORY,
+        PAM_AUTHTOK_PROMPT,
+        PAM_OLDAUTHTOK_PROMPT,
+        PAM_HOST,
+        // Sun-only items.
+        PAM_RESOURCE,
+        PAM_AUSER,
+    );
+
+    // Prompt types.
+    c_enum!(
+        PAM_PROMPT_ECHO_OFF = 96,
+        PAM_PROMPT_ECHO_ON,
+        PAM_ERROR_MSG,
+        PAM_TEXT_INFO,
+        PAM_RADIO_TYPE,
+        PAM_BINARY_PROMPT,
+    );
+
+    // Errors.
+    c_enum!(
+        PAM_OPEN_ERR = 128,
+        PAM_SYMBOL_ERR,
+        PAM_SERVICE_ERR,
+        PAM_SYSTEM_ERR,
+        PAM_BUF_ERR,
+        PAM_PERM_DENIED,
+        PAM_AUTH_ERR,
+        PAM_CRED_INSUFFICIENT,
+        PAM_AUTHINFO_UNAVAIL,
+        PAM_USER_UNKNOWN,
+        PAM_MAXTRIES,
+        PAM_NEW_AUTHTOK_REQD,
+        PAM_ACCT_EXPIRED,
+        PAM_SESSION_ERR,
+        PAM_CRED_UNAVAIL,
+        PAM_CRED_EXPIRED,
+        PAM_CRED_ERR,
+        PAM_NO_MODULE_DATA,
+        PAM_CONV_ERR,
+        PAM_AUTHTOK_ERR,
+        PAM_AUTHTOK_RECOVERY_ERR,
+        PAM_AUTHTOK_LOCK_BUSY,
+        PAM_AUTHTOK_DISABLE_AGING,
+        PAM_TRY_AGAIN,
+        PAM_IGNORE,
+        PAM_ABORT,
+        PAM_AUTHTOK_EXPIRED,
+        PAM_MODULE_UNKNOWN,
+        PAM_BAD_ITEM,
+        PAM_CONV_AGAIN,
+        PAM_INCOMPLETE,
+        // OpenPAM-only errors.
+        PAM_DOMAIN_UNKNOWN,
+        PAM_BAD_HANDLE,
+        PAM_BAD_FEATURE,
+        PAM_BAD_CONSTANT,
+    );
+
+    macro_rules! flag_enum {
+        ($first:ident = $value:expr, $($rest:ident,)*) => {
+            flag_enum!(($value) $first, $($rest,)*);
+        };
+        (($value:expr) $first:ident, $($rest:ident,)*) => {
+            pub const $first: i32 = $value;
+            flag_enum!(($value*2) $($rest,)*);
+        };
+        (($value:expr)) => {};
+    }
+
+    flag_enum!(
+        PAM_SILENT = 256,
+        PAM_DISALLOW_NULL_AUTHTOK,
+        PAM_ESTABLISH_CRED,
+        PAM_DELETE_CRED,
+        PAM_REINITIALIZE_CRED,
+        PAM_REFRESH_CRED,
+
+        PAM_CHANGE_EXPIRED_AUTHTOK,
+
+        PAM_PRELIM_CHECK,
+        PAM_UPDATE_AUTHTOK,
+        PAM_DATA_REPLACE,
+        PAM_DATA_SILENT,
+    );
+}
+
 /// Creates a bitflags! macro, with an extra SILENT element.
 macro_rules! pam_flags {
     (
@@ -24,7 +150,7 @@
             #[repr(transparent)]
             pub struct $name: c_int {
                 /// The module should not generate any messages.
-                const SILENT = constants::PAM_SILENT;
+                const SILENT = pam_constants::PAM_SILENT;
                 $($inner)*
             }
         }
@@ -37,7 +163,7 @@
         /// The module should return [AuthError](ErrorCode::AuthError)
         /// if the user has an empty authentication token, rather than
         /// allowing them to log in.
-        const DISALLOW_NULL_AUTHTOK = constants::PAM_DISALLOW_NULL_AUTHTOK;
+        const DISALLOW_NULL_AUTHTOK = pam_constants::PAM_DISALLOW_NULL_AUTHTOK;
     }
 }
 
@@ -47,11 +173,11 @@
         /// Indicates that the user's authentication token should
         /// only be changed if it is expired. If not passed,
         /// the authentication token should be changed unconditionally.
-        const CHANGE_EXPIRED_AUTHTOK = constants::PAM_CHANGE_EXPIRED_AUTHTOK;
+        const CHANGE_EXPIRED_AUTHTOK = pam_constants::PAM_CHANGE_EXPIRED_AUTHTOK;
 
         /// Don't check if the password is any good (Sun only).
         #[cfg(pam_impl = "Sun")]
-        const NO_AUTHTOK_CHECK = constants::PAM_NO_AUTHTOK_CHECK;
+        const NO_AUTHTOK_CHECK = pam_constants::PAM_NO_AUTHTOK_CHECK;
     }
 }
 
@@ -105,13 +231,13 @@
     /// The credential management action that should take place.
     CredAction {
         /// Set the user's credentials from this module. Default if unspecified.
-        Establish = constants::PAM_ESTABLISH_CRED,
+        Establish = pam_constants::PAM_ESTABLISH_CRED,
         /// Revoke the user's credentials established by this module.
-        Delete = constants::PAM_DELETE_CRED,
+        Delete = pam_constants::PAM_DELETE_CRED,
         /// Fully reinitialize the user's credentials from this module.
-        Reinitialize = constants::PAM_REINITIALIZE_CRED,
+        Reinitialize = pam_constants::PAM_REINITIALIZE_CRED,
         /// Extend the lifetime of the user's credentials from this module.
-        Refresh = constants::PAM_REFRESH_CRED,
+        Refresh = pam_constants::PAM_REFRESH_CRED,
     }
 }
 
@@ -133,9 +259,9 @@
     AuthtokAction {
         /// This is a preliminary call to check if we're ready to change passwords
         /// and that the new password is acceptable.
-        PreliminaryCheck = constants::PAM_PRELIM_CHECK,
+        PreliminaryCheck = pam_constants::PAM_PRELIM_CHECK,
         /// You should actually update the password.
-        Update = constants::PAM_UPDATE_AUTHTOK,
+        Update = pam_constants::PAM_UPDATE_AUTHTOK,
     }
 }
 
@@ -168,49 +294,49 @@
 #[non_exhaustive] // C might give us anything!
 #[repr(i32)]
 pub enum ErrorCode {
-    OpenError = constants::PAM_OPEN_ERR,
-    SymbolError = constants::PAM_SYMBOL_ERR,
-    ServiceError = constants::PAM_SERVICE_ERR,
-    SystemError = constants::PAM_SYSTEM_ERR,
-    BufferError = constants::PAM_BUF_ERR,
-    PermissionDenied = constants::PAM_PERM_DENIED,
-    AuthenticationError = constants::PAM_AUTH_ERR,
-    CredentialsInsufficient = constants::PAM_CRED_INSUFFICIENT,
-    AuthInfoUnavailable = constants::PAM_AUTHINFO_UNAVAIL,
-    UserUnknown = constants::PAM_USER_UNKNOWN,
-    MaxTries = constants::PAM_MAXTRIES,
-    NewAuthTokRequired = constants::PAM_NEW_AUTHTOK_REQD,
-    AccountExpired = constants::PAM_ACCT_EXPIRED,
-    SessionError = constants::PAM_SESSION_ERR,
-    CredentialsUnavailable = constants::PAM_CRED_UNAVAIL,
-    CredentialsExpired = constants::PAM_CRED_EXPIRED,
-    CredentialsError = constants::PAM_CRED_ERR,
-    NoModuleData = constants::PAM_NO_MODULE_DATA,
-    ConversationError = constants::PAM_CONV_ERR,
-    AuthTokError = constants::PAM_AUTHTOK_ERR,
-    AuthTokRecoveryError = constants::PAM_AUTHTOK_RECOVERY_ERR,
-    AuthTokLockBusy = constants::PAM_AUTHTOK_LOCK_BUSY,
-    AuthTokDisableAging = constants::PAM_AUTHTOK_DISABLE_AGING,
-    TryAgain = constants::PAM_TRY_AGAIN,
-    Ignore = constants::PAM_IGNORE,
-    Abort = constants::PAM_ABORT,
-    AuthTokExpired = constants::PAM_AUTHTOK_EXPIRED,
+    OpenError = pam_constants::PAM_OPEN_ERR,
+    SymbolError = pam_constants::PAM_SYMBOL_ERR,
+    ServiceError = pam_constants::PAM_SERVICE_ERR,
+    SystemError = pam_constants::PAM_SYSTEM_ERR,
+    BufferError = pam_constants::PAM_BUF_ERR,
+    PermissionDenied = pam_constants::PAM_PERM_DENIED,
+    AuthenticationError = pam_constants::PAM_AUTH_ERR,
+    CredentialsInsufficient = pam_constants::PAM_CRED_INSUFFICIENT,
+    AuthInfoUnavailable = pam_constants::PAM_AUTHINFO_UNAVAIL,
+    UserUnknown = pam_constants::PAM_USER_UNKNOWN,
+    MaxTries = pam_constants::PAM_MAXTRIES,
+    NewAuthTokRequired = pam_constants::PAM_NEW_AUTHTOK_REQD,
+    AccountExpired = pam_constants::PAM_ACCT_EXPIRED,
+    SessionError = pam_constants::PAM_SESSION_ERR,
+    CredentialsUnavailable = pam_constants::PAM_CRED_UNAVAIL,
+    CredentialsExpired = pam_constants::PAM_CRED_EXPIRED,
+    CredentialsError = pam_constants::PAM_CRED_ERR,
+    NoModuleData = pam_constants::PAM_NO_MODULE_DATA,
+    ConversationError = pam_constants::PAM_CONV_ERR,
+    AuthTokError = pam_constants::PAM_AUTHTOK_ERR,
+    AuthTokRecoveryError = pam_constants::PAM_AUTHTOK_RECOVERY_ERR,
+    AuthTokLockBusy = pam_constants::PAM_AUTHTOK_LOCK_BUSY,
+    AuthTokDisableAging = pam_constants::PAM_AUTHTOK_DISABLE_AGING,
+    TryAgain = pam_constants::PAM_TRY_AGAIN,
+    Ignore = pam_constants::PAM_IGNORE,
+    Abort = pam_constants::PAM_ABORT,
+    AuthTokExpired = pam_constants::PAM_AUTHTOK_EXPIRED,
     #[cfg(feature = "basic-ext")]
-    ModuleUnknown = constants::PAM_MODULE_UNKNOWN,
+    ModuleUnknown = pam_constants::PAM_MODULE_UNKNOWN,
     #[cfg(feature = "basic-ext")]
-    BadItem = constants::PAM_BAD_ITEM,
+    BadItem = pam_constants::PAM_BAD_ITEM,
     #[cfg(feature = "linux-pam-ext")]
-    ConversationAgain = constants::PAM_CONV_AGAIN,
+    ConversationAgain = pam_constants::PAM_CONV_AGAIN,
     #[cfg(feature = "linux-pam-ext")]
-    Incomplete = constants::PAM_INCOMPLETE,
+    Incomplete = pam_constants::PAM_INCOMPLETE,
     #[cfg(feature = "openpam-ext")]
-    DomainUnknown = constants::PAM_DOMAIN_UNKNOWN,
+    DomainUnknown = pam_constants::PAM_DOMAIN_UNKNOWN,
     #[cfg(feature = "openpam-ext")]
-    BadHandle = constants::PAM_BAD_HANDLE,
+    BadHandle = pam_constants::PAM_BAD_HANDLE,
     #[cfg(feature = "openpam-ext")]
-    BadFeature = constants::PAM_BAD_FEATURE,
+    BadFeature = pam_constants::PAM_BAD_FEATURE,
     #[cfg(feature = "openpam-ext")]
-    BadConstant = constants::PAM_BAD_CONSTANT,
+    BadConstant = pam_constants::PAM_BAD_CONSTANT,
 }
 
 /// A PAM-specific Result type with an [ErrorCode] error.
@@ -280,12 +406,12 @@
     fn test_enums() {
         assert_eq!(Ok(()), ErrorCode::result_from(0));
         assert_eq!(
-            constants::PAM_SESSION_ERR,
+            pam_constants::PAM_SESSION_ERR,
             ErrorCode::result_to_c::<()>(Err(ErrorCode::SessionError))
         );
         assert_eq!(
             Err(ErrorCode::Abort),
-            ErrorCode::result_from(constants::PAM_ABORT)
+            ErrorCode::result_from(pam_constants::PAM_ABORT)
         );
         assert_eq!(Err(ErrorCode::SystemError), ErrorCode::result_from(423));
     }
@@ -297,9 +423,9 @@
         assert_eq!(
             Ok((
                 AuthtokAction::Update,
-                AuthtokFlags::from_bits_retain(0x7fff0000)
+                AuthtokFlags::from_bits_retain(0x7f000000)
             )),
-            AuthtokAction::extract(0x7fff0000 | constants::PAM_UPDATE_AUTHTOK)
+            AuthtokAction::extract(0x7f000000 | pam_constants::PAM_UPDATE_AUTHTOK)
         );
         CredAction::extract(0xffff).expect_err("too many set");
         assert_eq!(
@@ -308,7 +434,7 @@
         );
         assert_eq!(
             Ok((CredAction::Delete, BaseFlags::from_bits_retain(0x55000000))),
-            CredAction::extract(0x55000000 | constants::PAM_DELETE_CRED)
+            CredAction::extract(0x55000000 | pam_constants::PAM_DELETE_CRED)
         );
     }
 }