view build.rs @ 87:05291b601f0a

Well and truly separate the Linux extensions. This separates the Linux extensions on the libpam side, and disables the two enums on the interface side. Users can still call the Linux extensions from non-Linux PAM impls, but they'll get a conversation error back.
author Paul Fisher <paul@pfish.zone>
date Tue, 10 Jun 2025 04:40:01 -0400
parents a638a45e5f1f
children
line wrap: on
line source

use bindgen::MacroTypeVariation;
use std::env;
use std::path::PathBuf;

fn main() {
    if cfg!(feature = "link") {
        println!("cargo::rustc-check-cfg=cfg(pam_impl, values(\"linux-pam\",\"openpam\"))");
        let common_builder = bindgen::Builder::default()
            .merge_extern_blocks(true)
            .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
            .blocklist_type("pam_handle")
            .blocklist_type("pam_conv")
            .allowlist_var(".*")
            .allowlist_function("pam_start")
            .allowlist_function("pam_[gs]et_item")
            .allowlist_function("pam_get_user")
            .allowlist_function("pam_get_authtok")
            .allowlist_function("pam_end")
            .dynamic_link_require_all(true)
            .default_macro_constant_type(MacroTypeVariation::Unsigned);

        let linux_builder = common_builder
            .clone()
            // This function is not available in OpenPAM.
            // We don't use it, but we include it so that if the user
            // tries to run this against the wrong PAM library, it fails.
            .allowlist_function("pam_start_confdir")
            .header_contents(
                "linux-pam.h",
                r#"
                #include <security/_pam_types.h>
                #include <security/pam_appl.h>
                #include <security/pam_ext.h>
                #include <security/pam_modules.h>
                "#,
            );
        let openpam_builder = common_builder
            .clone()
            // This function is not available in Linux-PAM.
            // We don't use it, but we include it so that if the user
            // tries to run this against the wrong PAM library, it fails.
            .allowlist_function("pam_setenv")
            .header_contents(
                "openpam.h",
                r#"
                #include <security/pam_types.h>
                #include <security/openpam.h>
                #include <security/pam_appl.h>
                #include <security/pam_constants.h>
                "#,
            );

        let (pam_impl, bindings) = {
            if let Ok(bindings) = linux_builder.generate() {
                ("linux-pam", bindings)
            } else if let Ok(bindings) = openpam_builder.generate() {
                ("openpam", bindings)
            } else {
                panic!("unrecognized PAM implementation")
            }
        };
        println!("cargo::rustc-cfg=pam_impl={pam_impl:?}");
        let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
        bindings
            .write_to_file(out_path.join("bindings.rs"))
            .unwrap();
    }
}