view build.rs @ 95:51c9d7e8261a

Return owned strings rather than borrowed strings. It's going to be irritating to have to work with strings borrowed from the PAM handle rather than just using your own. They're cheap enough to copy.
author Paul Fisher <paul@pfish.zone>
date Mon, 23 Jun 2025 14:03:44 -0400
parents 5ddbcada30f2
children efe2f5f8b5b2
line wrap: on
line source

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

fn main() {
    if cfg!(feature = "link") {
        println!("cargo::rustc-link-lib=pam");
        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")
            .allowlist_function("pam_strerror")
            .default_macro_constant_type(MacroTypeVariation::Unsigned);

        let linux_builder = common_builder
            .clone()
            // This function is not available in OpenPAM.
            // That means if somebody tries to run a binary compiled for
            // Linux-PAM against a different impl, it will fail.
            .allowlist_function("pam_syslog")
            .header_contents(
                "linux-pam.h",
                r#"
                #include <syslog.h> // for log levels
                #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.
            // That means if somebody tries to run a binary compiled for
            // OpenPAM against a different impl, it will fail.
            .allowlist_function("openpam_log")
            .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();
    }
}