diff libpam-sys/libpam-sys-impls/build.rs @ 116:a12706e42c9d default tip

Logging, macros, and building: - Changes logging API to accept the `Location` of the log statement. Fixes OpenPAM implementation. - Stops publicly exporting doc macros. - Uses dlopen to detect the PAM library rather than header jankery.
author Paul Fisher <paul@pfish.zone>
date Sun, 29 Jun 2025 18:27:51 -0400
parents 178310336596
children
line wrap: on
line diff
--- a/libpam-sys/libpam-sys-impls/build.rs	Sun Jun 29 03:35:59 2025 -0400
+++ b/libpam-sys/libpam-sys-impls/build.rs	Sun Jun 29 18:27:51 2025 -0400
@@ -9,7 +9,9 @@
 use proc_macro2::TokenStream;
 use quote::quote;
 use std::{env, fs};
+use std::ffi::c_void;
 use strum::EnumString;
+use dlopen::raw::Library;
 
 fn main() {
     let pam_impl = match option_env!("LIBPAMSYS_IMPL") {
@@ -32,10 +34,11 @@
             }
         }
         Some("_detect") => {
-            // Detect which impl it is from system headers.
-            if header_exists("security/_pam_types.h") {
+            // Detect what library we're using based on the symbols.
+            let lib = Library::open("libpam.so").unwrap();
+            if symbol_exists(&lib, "pam_syslog") {
                 PamImpl::LinuxPam
-            } else if header_exists("security/openpam.h") {
+            } 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.
@@ -58,6 +61,10 @@
     println!("cargo:rustc-env=LIBPAMSYS_IMPL={pam_impl:?}");
 }
 
+fn symbol_exists(lib: &Library, symbol: &str) -> bool {
+    unsafe { lib.symbol::<*mut c_void>(symbol) }.is_ok()
+}
+
 /// This defines a local enum with an `enum_tokens()` method that can spit out
 /// its own contents.
 macro_rules! self_aware_enum {