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"))