Mercurial > crates > nonstick
diff libpam-sys/libpam-sys-consts/build.rs @ 160:09dff285ff5e
Switch default PAM detection strategy to target-based.
To make cross-compilation easier (like for docs.rs), this change
makes OS-based detection of PAM the default, only falling back
to probing the actual installed PAM as a last resort.
I haven't been able to find a Linux distribution that uses
anything but Linux-PAM.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sun, 13 Jul 2025 15:38:00 -0400 |
parents | d5b7b28d754e |
children | 46e8ce5cd5d1 |
line wrap: on
line diff
--- a/libpam-sys/libpam-sys-consts/build.rs Sat Jul 12 18:16:18 2025 -0400 +++ b/libpam-sys/libpam-sys-consts/build.rs Sun Jul 13 15:38:00 2025 -0400 @@ -8,40 +8,34 @@ /// The strategy to use to detect PAM. enum Detect { - /// Automatically detect PAM, using the installed implementation if present - /// or the OS default if not. - Auto, - /// Use the default PAM implementation based on the OS. + /// Use the default PAM implementation based on the OS, + /// or the currently-installed version if the OS is not recognized. TargetDefault, + /// Detect the installed implementation. + Installed, /// Use the named version of PAM. Specified(PamImpl), } -const TARGET_DEFAULT: &str = "__TARGET_DEFAULT__"; +const INSTALLED: &str = "__installed__"; fn main() { let detection = match option_env!("LIBPAMSYS_IMPL") { - None | Some("") => match option_env!("DOCS_RS") { - // docs.rs cross-compiles, so we don't want to look at - // its currently-installed PAM; instead we want to use the OS. - Some(_) => Detect::TargetDefault, - // In other cases, just auto-detect the actual installed library. - None => Detect::Auto, - }, - Some(TARGET_DEFAULT) => Detect::TargetDefault, + Some("") | None => Detect::TargetDefault, + Some(INSTALLED) => Detect::Installed, Some(val) => Detect::Specified(PamImpl::try_from(val).unwrap_or_else(|_| { panic!( "unknown PAM implementation {val:?}. \ valid LIBPAMSYS_IMPLs are {:?}, \ - {TARGET_DEFAULT:?} to use the OS default, \ + {INSTALLED:?} to use the OS default, \ or unset to detect", PamImpl::items() ) })), }; let pam_impl = match detection { - Detect::Auto => LibPam::probe_detect(), - Detect::TargetDefault => LibPam::os_default(), + Detect::TargetDefault => LibPam::target_default(), + Detect::Installed => LibPam::probe_detect(), Detect::Specified(other) => other, }; let impl_str = format!("{pam_impl:?}"); @@ -73,23 +67,8 @@ struct LibPam(NonNull<c_void>); impl LibPam { - /// Look at the currently-installed LibPAM, or use [`Self::os_default`] - /// if absent. - fn probe_detect() -> PamImpl { - if let Some(lib) = Self::open() { - if lib.has("pam_syslog") { - return PamImpl::LinuxPam; - } else if lib.has("_openpam_log") { - return PamImpl::OpenPam; - } else if lib.has("__pam_get_authtok") { - return PamImpl::Sun; - } - } - Self::os_default() - } - /// Guess the PAM implementation based on the current OS. - fn os_default() -> PamImpl { + fn target_default() -> PamImpl { if cfg!(target_os = "linux") { PamImpl::LinuxPam } else if cfg!(any( @@ -103,10 +82,25 @@ } else if cfg!(any(target_os = "illumos", target_os = "solaris")) { PamImpl::Sun } else { - PamImpl::XSso + Self::probe_detect() } } + /// Look at the currently-installed LibPAM. + fn probe_detect() -> PamImpl { + if let Some(lib) = Self::open() { + if lib.has("pam_syslog") { + return PamImpl::LinuxPam; + } else if lib.has("_openpam_log") { + return PamImpl::OpenPam; + } else if lib.has("__pam_get_authtok") { + return PamImpl::Sun; + } + } + // idk + PamImpl::XSso + } + fn open() -> Option<Self> { let dlopen = |s: &[u8]| unsafe { libc::dlopen(s.as_ptr().cast(), libc::RTLD_LAZY) }; NonNull::new(dlopen(b"libpam.so\0"))