diff libpam-sys/libpam-sys-impls/build.rs @ 118:39760dfc9b3b

Detect PAM library based only on system lib; rename minimal lib to XSso. Also formats and assorted other cleanup.
author Paul Fisher <paul@pfish.zone>
date Sun, 29 Jun 2025 20:13:03 -0400
parents a12706e42c9d
children
line wrap: on
line diff
--- a/libpam-sys/libpam-sys-impls/build.rs	Sun Jun 29 18:48:14 2025 -0400
+++ b/libpam-sys/libpam-sys-impls/build.rs	Sun Jun 29 20:13:03 2025 -0400
@@ -6,12 +6,14 @@
 //!  2. It detects the current PAM implementation and sets an env var for
 //!     the macros in `libpam-sys-impl`.
 
+use dlopen::raw::Library;
 use proc_macro2::TokenStream;
 use quote::quote;
+use std::ffi::c_void;
 use std::{env, fs};
-use std::ffi::c_void;
-use strum::EnumString;
-use dlopen::raw::Library;
+use strum::{EnumIter, EnumString, IntoEnumIterator};
+
+const DETECT: &str = "__detect__";
 
 fn main() {
     let pam_impl = match option_env!("LIBPAMSYS_IMPL") {
@@ -30,27 +32,31 @@
             } else if cfg!(any(target_os = "illumos", target_os = "solaris",)) {
                 PamImpl::Sun
             } else {
-                PamImpl::MinimalOpenPam
+                PamImpl::XSso
             }
         }
-        Some("_detect") => {
-            // Detect what library we're using based on the symbols.
+        Some(DETECT) => {
+            // Detect the library based on the symbols in libpam.so.
             let lib = Library::open("libpam.so").unwrap();
             if symbol_exists(&lib, "pam_syslog") {
                 PamImpl::LinuxPam
             } else if symbol_exists(&lib, "_openpam_log") {
                 PamImpl::OpenPam
-            } else if header_exists("security/pam_appl.h") {
-                // We figure we're *probably* on a Sun derivative.
+            } else if symbol_exists(&lib, "__pam_get_authtok") {
                 PamImpl::Sun
             } else {
                 // If all else fails, assume the bare minimum.
-                PamImpl::MinimalOpenPam
+                PamImpl::XSso
             }
         }
         Some(other) => match PamImpl::try_from(other) {
             Ok(i) => i,
-            Err(_) => panic!("unknown PAM implementation {other:?}"),
+            Err(_) => {
+                let valid: Vec<_> = PamImpl::iter().collect();
+                panic!(
+                    "unknown PAM implementation {other:?}. valid LIBPAMSYS_IMPLs are {valid:?}, or use {DETECT:?}"
+                )
+            }
         },
     };
     fs::write(
@@ -95,7 +101,7 @@
 }
 
 self_aware_enum!(
-    #here[derive(EnumString, strum::Display)]
+    #here[derive(EnumString, strum::Display, EnumIter)]
     /// The PAM implementations supported by `libpam-sys`.
     #[derive(Clone, Copy, Debug, PartialEq)]
     PamImpl {
@@ -111,17 +117,9 @@
         ///
         /// [sun]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam
         Sun,
-        /// Only the functionality in [the PAM spec], with OpenPAM/Sun consts.
+        /// Only the functionality and constants in [the PAM spec].
         ///
         /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm
-        MinimalOpenPam,
+        XSso,
     }
 );
-
-fn header_exists(header: &str) -> bool {
-    bindgen::Builder::default()
-        .blocklist_item(".*")
-        .header_contents("header.h", &format!("#include <{header}>"))
-        .generate()
-        .is_ok()
-}