libpam-sys-0.2.0/Cargo.toml0000644000000023550000000000100111160ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.75.0" name = "libpam-sys" version = "0.2.0" authors = ["Paul Fisher "] links = "pam" description = "Low-level bindings for PAM (Pluggable Authentication Modules)" readme = "README.md" categories = [ "authentication", "external-ffi-bindings", "os::unix-apis", ] license = "MIT" repository = "https://hg.pfish.zone/crates/nonstick/" [package.metadata.docs.rs] default-target = "x86_64-unknown-linux-gnu" targets = [ "x86_64-apple-darwin", "x86_64-unknown-freebsd", "x86_64-unknown-illumos", ] [dependencies.libc] version = "0.2" [dependencies.libpam-sys-impls] version = "0.2.0" [build-dependencies.libpam-sys-impls] version = "0.2.0" [target."cfg(doc)".dependencies.libpam-sys-helpers] version = "0.2.0" libpam-sys-0.2.0/Cargo.toml.orig000064400000000000000000000021521046102023000145720ustar 00000000000000[workspace] resolver = "2" members = ["libpam-sys-impls", "libpam-sys-helpers", "libpam-sys-test"] [workspace.package] version = "0.2.0" authors = ["Paul Fisher "] repository = "https://hg.pfish.zone/crates/nonstick/" edition = "2021" rust-version = "1.75.0" license = "MIT" [package] name = "libpam-sys" description = "Low-level bindings for PAM (Pluggable Authentication Modules)" links = "pam" categories = [ "authentication", "external-ffi-bindings", "os::unix-apis", ] version.workspace = true authors.workspace = true repository.workspace = true edition.workspace = true rust-version.workspace = true license.workspace = true [package.metadata.docs.rs] default-target = "x86_64-unknown-linux-gnu" targets = [ "x86_64-apple-darwin", "x86_64-unknown-freebsd", "x86_64-unknown-illumos", ] [dependencies] libc = "0.2" libpam-sys-impls = { version = "0.2.0", path = "libpam-sys-impls" } [target.'cfg(doc)'.dependencies] libpam-sys-helpers = { version = "0.2.0", path = "libpam-sys-helpers" } [build-dependencies] libpam-sys-impls = { version = "0.2.0", path = "libpam-sys-impls" } libpam-sys-0.2.0/LICENSE000064400000000000000000000020441046102023000127100ustar 00000000000000Copyright 2025 Paul Fisher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. libpam-sys-0.2.0/README.md000064400000000000000000000072451046102023000131720ustar 00000000000000# `libpam-sys`: low-level bindings to Pluggable Authentication Modules - Supports all known PAM implementations on Linux, Mac OS, BSD, and Illumos/Solaris - Works with zero configuration for common use cases - No need for system header files - Depends only on `libc` If you're looking for a nice, safe, Rusty API to PAM, may I recommend [nonstick]? ## PAM implementations Supported PAM implementations are defined in the `pam_impl::PamImpl` enum. This crate automatically chooses the appropriate PAM implementation you are most likely to need installed based on the target OS. You can also explicitly specify the PAM implementation you want (if not detected correctly) by setting the `LIBPAMSYS_IMPL` environment variable **at build time**. All build-time configuration is performed by the build script of the [`libpam-sys-impls` crate](https://crates.io/crates/libpam-sys-impls). Normally, this crate exports all functionality available in the selected PAM library. `XSso` exports only the subset of the [X/SSO specification][xsso] supported by both OpenPAM and Sun PAM. ### Changing behavior based on PAM implementation Downstream crates can detect the current PAM implementation using custom `#[cfg]`s: ```rust // Your package's build.rs: use libpam_sys::pam_impl; fn main() { pam_impl::enable_pam_impl_cfg(); // the rest of your build script... } ``` This will enable the use of `#[cfg]`s that look like this: ```rust #[cfg(pam_impl = "Sun")] fn some_func() { /* Sun-specific implementation */ } #[cfg(any(pam_impl = "LinuxPam", pam_impl = "OpenPam"))] fn some_func() { /* Linux-PAM / OpenPAM implementation */ } ``` Further documentation on this is available in `libpam-sys-impls`. ## Testing Tests are mostly run through `libpam-sys-test`, which lives in the crate's workspace in its repository (along with [nonstick]). - [`ctest`][ctest] verifies the correctness of the FFI bindings (function/struct alignment, etc.). - A kind of scuffed homebrew thing also verifies that the constants are correct. There are some unit tests of glue code and other type checks. ## Minimum Rust version This crate supports **Rust 1.75**, the current version in Debian Trixie and Ubuntu 24.04.2 LTS. There shouldn't be much that needs changing, since PAM's API is quite stable. ## References - [X/SSO PAM specification][xsso]: This 1997 document laid out the original specification for PAM. - [Linux-PAM repository][linux-pam]: The Linux-PAM implementation, used by most (all?) Linux distributions. Contains many extensions. - [Linux-PAM man page][man7]: Root man page for Linux-PAM, with links to additional PAM man pages. - [Linux-PAM guides][linux-guides]: Documentation for developers using PAM and sysadmins. - [OpenPAM repository][openpam]: The OpenPAM implementation, used by many BSD varieties. This hews very close to the spec. - [OpenPAM man page][manbsd]: NetBSD's root man page for OpenPAM. - [Illumos PAM repository][illumos-pam]: Illumos's implementation of PAM, based on Sun's Solaris. Even more basic than OpenPAM. - [Illumos PAM man page][manillumos]: Illumos's root man page for its PAM implementation. [ctest]: https://github.com/rust-lang/libc/tree/ctest-v0.4.11/ctest [nonstick]: https://crates.io/crates/nonstick [xsso]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm [linux-pam]: https://github.com/linux-pam/linux-pam [man7]: https://www.man7.org/linux/man-pages/man8/pam.8.html [linux-guides]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/ [openpam]: https://git.des.dev/OpenPAM/OpenPAM [manbsd]: https://man.netbsd.org/pam.8 [illumos-pam]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam/ [manillumos]: https://illumos.org/man/3PAM/pamlibpam-sys-0.2.0/build.rs000064400000000000000000000022001046102023000133420ustar 00000000000000use std::{env, fs}; fn main() { println!("cargo:rustc-link-lib=pam"); libpam_sys_impls::enable_pam_impl_cfg(); let pam_impl = libpam_sys_impls::build_target_impl(); let impl_str = pam_impl .map(|i| format!("{i:?}")) .unwrap_or("[undefined]".into()); println!("cargo:rustc-env=LIBPAMSYS_IMPL={impl_str}"); let output = match pam_impl { None => "".into(), Some(pam_impl) => { format!( "\ /// The implementation of PAM this library was built against. pub const CURRENT: PamImpl = PamImpl::{pam_impl:?}; /// The name of the PAM implementation this library was built /// against, as a string. #[macro_export] macro_rules! pam_impl_name {{ () => {{ \"{pam_impl:?}\" }} }} pub(crate) use pam_impl_name; " ) } }; let outfile = format!( "{out}/pam_impl_consts.rs", out = env::var("OUT_DIR").expect("missing OUT_DIR env var") ); fs::write(outfile, output).expect("couldn't write output file"); } libpam-sys-0.2.0/src/aliases.rs000064400000000000000000000030061046102023000144600ustar 00000000000000//! Convenience aliases for complex types in PAM. use super::{pam_conv, pam_handle, pam_message, pam_response, pam_set_data}; use std::ffi::{c_int, c_void}; /// The type of [`pam_conv::conv`]. /// /// The exact format of `messages` varies between Linux-PAM and other /// implementations. See `libpam_sys_helpers::PtrPtrVec` for details /// (and a workaround). /// /// ```no_run /// use libpam_sys::aliases::ConversationCallback; /// use libpam_sys::pam_conv; /// fn convo() -> ConversationCallback { /// // ... /// # unimplemented!() /// } /// let conv = pam_conv { /// conv: convo(), /// appdata_ptr: std::ptr::null_mut(), /// }; /// ``` pub type ConversationCallback = unsafe extern "C" fn( num_msg: c_int, msg: *const *const pam_message, resp: *mut *mut pam_response, appdata: *mut c_void, ) -> c_int; /// Alias for the callback to [`pam_set_data`]. /// /// ```no_run /// # use std::ffi::CString; /// use libpam_sys::aliases::CleanupCallback; /// use libpam_sys::pam_set_data; /// # use libpam_sys::pam_handle; /// # let handle: *mut pam_handle = std::ptr::null_mut(); /// # let mut my_data = 100; /// # let data_ptr = &mut my_data as *mut i32; /// fn cleanup() -> CleanupCallback { /// // ... /// # unimplemented!() /// } /// let name = CString::new("name").unwrap(); /// unsafe { /// pam_set_data(handle, name.as_ptr().cast_mut(), data_ptr.cast(), cleanup()); /// } /// ``` pub type CleanupCallback = unsafe extern "C" fn(pamh: *mut pam_handle, data: *mut c_void, pam_end_status: c_int); libpam-sys-0.2.0/src/constants.rs000064400000000000000000000175421046102023000150650ustar 00000000000000//! All of `libpam`'s constants. //! //! These constants are tested on a per-platform basis by `libpam-sys-test`'s //! `test_constants.rs`. #![allow(non_camel_case_types)] /// Macro to make defining a bunch of constants way easier. macro_rules! define { ($(#[$attr:meta])* $($name:ident = $value:expr);+$(;)?) => { define!( @meta { $(#[$attr])* } $(pub const $name: i32 = $value;)+ ); }; (@meta $m:tt $($i:item)+) => { define!(@expand $($m $i)+); }; (@expand $({ $(#[$m:meta])* } $i:item)+) => {$($(#[$m])* $i)+}; } /// Macro to make defining C-style enums way easier. macro_rules! c_enum { ($(#[$attr:meta])* $($name:ident $(= $value:expr)?,)*) => { c_enum!( (0) $(#[$attr])* $($name $(= $value)?,)* ); }; (($n:expr) $(#[$attr:meta])* $name:ident, $($rest:ident $(= $rv:expr)?,)*) => { $(#[$attr])* pub const $name: i32 = $n; c_enum!(($n + 1) $(#[$attr])* $($rest $(= $rv)?,)*); }; (($n:expr) $(#[$attr:meta])* $name:ident = $value:expr, $($rest:ident $(= $rv:expr)?,)*) => { $(#[$attr])* pub const $name: i32 = $value; c_enum!(($value + 1) $(#[$attr])* $($rest $(= $rv)?,)*); }; (($n:expr) $(#[$attr:meta])*) => {}; } // There are a few truly universal constants. // They are defined here directly. /// The successful return code. pub const PAM_SUCCESS: i32 = 0; c_enum!( /// An item type. PAM_SERVICE = 1, PAM_USER, PAM_TTY, PAM_RHOST, PAM_CONV, PAM_AUTHTOK, PAM_OLDAUTHTOK, PAM_RUSER, PAM_USER_PROMPT, ); c_enum!( /// A message style. PAM_PROMPT_ECHO_OFF = 1, PAM_PROMPT_ECHO_ON, PAM_ERROR_MSG, PAM_TEXT_INFO, ); define!( /// Maximum size of PAM conversation elements (suggested). PAM_MAX_NUM_MSG = 32; PAM_MAX_MSG_SIZE = 512; PAM_MAX_RESP_SIZE = 512; ); /// A flag for `pam_authenticate`. pub const PAM_DISALLOW_NULL_AUTHTOK: i32 = 0x1; #[cfg(pam_impl = "LinuxPam")] pub use linux_pam::*; #[cfg(pam_impl = "LinuxPam")] mod linux_pam { c_enum!( /// An error return code. PAM_OPEN_ERR = 1, PAM_SYMBOL_ERR, PAM_SERVICE_ERR, PAM_SYSTEM_ERR, PAM_BUF_ERR, PAM_PERM_DENIED, PAM_AUTH_ERR, PAM_CRED_INSUFFICIENT, PAM_AUTHINFO_UNAVAIL, PAM_USER_UNKNOWN, PAM_MAXTRIES, PAM_NEW_AUTHTOK_REQD, PAM_ACCT_EXPIRED, PAM_SESSION_ERR, PAM_CRED_UNAVAIL, PAM_CRED_EXPIRED, PAM_CRED_ERR, PAM_NO_MODULE_DATA, PAM_CONV_ERR, PAM_AUTHTOK_ERR, PAM_AUTHTOK_RECOVERY_ERR, PAM_AUTHTOK_LOCK_BUSY, PAM_AUTHTOK_DISABLE_AGING, PAM_TRY_AGAIN, PAM_IGNORE, PAM_ABORT, PAM_AUTHTOK_EXPIRED, PAM_MODULE_UNKNOWN, PAM_BAD_ITEM, PAM_CONV_AGAIN, PAM_INCOMPLETE, _PAM_RETURN_VALUES, ); define!( /// A flag value. PAM_SILENT = 0x8000; PAM_ESTABLISH_CRED = 0x0002; PAM_DELETE_CRED = 0x0004; PAM_REINITIALIZE_CRED = 0x0008; PAM_REFRESH_CRED = 0x0010; PAM_CHANGE_EXPIRED_AUTHTOK = 0x0020; PAM_PRELIM_CHECK = 0x4000; PAM_UPDATE_AUTHTOK = 0x2000; PAM_DATA_REPLACE = 0x20000000; ); c_enum!( /// An item type (Linux-only). PAM_FAIL_DELAY = 10, PAM_XDISPLAY, PAM_XAUTHDATA, PAM_AUTHTOK_TYPE, ); /// To suppress messages in the item cleanup function. pub const PAM_DATA_SILENT: i32 = 0x40000000; // Message styles define!( /// A message style. PAM_RADIO_TYPE = 5; PAM_BINARY_PROMPT = 7; ); pub const PAM_MODUTIL_NGROUPS: i32 = 64; #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[repr(i32)] pub enum pam_modutil_redirect_fd { PAM_MODUTIL_IGNORE_FD, PAM_MODUTIL_PIPE_FD, PAM_MODUTIL_NULL_FD, } impl From for i32 { fn from(value: pam_modutil_redirect_fd) -> Self { value as Self } } impl TryFrom for pam_modutil_redirect_fd { type Error = i32; fn try_from(value: i32) -> Result { match value { 0..=2 => Ok(unsafe { *(&value as *const i32).cast() }), other => Err(other), } } } #[doc(inline)] pub use pam_modutil_redirect_fd::*; } #[cfg(any(pam_impl = "OpenPam", pam_impl = "Sun", pam_impl = "XSso"))] pub use xsso_shared::*; #[cfg(any(pam_impl = "OpenPam", pam_impl = "Sun", pam_impl = "XSso"))] mod xsso_shared { c_enum!( /// An error return code. PAM_OPEN_ERR = 1, PAM_SYMBOL_ERR, PAM_SERVICE_ERR, PAM_SYSTEM_ERR, PAM_BUF_ERR, PAM_CONV_ERR, PAM_PERM_DENIED, PAM_MAXTRIES, PAM_AUTH_ERR, PAM_NEW_AUTHTOK_REQD, PAM_CRED_INSUFFICIENT, PAM_AUTHINFO_UNAVAIL, PAM_USER_UNKNOWN, PAM_CRED_UNAVAIL, PAM_CRED_EXPIRED, PAM_CRED_ERR, PAM_ACCT_EXPIRED, PAM_AUTHTOK_EXPIRED, PAM_SESSION_ERR, PAM_AUTHTOK_ERR, PAM_AUTHTOK_RECOVERY_ERR, PAM_AUTHTOK_LOCK_BUSY, PAM_AUTHTOK_DISABLE_AGING, PAM_NO_MODULE_DATA, PAM_IGNORE, PAM_ABORT, PAM_TRY_AGAIN, ); // While `PAM_MODULE_UNKNOWN` and `PAM_DOMAIN_UNKNOWN` are in X/SSO, // Sun doesn't use them so we're omitting them here. /// A general flag for PAM operations. pub const PAM_SILENT: i32 = 0x80000000u32 as i32; define!( /// A flag for `pam_setcred`. PAM_ESTABLISH_CRED = 0b0001; PAM_DELETE_CRED = 0b0010; PAM_REINITIALIZE_CRED = 0b0100; PAM_REFRESH_CRED = 0b1000; ); define!( /// A flag for `pam_sm_chauthtok`. PAM_PRELIM_CHECK = 0b0001; PAM_UPDATE_AUTHTOK = 0b0010; PAM_CHANGE_EXPIRED_AUTHTOK = 0b0100; ); } #[cfg(pam_impl = "OpenPam")] pub use openpam::*; #[cfg(pam_impl = "OpenPam")] mod openpam { c_enum!( /// An error return code. PAM_MODULE_UNKNOWN = 28, PAM_DOMAIN_UNKNOWN, PAM_BAD_HANDLE, PAM_BAD_ITEM, PAM_BAD_FEATURE, PAM_BAD_CONSTANT, ); /// The total number of PAM error codes (including success). pub const PAM_NUM_ERRORS: i32 = 34; c_enum!( /// An item type. PAM_REPOSITORY = 10, PAM_AUTHTOK_PROMPT, PAM_OLDAUTHTOK_PROMPT, PAM_HOST, ); /// The total number of PAM items. pub const PAM_NUM_ITEMS: i32 = 14; c_enum!( /// An optional OpenPAM feature. OPENPAM_RESTRICT_SERVICE_NAME, OPENPAM_VERIFY_POLICY_FILE, OPENPAM_RESTRICT_MODULE_NAME, OPENPAM_VERIFY_MODULE_FILE, OPENPAM_FALLBACK_TO_OTHER, ); /// The number of optional OpenPAM features. pub const OPENPAM_NUM_FEATURES: i32 = 5; c_enum!( /// Log level. PAM_LOG_LIBDEBUG = -1, PAM_LOG_DEBUG, PAM_LOG_VERBOSE, PAM_LOG_NOTICE, PAM_LOG_ERROR, ); c_enum!( /// PAM primitives. PAM_SM_AUTHENTICATE, PAM_SM_SETCRED, PAM_SM_ACCT_MGMT, PAM_SM_OPEN_SESSION, PAM_SM_CLOSE_SESSION, PAM_SM_CHAUTHTOK, ); /// The number of PAM primitives. pub const PAM_NUM_PRIMITIVES: i32 = 6; } /// Constants exclusive to Illumos. #[cfg(pam_impl = "Sun")] pub use sun::*; #[cfg(pam_impl = "Sun")] mod sun { /// The total number of PAM error codes. pub const PAM_TOTAL_ERRNUM: i32 = 28; c_enum!( /// An item type. PAM_REPOSITORY = 10, PAM_RESOURCE, PAM_AUSER, ); /// A flag for `pam_chauthtok`. pub const PAM_NO_AUTHTOK_CHECK: i32 = 0b1000; define!( /// A flag for `__pam_get_authtok`. PAM_PROMPT = 1; PAM_HANDLE = 2; ); } libpam-sys-0.2.0/src/ffi.rs000064400000000000000000000312241046102023000136060ustar 00000000000000use std::ffi::{c_char, c_int, c_uint, c_void}; use std::fmt; use std::marker::{PhantomData, PhantomPinned}; /// An opaque structure that PAM uses to communicate. /// /// This is only ever returned in pointer form and cannot be constructed. #[repr(C)] pub struct pam_handle { _value: (), _marker: PhantomData<(PhantomPinned, *mut c_void)>, } impl fmt::Debug for pam_handle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "pam_handle({self:p}") } } /// Used by PAM to communicate between the module and the application. #[repr(C)] #[derive(Debug)] pub struct pam_conv { pub conv: unsafe extern "C" fn( num_msg: c_int, msg: *const *const pam_message, resp: *mut *mut pam_response, appdata: *mut c_void, ) -> c_int, pub appdata_ptr: *mut c_void, } /// A message sent into a PAM conversation. #[repr(C)] #[derive(Debug)] pub struct pam_message { pub msg_style: c_int, pub msg: *const c_char, } /// A response returned from a PAM conversation. #[repr(C)] #[derive(Debug)] pub struct pam_response { pub resp: *mut c_char, /// Completely unused. pub resp_retcode: c_int, } /// Definition of the PAM_XAUTHDATA item. Compatible with `xcb_auth_info_t`. #[cfg(pam_impl = "LinuxPam")] #[repr(C)] pub struct pam_xauth_data { pub namelen: c_int, pub name: *mut c_char, pub datalen: c_int, pub data: *mut c_char, } #[cfg(pam_impl = "LinuxPam")] #[derive(Debug)] #[repr(C)] pub struct pam_modutil_privs { pub grplist: *mut libc::gid_t, pub number_of_groups: c_int, pub allocated: c_int, pub old_gid: libc::gid_t, pub old_uid: libc::uid_t, pub is_dropped: c_int, } #[cfg(pam_impl = "OpenPam")] pub type pam_func_t = unsafe extern "C" fn( handle: *mut pam_handle, flags: c_int, argc: c_int, argv: *const *const c_char, ) -> c_int; #[cfg(pam_impl = "OpenPam")] #[derive(Debug)] #[repr(C)] pub struct pam_module { pub path: *mut c_char, pub func: [pam_func_t; 6], pub dlh: *mut c_void, } #[cfg(any(pam_impl = "OpenPam", pam_impl = "Sun"))] #[derive(Debug)] #[repr(C)] pub struct pam_repository { pub type_: *mut c_char, pub scope: *mut c_void, pub scope_len: usize, } // These are the functions specified in X/SSO. Everybody exports them. extern "C" { /// Account validation. pub fn pam_acct_mgmt(pamh: *mut pam_handle, flags: c_int) -> c_int; /// Authenticate a user. pub fn pam_authenticate(pamh: *mut pam_handle, flags: c_int) -> c_int; // Nobody implements pam_authenticate_secondary. /// Manage authentication tokens. pub fn pam_chauthtok(pamh: *mut pam_handle, flags: c_int) -> c_int; /// Close an opened user session. pub fn pam_close_session(pamh: *mut pam_handle, flags: c_int) -> c_int; /// Ends the PAM transaction. pub fn pam_end(pamh: *mut pam_handle, flags: c_int) -> c_int; /// Gets module-specific data. PAM still owns the data. pub fn pam_get_data( pamh: *const pam_handle, module_data_name: *const c_char, data: *mut *const c_void, ) -> c_int; /// Gets an environment variable. You own the return value. pub fn pam_getenv(pamh: *const pam_handle, name: *const c_char) -> *mut c_char; /// Gets all the environment variables. You own everything it points to. pub fn pam_getenvlist(pamh: *const pam_handle) -> *mut *mut c_char; /// Get information about the transaction. /// /// The item is owned by PAM. pub fn pam_get_item( pamh: *const pam_handle, item_type: c_int, item: *mut *const c_void, ) -> c_int; // Nobody implements pam_get_mapped_authtok. // Nobody implements pam_get_mapped_username. /// Get the username. PAM owns it. pub fn pam_get_user( pamh: *mut pam_handle, user: *mut *const c_char, prompt: *const c_char, ) -> c_int; /// Opens a user session. pub fn pam_open_session(pamh: *mut pam_handle, flags: c_int) -> c_int; /// Sets the value of an environment variable. `namevalue` is copied. pub fn pam_putenv(pamh: *mut pam_handle, namevalue: *const c_char) -> c_int; /// Update or delete user credentials. pub fn pam_setcred(pamh: *mut pam_handle, flags: c_int) -> c_int; /// Set module-specific data. PAM will call `cleanup` when completed. pub fn pam_set_data( pamh: *mut pam_handle, module_data_name: *const c_char, data: *mut c_void, cleanup: unsafe extern "C" fn( pamh: *mut pam_handle, data: *mut c_void, pam_end_status: c_int, ), ) -> c_int; /// Set information about the transaction. The `item` is copied. pub fn pam_set_item(pamh: *mut pam_handle, item_type: c_int, item: *const c_void) -> c_int; // Nobody implements pam_set_mapped_authtok. // Nobody implements pam_set_mapped_username. // The pam_sm_whatever functions are prototypes for the functions that // a PAM module should implement, not symbols provided by PAM. /// Starts a PAM transaction. The `conv` may or may not be copied. pub fn pam_start( service: *const c_char, user: *const c_char, pam_conv: *mut pam_conv, pamh: *mut *mut pam_handle, ) -> c_int; /// Gets a statically-allocated error string. /// /// All implementations of PAM known to this library (Linux-PAM, OpenPAM, /// and Sun) ignore `pamh` and will accept a null pointer. pub fn pam_strerror(pamh: *const pam_handle, error_number: c_int) -> *mut c_char; } #[cfg(any(pam_impl = "LinuxPam", pam_impl = "OpenPam"))] extern "C" { /// Gets `PAM_AUTHTOK`, or asks the user if that is unset. pub fn pam_get_authtok( pamh: *mut pam_handle, item: c_int, authtok: *mut *const c_char, prompt: *const c_char, ) -> c_int; pub fn pam_prompt( pamh: *const pam_handle, style: c_int, response: *mut *mut c_char, fmt: *const c_char, ... ) -> c_int; } #[cfg(pam_impl = "LinuxPam")] extern "C" { pub fn pam_fail_delay(pamh: *mut pam_handle, musec_delay: c_uint) -> c_int; /// Start a PAM transaction based on configuration in the given directory. pub fn pam_start_confdir( service_name: *const c_char, user: *const c_char, pam_conversation: *mut pam_conv, confdir: *const c_char, pamh: *mut *mut pam_handle, ) -> c_int; // We don't export the v-variants of the formatting functions. pub fn pam_syslog(pamh: *const pam_handle, priority: c_int, fmt: *const c_char, ...); pub fn pam_get_authtok_noverify( pamh: *const pam_handle, authtok: *mut *const c_char, prompt: *const c_char, ) -> c_int; pub fn pam_get_authtok_verify( pamh: *const pam_handle, authtok: *mut *const c_char, prompt: *const c_char, ) -> c_int; // pam_modutil also lives in libpam for Linux. pub fn pam_modutil_check_user_in_passwd( pamh: *mut pam_handle, user_name: *const c_char, file_name: *const c_char, ) -> c_int; pub fn pam_modutil_getpwnam(pamh: *mut pam_handle, user: *const c_char) -> *mut libc::passwd; pub fn pam_modutil_getpwuid(pamh: *mut pam_handle, uid: libc::uid_t) -> *mut libc::passwd; pub fn pam_modutil_getgrnam(pamh: *mut pam_handle, group: *const c_char) -> *mut libc::group; pub fn pam_modutil_getgrgid(pamh: *mut pam_handle, gid: libc::gid_t) -> *mut libc::group; pub fn pam_modutil_getspnam(pamh: *mut pam_handle, user: *const c_char) -> *mut libc::spwd; pub fn pam_modutil_user_in_group_nam_nam( pamh: *mut pam_handle, user: *const c_char, group: *const c_char, ) -> c_int; pub fn pam_modutil_user_in_group_nam_gid( pamh: *mut pam_handle, user: *const c_char, group: libc::gid_t, ) -> c_int; pub fn pam_modutil_user_in_group_uid_nam( pamh: *mut pam_handle, user: libc::uid_t, group: *const c_char, ) -> c_int; pub fn pam_modutil_user_in_group_uid_gid( pamh: *mut pam_handle, user: libc::uid_t, group: libc::gid_t, ) -> c_int; pub fn pam_modutil_getlogin(pamh: *mut pam_handle) -> *const c_char; pub fn pam_modutil_read(fd: c_int, buffer: *mut c_char, count: c_int) -> c_int; pub fn pam_modutil_write(fd: c_int, buffer: *const c_char, count: c_int) -> c_int; pub fn pam_modutil_audit_write( pamh: *mut pam_handle, type_: c_int, message: *const c_char, retval: c_int, ) -> c_int; pub fn pam_modutil_drop_priv( pamh: *mut pam_handle, p: *mut pam_modutil_privs, pw: *const libc::passwd, ) -> c_int; pub fn pam_modutil_regain_priv(pamh: *mut pam_handle, p: *mut pam_modutil_privs) -> c_int; pub fn pam_modutil_sanitize_helper_fds( pamh: *mut pam_handle, redirect_stdin: super::constants::pam_modutil_redirect_fd, redirect_stdout: super::constants::pam_modutil_redirect_fd, redirect_stderr: super::constants::pam_modutil_redirect_fd, ) -> c_int; pub fn pam_modutil_search_key( pamh: *mut pam_handle, file_name: *const c_char, key: *const c_char, ) -> *mut c_char; } #[cfg(pam_impl = "OpenPam")] extern "C" { pub fn openpam_borrow_cred(pamh: *mut pam_handle, passwd: *const libc::passwd) -> c_int; pub fn openpam_subst( pamh: *const pam_handle, buf: *mut c_char, _bufsize: *mut usize, _template: *const c_char, ) -> c_int; pub fn openpam_free_data(pamh: *mut pam_handle, data: *mut c_void, status: c_int); pub fn openpam_free_envlist(_envlist: *mut *mut c_char); pub fn openpam_get_option(_pamh: *mut pam_handle, _option: *const c_char) -> *const c_char; pub fn openpam_restore_cred(pamh: *mut pam_handle) -> c_int; pub fn openpam_set_option( _pamh: *mut pam_handle, _option: *const c_char, _value: *const c_char, ) -> c_int; pub fn pam_error(pamh: *const pam_handle, _fmt: *const c_char, ...) -> c_int; pub fn pam_info(_pamh: *const pam_handle, _fmt: *const c_char, ...) -> c_int; pub fn openpam_readline( _f: *mut libc::FILE, _lineno: *mut c_int, _lenp: *mut usize, ) -> *mut c_char; pub fn openpam_readlinev( _f: *mut libc::FILE, _lineno: *mut c_int, _lenp: *mut c_int, ) -> *mut *mut c_char; pub fn openpam_readword( _f: *mut libc::FILE, _lineno: *mut c_int, _lenp: *mut usize, ) -> *mut c_char; pub fn openpam_straddch( _str: *mut *mut c_char, _sizep: *mut usize, _lenp: *mut usize, ch: c_int, ) -> c_int; pub fn openpam_set_feature(_feature: c_int, _onoff: c_int) -> c_int; pub fn openpam_get_feature(_feature: c_int, _onoff: *mut c_int) -> c_int; pub fn _openpam_log(_level: c_int, _func: *const c_char, _fmt: *const c_char, ...); /// A premade conversation function that talks to the TTY. /// /// ```no_run /// # use std::ffi::CString; /// # use std::ptr; /// use libpam_sys::*; /// # let service = CString::new("whatever").unwrap(); /// # let user = CString::new("whatever").unwrap(); /// let mut handle: *mut pam_handle = ptr::null_mut(); /// let mut conv = pam_conv { /// conv: openpam_ttyconv, /// appdata_ptr: ptr::null_mut(), /// }; /// let result = unsafe { pam_start(service.as_ptr(), user.as_ptr(), &mut conv, &mut handle) }; /// ``` pub fn openpam_ttyconv( n: c_int, _msg: *const *const pam_message, _resp: *mut *mut pam_response, _data: *mut c_void, ) -> c_int; pub static mut openpam_ttyconv_timeout: c_int; /// A null conversation function. /// /// ```no_run /// # use std::ffi::CString; /// # use std::ptr; /// use libpam_sys::*; /// # let service = CString::new("whatever").unwrap(); /// # let user = CString::new("whatever").unwrap(); /// let mut handle: *mut pam_handle = ptr::null_mut(); /// let mut conv = pam_conv { /// conv: openpam_nullconv, /// appdata_ptr: ptr::null_mut(), /// }; /// let result = unsafe { pam_start(service.as_ptr(), user.as_ptr(), &mut conv, &mut handle) }; /// ``` pub fn openpam_nullconv( n: c_int, _msg: *const *const pam_message, _resp: *mut *mut pam_response, _data: *mut c_void, ) -> c_int; } #[cfg(pam_impl = "Sun")] extern "C" { pub fn __pam_get_authtok( pamh: *mut pam_handle, source: c_int, type_: c_int, prompt: *const c_char, authtok: *mut *mut c_char, ) -> c_int; pub fn __pam_log(priority: c_int, format: *const c_char, ...); } libpam-sys-0.2.0/src/lib.rs000064400000000000000000000025441046102023000136130ustar 00000000000000//! `libpam-sys` provides low-level access to LibPAM. //! //! Everything in here is directly as exported from the LibPAM library or //! its header files, with two exceptions: //! //! - The [`pam_impl`] submodule (and the associated [`pam_impl_name!`] macro), //! which can be used to detect the current PAM implementation. //! - The [`aliases`] submodule, which contains convenient aliases //! for callback types used in libpam, so you don't have to type //! `unsafe extern "C" fn(this is so long)` all the time. #![doc = ""] #![doc = concat!("This documentation was built for the **", env!("LIBPAMSYS_IMPL"), "** implementation.")] //! //! You can override this **at build time** by setting the `LIBPAMSYS_IMPL` //! environment variable to one of the values of the [`pam_impl::PamImpl`] enum. //! For more information about configuration, see [the documentation of //! libpam-sys-impls](libpam_sys_impls::build_target_impl). #![allow(non_camel_case_types)] #![allow(unused_imports)] pub mod aliases; mod constants; mod ffi; #[doc(inline)] pub use crate::{constants::*, ffi::*}; /// Information about the current PAM implementation (or the implementation /// that is being built for). pub mod pam_impl { #[doc(inline)] pub use libpam_sys_impls::{enable_pam_impl_cfg, pam_impl_cfg_string, PamImpl}; include!(concat!(env!("OUT_DIR"), "/pam_impl_consts.rs")); }