From 50c5d42fbd343eaab9255d761f7b4638797cad9e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:08:21 +0200 Subject: [PATCH 1/2] Commit PAM bindings for FreeBSD This is a prerequisite of compiling sudo-rs for FreeBSD, but not in itself enough to compile sudo-rs for FreeBSD. This also intentionally excluses a minor change to the PAM code that is necessary for FreeBSD as someone will need to carefully verify that PAM on FreeBSD behaves similar enough to PAM on Linux or if not adapt the PAM code in sudo-rs. --- Makefile | 16 ++-- src/pam/mod.rs | 2 + src/pam/sys_freebsd.rs | 126 +++++++++++++++++++++++++++++++ src/pam/{sys.rs => sys_linux.rs} | 2 - src/pam/wrapper.h | 6 -- 5 files changed, 135 insertions(+), 17 deletions(-) create mode 100644 src/pam/sys_freebsd.rs rename src/pam/{sys.rs => sys_linux.rs} (98%) diff --git a/Makefile b/Makefile index 9169485a0..d8ea570eb 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,19 @@ PAM_SRC_DIR = src/pam -BINDGEN_CMD = bindgen --allowlist-function '^pam_.*$$' --allowlist-var '^PAM_.*$$' --opaque-type pam_handle_t --blocklist-function pam_vsyslog --blocklist-function pam_vprompt --blocklist-type '.*va_list.*' --ctypes-prefix libc --no-layout-tests --sort-semantically +BINDGEN_CMD = bindgen --allowlist-function '^pam_.*$$' --allowlist-var '^PAM_.*$$' --opaque-type pam_handle_t --blocklist-function pam_vsyslog --blocklist-function pam_vprompt --blocklist-function pam_vinfo --blocklist-function pam_verror --blocklist-type '.*va_list.*' --ctypes-prefix libc --no-layout-tests --sort-semantically .PHONY: all clean pam-sys pam-sys-diff -pam-sys-diff: $(PAM_SRC_DIR)/wrapper.h +pam-sys-diff: @$(BINDGEN_CMD) $< | diff --color=auto $(PAM_SRC_DIR)/sys.rs - || (echo run \'make -B pam-sys\' to apply these changes && false) @echo $(PAM_SRC_DIR)/sys.rs does not need to be re-generated -# use 'make pam-sys' to re-generate the sys.rs file -pam-sys: $(PAM_SRC_DIR)/sys.rs - -$(PAM_SRC_DIR)/sys.rs: $(PAM_SRC_DIR)/wrapper.h - $(BINDGEN_CMD) $< --output $@ +# use 'make pam-sys' to re-generate the sys.rs file for your local platform +pam-sys: + $(BINDGEN_CMD) $(PAM_SRC_DIR)/wrapper.h --output $(PAM_SRC_DIR)/sys_$$(uname | tr 'A-Z' 'a-z').rs cargo minify --apply --allow-dirty - sed -i.bak 's/rust-bindgen \w*\.\w*\.\w*/\0, minified by cargo-minify/' $@ - rm $@.bak + sed -i.bak 's/rust-bindgen [0-9]*\.[0-9]*\.[0-9]*/&, minified by cargo-minify/' $(PAM_SRC_DIR)/sys_$$(uname | tr 'A-Z' 'a-z').rs + rm $(PAM_SRC_DIR)/sys_$$(uname | tr 'A-Z' 'a-z').rs.bak clean: rm $(PAM_SRC_DIR)/sys.rs diff --git a/src/pam/mod.rs b/src/pam/mod.rs index 99d573f3f..a5a835db4 100644 --- a/src/pam/mod.rs +++ b/src/pam/mod.rs @@ -16,6 +16,8 @@ mod error; mod rpassword; mod securemem; +#[cfg_attr(target_os = "linux", path = "sys_linux.rs")] +#[cfg_attr(target_os = "freebsd", path = "sys_freebsd.rs")] #[allow(nonstandard_style)] pub mod sys; diff --git a/src/pam/sys_freebsd.rs b/src/pam/sys_freebsd.rs new file mode 100644 index 000000000..f05d093e4 --- /dev/null +++ b/src/pam/sys_freebsd.rs @@ -0,0 +1,126 @@ +/* automatically generated by rust-bindgen 0.70.1, minified by cargo-minify */ + +pub type pam_handle_t = u8; +pub type _bindgen_ty_1 = libc::c_uint; +pub type _bindgen_ty_2 = libc::c_uint; +pub type _bindgen_ty_3 = libc::c_int; +pub type _bindgen_ty_4 = libc::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pam_message { + pub msg_style: libc::c_int, + pub msg: *mut libc::c_char, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pam_response { + pub resp: *mut libc::c_char, + pub resp_retcode: libc::c_int, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pam_conv { + pub conv: ::std::option::Option< + unsafe extern "C" fn( + arg1: libc::c_int, + arg2: *mut *const pam_message, + arg3: *mut *mut pam_response, + arg4: *mut libc::c_void, + ) -> libc::c_int, + >, + pub appdata_ptr: *mut libc::c_void, +} +pub const PAM_SUCCESS: _bindgen_ty_1 = 0; +pub const PAM_OPEN_ERR: _bindgen_ty_1 = 1; +pub const PAM_SYMBOL_ERR: _bindgen_ty_1 = 2; +pub const PAM_SERVICE_ERR: _bindgen_ty_1 = 3; +pub const PAM_SYSTEM_ERR: _bindgen_ty_1 = 4; +pub const PAM_BUF_ERR: _bindgen_ty_1 = 5; +pub const PAM_CONV_ERR: _bindgen_ty_1 = 6; +pub const PAM_PERM_DENIED: _bindgen_ty_1 = 7; +pub const PAM_MAXTRIES: _bindgen_ty_1 = 8; +pub const PAM_AUTH_ERR: _bindgen_ty_1 = 9; +pub const PAM_NEW_AUTHTOK_REQD: _bindgen_ty_1 = 10; +pub const PAM_CRED_INSUFFICIENT: _bindgen_ty_1 = 11; +pub const PAM_AUTHINFO_UNAVAIL: _bindgen_ty_1 = 12; +pub const PAM_USER_UNKNOWN: _bindgen_ty_1 = 13; +pub const PAM_CRED_UNAVAIL: _bindgen_ty_1 = 14; +pub const PAM_CRED_EXPIRED: _bindgen_ty_1 = 15; +pub const PAM_CRED_ERR: _bindgen_ty_1 = 16; +pub const PAM_ACCT_EXPIRED: _bindgen_ty_1 = 17; +pub const PAM_AUTHTOK_EXPIRED: _bindgen_ty_1 = 18; +pub const PAM_SESSION_ERR: _bindgen_ty_1 = 19; +pub const PAM_AUTHTOK_ERR: _bindgen_ty_1 = 20; +pub const PAM_AUTHTOK_RECOVERY_ERR: _bindgen_ty_1 = 21; +pub const PAM_AUTHTOK_LOCK_BUSY: _bindgen_ty_1 = 22; +pub const PAM_AUTHTOK_DISABLE_AGING: _bindgen_ty_1 = 23; +pub const PAM_NO_MODULE_DATA: _bindgen_ty_1 = 24; +pub const PAM_IGNORE: _bindgen_ty_1 = 25; +pub const PAM_ABORT: _bindgen_ty_1 = 26; +pub const PAM_TRY_AGAIN: _bindgen_ty_1 = 27; +pub const PAM_MODULE_UNKNOWN: _bindgen_ty_1 = 28; +pub const PAM_BAD_ITEM: _bindgen_ty_1 = 31; +pub const PAM_PROMPT_ECHO_OFF: _bindgen_ty_2 = 1; +pub const PAM_PROMPT_ECHO_ON: _bindgen_ty_2 = 2; +pub const PAM_ERROR_MSG: _bindgen_ty_2 = 3; +pub const PAM_TEXT_INFO: _bindgen_ty_2 = 4; +pub const PAM_MAX_RESP_SIZE: _bindgen_ty_2 = 512; +pub const PAM_SILENT: _bindgen_ty_3 = -2147483648; +pub const PAM_DISALLOW_NULL_AUTHTOK: _bindgen_ty_3 = 1; +pub const PAM_REINITIALIZE_CRED: _bindgen_ty_3 = 4; +pub const PAM_CHANGE_EXPIRED_AUTHTOK: _bindgen_ty_3 = 4; +pub const PAM_USER: _bindgen_ty_4 = 2; +pub const PAM_TTY: _bindgen_ty_4 = 3; +pub const PAM_RUSER: _bindgen_ty_4 = 8; +extern "C" { + pub fn pam_acct_mgmt(_pamh: *mut pam_handle_t, _flags: libc::c_int) -> libc::c_int; +} +extern "C" { + pub fn pam_authenticate(_pamh: *mut pam_handle_t, _flags: libc::c_int) -> libc::c_int; +} +extern "C" { + pub fn pam_chauthtok(_pamh: *mut pam_handle_t, _flags: libc::c_int) -> libc::c_int; +} +extern "C" { + pub fn pam_close_session(_pamh: *mut pam_handle_t, _flags: libc::c_int) -> libc::c_int; +} +extern "C" { + pub fn pam_end(_pamh: *mut pam_handle_t, _status: libc::c_int) -> libc::c_int; +} +extern "C" { + pub fn pam_get_item( + _pamh: *const pam_handle_t, + _item_type: libc::c_int, + _item: *mut *const libc::c_void, + ) -> libc::c_int; +} +extern "C" { + pub fn pam_getenvlist(_pamh: *mut pam_handle_t) -> *mut *mut libc::c_char; +} +extern "C" { + pub fn pam_open_session(_pamh: *mut pam_handle_t, _flags: libc::c_int) -> libc::c_int; +} +extern "C" { + pub fn pam_set_item( + _pamh: *mut pam_handle_t, + _item_type: libc::c_int, + _item: *const libc::c_void, + ) -> libc::c_int; +} +extern "C" { + pub fn pam_setcred(_pamh: *mut pam_handle_t, _flags: libc::c_int) -> libc::c_int; +} +extern "C" { + pub fn pam_start( + _service: *const libc::c_char, + _user: *const libc::c_char, + _pam_conv: *const pam_conv, + _pamh: *mut *mut pam_handle_t, + ) -> libc::c_int; +} +extern "C" { + pub fn pam_strerror( + _pamh: *const pam_handle_t, + _error_number: libc::c_int, + ) -> *const libc::c_char; +} diff --git a/src/pam/sys.rs b/src/pam/sys_linux.rs similarity index 98% rename from src/pam/sys.rs rename to src/pam/sys_linux.rs index 16c58a1fa..06fe8eef8 100644 --- a/src/pam/sys.rs +++ b/src/pam/sys_linux.rs @@ -1,8 +1,6 @@ /* automatically generated by rust-bindgen 0.70.1, minified by cargo-minify */ pub type pam_handle_t = u8; -pub type __uid_t = libc::c_uint; -pub type __gid_t = libc::c_uint; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct pam_message { diff --git a/src/pam/wrapper.h b/src/pam/wrapper.h index 18d95969b..5d1b38f99 100644 --- a/src/pam/wrapper.h +++ b/src/pam/wrapper.h @@ -1,7 +1 @@ #include -#include -#include -#include -#include -#include -#include From b7850f44a1fda5f964aa47247aba5948dfdf246a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:03:55 +0200 Subject: [PATCH 2/2] Rename the pam binding files as requested Also fix the Makefile to generate the bindings. --- Makefile | 15 ++++++++++----- get-pam-variant.bash | 15 +++++++++++++++ src/pam/mod.rs | 4 ++-- src/pam/{sys_linux.rs => sys_linuxpam.rs} | 0 src/pam/{sys_freebsd.rs => sys_openpam.rs} | 0 5 files changed, 27 insertions(+), 7 deletions(-) create mode 100755 get-pam-variant.bash rename src/pam/{sys_linux.rs => sys_linuxpam.rs} (100%) rename src/pam/{sys_freebsd.rs => sys_openpam.rs} (100%) diff --git a/Makefile b/Makefile index d8ea570eb..8350a66e2 100644 --- a/Makefile +++ b/Makefile @@ -2,18 +2,23 @@ PAM_SRC_DIR = src/pam BINDGEN_CMD = bindgen --allowlist-function '^pam_.*$$' --allowlist-var '^PAM_.*$$' --opaque-type pam_handle_t --blocklist-function pam_vsyslog --blocklist-function pam_vprompt --blocklist-function pam_vinfo --blocklist-function pam_verror --blocklist-type '.*va_list.*' --ctypes-prefix libc --no-layout-tests --sort-semantically +PAM_VARIANT = $$(./get-pam-variant.bash) + .PHONY: all clean pam-sys pam-sys-diff pam-sys-diff: - @$(BINDGEN_CMD) $< | diff --color=auto $(PAM_SRC_DIR)/sys.rs - || (echo run \'make -B pam-sys\' to apply these changes && false) - @echo $(PAM_SRC_DIR)/sys.rs does not need to be re-generated + @$(BINDGEN_CMD) $(PAM_SRC_DIR)/wrapper.h | \ + sed 's/rust-bindgen [0-9]*\.[0-9]*\.[0-9]*/&, minified by cargo-minify/' | \ + diff --color=auto $(PAM_SRC_DIR)/sys_$(PAM_VARIANT).rs - \ + || (echo run \'make -B pam-sys\' to apply these changes && false) + @echo $(PAM_SRC_DIR)/sys_$(PAM_VARIANT).rs does not need to be re-generated # use 'make pam-sys' to re-generate the sys.rs file for your local platform pam-sys: - $(BINDGEN_CMD) $(PAM_SRC_DIR)/wrapper.h --output $(PAM_SRC_DIR)/sys_$$(uname | tr 'A-Z' 'a-z').rs + $(BINDGEN_CMD) $(PAM_SRC_DIR)/wrapper.h --output $(PAM_SRC_DIR)/sys_$(PAM_VARIANT).rs cargo minify --apply --allow-dirty - sed -i.bak 's/rust-bindgen [0-9]*\.[0-9]*\.[0-9]*/&, minified by cargo-minify/' $(PAM_SRC_DIR)/sys_$$(uname | tr 'A-Z' 'a-z').rs - rm $(PAM_SRC_DIR)/sys_$$(uname | tr 'A-Z' 'a-z').rs.bak + sed -i.bak 's/rust-bindgen [0-9]*\.[0-9]*\.[0-9]*/&, minified by cargo-minify/' $(PAM_SRC_DIR)/sys_$(PAM_VARIANT).rs + rm $(PAM_SRC_DIR)/sys_$(PAM_VARIANT).rs.bak clean: rm $(PAM_SRC_DIR)/sys.rs diff --git a/get-pam-variant.bash b/get-pam-variant.bash new file mode 100755 index 000000000..7d34d46de --- /dev/null +++ b/get-pam-variant.bash @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# FIXME read headers to find the actually used variant +case $(uname) in +Linux) + echo linuxpam + ;; +FreeBSD) + echo openpam + ;; +*) + echo "Unsupported platform" + exit 1 + ;; +esac diff --git a/src/pam/mod.rs b/src/pam/mod.rs index a5a835db4..3e3a5314c 100644 --- a/src/pam/mod.rs +++ b/src/pam/mod.rs @@ -16,8 +16,8 @@ mod error; mod rpassword; mod securemem; -#[cfg_attr(target_os = "linux", path = "sys_linux.rs")] -#[cfg_attr(target_os = "freebsd", path = "sys_freebsd.rs")] +#[cfg_attr(target_os = "linux", path = "sys_linuxpam.rs")] +#[cfg_attr(target_os = "freebsd", path = "sys_openpam.rs")] #[allow(nonstandard_style)] pub mod sys; diff --git a/src/pam/sys_linux.rs b/src/pam/sys_linuxpam.rs similarity index 100% rename from src/pam/sys_linux.rs rename to src/pam/sys_linuxpam.rs diff --git a/src/pam/sys_freebsd.rs b/src/pam/sys_openpam.rs similarity index 100% rename from src/pam/sys_freebsd.rs rename to src/pam/sys_openpam.rs