Mercurial > crates > nonstick
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 } |