comparison 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
comparison
equal deleted inserted replaced
117:20f7712a6857 118:39760dfc9b3b
4 //! output to the `OUT_DIR/pam_impl_enum.rs` file for parsing/inclusion 4 //! output to the `OUT_DIR/pam_impl_enum.rs` file for parsing/inclusion
5 //! into the `__pam_impl_enum__` macro. 5 //! into the `__pam_impl_enum__` macro.
6 //! 2. It detects the current PAM implementation and sets an env var for 6 //! 2. It detects the current PAM implementation and sets an env var for
7 //! the macros in `libpam-sys-impl`. 7 //! the macros in `libpam-sys-impl`.
8 8
9 use dlopen::raw::Library;
9 use proc_macro2::TokenStream; 10 use proc_macro2::TokenStream;
10 use quote::quote; 11 use quote::quote;
12 use std::ffi::c_void;
11 use std::{env, fs}; 13 use std::{env, fs};
12 use std::ffi::c_void; 14 use strum::{EnumIter, EnumString, IntoEnumIterator};
13 use strum::EnumString; 15
14 use dlopen::raw::Library; 16 const DETECT: &str = "__detect__";
15 17
16 fn main() { 18 fn main() {
17 let pam_impl = match option_env!("LIBPAMSYS_IMPL") { 19 let pam_impl = match option_env!("LIBPAMSYS_IMPL") {
18 // The default option: Guess what PAM impl we're using based on OS. 20 // The default option: Guess what PAM impl we're using based on OS.
19 None => { 21 None => {
28 )) { 30 )) {
29 PamImpl::OpenPam 31 PamImpl::OpenPam
30 } else if cfg!(any(target_os = "illumos", target_os = "solaris",)) { 32 } else if cfg!(any(target_os = "illumos", target_os = "solaris",)) {
31 PamImpl::Sun 33 PamImpl::Sun
32 } else { 34 } else {
33 PamImpl::MinimalOpenPam 35 PamImpl::XSso
34 } 36 }
35 } 37 }
36 Some("_detect") => { 38 Some(DETECT) => {
37 // Detect what library we're using based on the symbols. 39 // Detect the library based on the symbols in libpam.so.
38 let lib = Library::open("libpam.so").unwrap(); 40 let lib = Library::open("libpam.so").unwrap();
39 if symbol_exists(&lib, "pam_syslog") { 41 if symbol_exists(&lib, "pam_syslog") {
40 PamImpl::LinuxPam 42 PamImpl::LinuxPam
41 } else if symbol_exists(&lib, "_openpam_log") { 43 } else if symbol_exists(&lib, "_openpam_log") {
42 PamImpl::OpenPam 44 PamImpl::OpenPam
43 } else if header_exists("security/pam_appl.h") { 45 } else if symbol_exists(&lib, "__pam_get_authtok") {
44 // We figure we're *probably* on a Sun derivative.
45 PamImpl::Sun 46 PamImpl::Sun
46 } else { 47 } else {
47 // If all else fails, assume the bare minimum. 48 // If all else fails, assume the bare minimum.
48 PamImpl::MinimalOpenPam 49 PamImpl::XSso
49 } 50 }
50 } 51 }
51 Some(other) => match PamImpl::try_from(other) { 52 Some(other) => match PamImpl::try_from(other) {
52 Ok(i) => i, 53 Ok(i) => i,
53 Err(_) => panic!("unknown PAM implementation {other:?}"), 54 Err(_) => {
55 let valid: Vec<_> = PamImpl::iter().collect();
56 panic!(
57 "unknown PAM implementation {other:?}. valid LIBPAMSYS_IMPLs are {valid:?}, or use {DETECT:?}"
58 )
59 }
54 }, 60 },
55 }; 61 };
56 fs::write( 62 fs::write(
57 format!("{}/pam_impl_enum.rs", env::var("OUT_DIR").unwrap()), 63 format!("{}/pam_impl_enum.rs", env::var("OUT_DIR").unwrap()),
58 PamImpl::enum_tokens().to_string(), 64 PamImpl::enum_tokens().to_string(),
93 } 99 }
94 } 100 }
95 } 101 }
96 102
97 self_aware_enum!( 103 self_aware_enum!(
98 #here[derive(EnumString, strum::Display)] 104 #here[derive(EnumString, strum::Display, EnumIter)]
99 /// The PAM implementations supported by `libpam-sys`. 105 /// The PAM implementations supported by `libpam-sys`.
100 #[derive(Clone, Copy, Debug, PartialEq)] 106 #[derive(Clone, Copy, Debug, PartialEq)]
101 PamImpl { 107 PamImpl {
102 /// [Linux-PAM] is provided by most Linux distributions. 108 /// [Linux-PAM] is provided by most Linux distributions.
103 /// 109 ///
109 OpenPam, 115 OpenPam,
110 /// Illumos and Solaris use a derivative of [Sun's implementation][sun]. 116 /// Illumos and Solaris use a derivative of [Sun's implementation][sun].
111 /// 117 ///
112 /// [sun]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam 118 /// [sun]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam
113 Sun, 119 Sun,
114 /// Only the functionality in [the PAM spec], with OpenPAM/Sun consts. 120 /// Only the functionality and constants in [the PAM spec].
115 /// 121 ///
116 /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm 122 /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm
117 MinimalOpenPam, 123 XSso,
118 } 124 }
119 ); 125 );
120
121 fn header_exists(header: &str) -> bool {
122 bindgen::Builder::default()
123 .blocklist_item(".*")
124 .header_contents("header.h", &format!("#include <{header}>"))
125 .generate()
126 .is_ok()
127 }