Mercurial > crates > nonstick
comparison libpam-sys/src/lib.rs @ 176:0730f5f2ee2a
Turn `libpam-sys-consts` back into `libpam-sys-impls`.
This moves the constants into `libpam-sys` and makes `libpam-sys-impls`
responsible solely for detecting the current PAM implementation.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Wed, 30 Jul 2025 17:53:31 -0400 |
| parents | 9e4ce1631bd3 |
| children | b2456d274576 |
comparison
equal
deleted
inserted
replaced
| 175:e30775c80b49 | 176:0730f5f2ee2a |
|---|---|
| 11 #![doc = concat!("This documentation was built for the **", pam_impl_name!(), "** implementation.")] | 11 #![doc = concat!("This documentation was built for the **", pam_impl_name!(), "** implementation.")] |
| 12 //! | 12 //! |
| 13 //! You can override this **at build time** by setting the `LIBPAMSYS_IMPL` | 13 //! You can override this **at build time** by setting the `LIBPAMSYS_IMPL` |
| 14 //! environment variable to one of the values of the [`pam_impl::PamImpl`] enum. | 14 //! environment variable to one of the values of the [`pam_impl::PamImpl`] enum. |
| 15 //! For more information about configuration, see the documentation of | 15 //! For more information about configuration, see the documentation of |
| 16 //! [`libpam-sys-consts`](https://crates.io/crates/libpam-sys-consts). | 16 //! [`libpam-sys-impls`](https://crates.io/crates/libpam-sys-impls). |
| 17 #![allow(non_camel_case_types)] | 17 #![allow(non_camel_case_types)] |
| 18 #![allow(unused_imports)] | 18 #![allow(unused_imports)] |
| 19 | 19 |
| 20 pub mod aliases; | 20 pub mod aliases; |
| 21 mod constants; | |
| 22 mod ffi; | |
| 21 #[doc(inline)] | 23 #[doc(inline)] |
| 22 pub use libpam_sys_consts::constants::*; | 24 pub use crate::{constants::*, ffi::*}; |
| 23 #[doc(inline)] | 25 #[doc(inline)] |
| 24 pub use libpam_sys_consts::{pam_impl, pam_impl_name}; | 26 pub use libpam_sys_impls as pam_impl; |
| 25 use std::ffi::{c_char, c_int, c_uint, c_void}; | 27 #[doc(inline)] |
| 26 use std::fmt; | 28 pub use libpam_sys_impls::pam_impl_name; |
| 27 use std::marker::{PhantomData, PhantomPinned}; | |
| 28 | |
| 29 /// An opaque structure that PAM uses to communicate. | |
| 30 /// | |
| 31 /// This is only ever returned in pointer form and cannot be constructed. | |
| 32 #[repr(C)] | |
| 33 pub struct pam_handle { | |
| 34 _value: (), | |
| 35 _marker: PhantomData<(PhantomPinned, *mut c_void)>, | |
| 36 } | |
| 37 | |
| 38 impl fmt::Debug for pam_handle { | |
| 39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| 40 write!(f, "pam_handle({self:p}") | |
| 41 } | |
| 42 } | |
| 43 | |
| 44 /// Used by PAM to communicate between the module and the application. | |
| 45 #[repr(C)] | |
| 46 #[derive(Debug)] | |
| 47 pub struct pam_conv { | |
| 48 pub conv: unsafe extern "C" fn( | |
| 49 num_msg: c_int, | |
| 50 msg: *const *const pam_message, | |
| 51 resp: *mut *mut pam_response, | |
| 52 appdata: *mut c_void, | |
| 53 ) -> c_int, | |
| 54 pub appdata_ptr: *mut c_void, | |
| 55 } | |
| 56 | |
| 57 /// A message sent into a PAM conversation. | |
| 58 #[repr(C)] | |
| 59 #[derive(Debug)] | |
| 60 pub struct pam_message { | |
| 61 pub msg_style: c_int, | |
| 62 pub msg: *const c_char, | |
| 63 } | |
| 64 | |
| 65 /// A response returned from a PAM conversation. | |
| 66 #[repr(C)] | |
| 67 #[derive(Debug)] | |
| 68 pub struct pam_response { | |
| 69 pub resp: *mut c_char, | |
| 70 /// Completely unused. | |
| 71 pub resp_retcode: c_int, | |
| 72 } | |
| 73 | |
| 74 /// Definition of the PAM_XAUTHDATA item. Compatible with `xcb_auth_info_t`. | |
| 75 #[cfg(pam_impl = "LinuxPam")] | |
| 76 #[repr(C)] | |
| 77 pub struct pam_xauth_data { | |
| 78 pub namelen: c_int, | |
| 79 pub name: *mut c_char, | |
| 80 pub datalen: c_int, | |
| 81 pub data: *mut c_char, | |
| 82 } | |
| 83 | |
| 84 #[cfg(pam_impl = "LinuxPam")] | |
| 85 #[derive(Debug)] | |
| 86 #[repr(C)] | |
| 87 pub struct pam_modutil_privs { | |
| 88 pub grplist: *mut libc::gid_t, | |
| 89 pub number_of_groups: c_int, | |
| 90 pub allocated: c_int, | |
| 91 pub old_gid: libc::gid_t, | |
| 92 pub old_uid: libc::uid_t, | |
| 93 pub is_dropped: c_int, | |
| 94 } | |
| 95 | |
| 96 #[cfg(pam_impl = "OpenPam")] | |
| 97 pub type pam_func_t = unsafe extern "C" fn( | |
| 98 handle: *mut pam_handle, | |
| 99 flags: c_int, | |
| 100 argc: c_int, | |
| 101 argv: *const *const c_char, | |
| 102 ) -> c_int; | |
| 103 | |
| 104 #[cfg(pam_impl = "OpenPam")] | |
| 105 #[derive(Debug)] | |
| 106 #[repr(C)] | |
| 107 pub struct pam_module { | |
| 108 pub path: *mut c_char, | |
| 109 pub func: [pam_func_t; 6], | |
| 110 pub dlh: *mut c_void, | |
| 111 } | |
| 112 | |
| 113 #[cfg(any(pam_impl = "OpenPam", pam_impl = "Sun"))] | |
| 114 #[derive(Debug)] | |
| 115 #[repr(C)] | |
| 116 pub struct pam_repository { | |
| 117 pub type_: *mut c_char, | |
| 118 pub scope: *mut c_void, | |
| 119 pub scope_len: usize, | |
| 120 } | |
| 121 | |
| 122 // These are the functions specified in X/SSO. Everybody exports them. | |
| 123 extern "C" { | |
| 124 /// Account validation. | |
| 125 pub fn pam_acct_mgmt(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
| 126 | |
| 127 /// Authenticate a user. | |
| 128 pub fn pam_authenticate(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
| 129 | |
| 130 // Nobody implements pam_authenticate_secondary. | |
| 131 | |
| 132 /// Manage authentication tokens. | |
| 133 pub fn pam_chauthtok(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
| 134 | |
| 135 /// Close an opened user session. | |
| 136 pub fn pam_close_session(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
| 137 | |
| 138 /// Ends the PAM transaction. | |
| 139 pub fn pam_end(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
| 140 | |
| 141 /// Gets module-specific data. PAM still owns the data. | |
| 142 pub fn pam_get_data( | |
| 143 pamh: *const pam_handle, | |
| 144 module_data_name: *const c_char, | |
| 145 data: *mut *const c_void, | |
| 146 ) -> c_int; | |
| 147 | |
| 148 /// Gets an environment variable. You own the return value. | |
| 149 pub fn pam_getenv(pamh: *const pam_handle, name: *const c_char) -> *mut c_char; | |
| 150 | |
| 151 /// Gets all the environment variables. You own everything it points to. | |
| 152 pub fn pam_getenvlist(pamh: *const pam_handle) -> *mut *mut c_char; | |
| 153 | |
| 154 /// Get information about the transaction. | |
| 155 /// | |
| 156 /// The item is owned by PAM. | |
| 157 pub fn pam_get_item( | |
| 158 pamh: *const pam_handle, | |
| 159 item_type: c_int, | |
| 160 item: *mut *const c_void, | |
| 161 ) -> c_int; | |
| 162 | |
| 163 // Nobody implements pam_get_mapped_authtok. | |
| 164 // Nobody implements pam_get_mapped_username. | |
| 165 | |
| 166 /// Get the username. PAM owns it. | |
| 167 pub fn pam_get_user( | |
| 168 pamh: *mut pam_handle, | |
| 169 user: *mut *const c_char, | |
| 170 prompt: *const c_char, | |
| 171 ) -> c_int; | |
| 172 | |
| 173 /// Opens a user session. | |
| 174 pub fn pam_open_session(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
| 175 | |
| 176 /// Sets the value of an environment variable. `namevalue` is copied. | |
| 177 pub fn pam_putenv(pamh: *mut pam_handle, namevalue: *const c_char) -> c_int; | |
| 178 | |
| 179 /// Update or delete user credentials. | |
| 180 pub fn pam_setcred(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
| 181 | |
| 182 /// Set module-specific data. PAM will call `cleanup` when completed. | |
| 183 pub fn pam_set_data( | |
| 184 pamh: *mut pam_handle, | |
| 185 module_data_name: *const c_char, | |
| 186 data: *mut c_void, | |
| 187 cleanup: unsafe extern "C" fn( | |
| 188 pamh: *mut pam_handle, | |
| 189 data: *mut c_void, | |
| 190 pam_end_status: c_int, | |
| 191 ), | |
| 192 ) -> c_int; | |
| 193 | |
| 194 /// Set information about the transaction. The `item` is copied. | |
| 195 pub fn pam_set_item(pamh: *mut pam_handle, item_type: c_int, item: *const c_void) -> c_int; | |
| 196 | |
| 197 // Nobody implements pam_set_mapped_authtok. | |
| 198 // Nobody implements pam_set_mapped_username. | |
| 199 | |
| 200 // The pam_sm_whatever functions are prototypes for the functions that | |
| 201 // a PAM module should implement, not symbols provided by PAM. | |
| 202 | |
| 203 /// Starts a PAM transaction. The `conv` may or may not be copied. | |
| 204 pub fn pam_start( | |
| 205 service: *const c_char, | |
| 206 user: *const c_char, | |
| 207 pam_conv: *mut pam_conv, | |
| 208 pamh: *mut *mut pam_handle, | |
| 209 ) -> c_int; | |
| 210 | |
| 211 /// Gets a statically-allocated error string. | |
| 212 /// | |
| 213 /// All implementations of PAM known to this library (Linux-PAM, OpenPAM, | |
| 214 /// and Sun) ignore `pamh` and will accept a null pointer. | |
| 215 pub fn pam_strerror(pamh: *const pam_handle, error_number: c_int) -> *mut c_char; | |
| 216 } | |
| 217 | |
| 218 #[cfg(any(pam_impl = "LinuxPam", pam_impl = "OpenPam"))] | |
| 219 extern "C" { | |
| 220 /// Gets `PAM_AUTHTOK`, or asks the user if that is unset. | |
| 221 pub fn pam_get_authtok( | |
| 222 pamh: *mut pam_handle, | |
| 223 item: c_int, | |
| 224 authtok: *mut *const c_char, | |
| 225 prompt: *const c_char, | |
| 226 ) -> c_int; | |
| 227 | |
| 228 pub fn pam_prompt( | |
| 229 pamh: *const pam_handle, | |
| 230 style: c_int, | |
| 231 response: *mut *mut c_char, | |
| 232 fmt: *const c_char, | |
| 233 ... | |
| 234 ) -> c_int; | |
| 235 | |
| 236 } | |
| 237 | |
| 238 #[cfg(pam_impl = "LinuxPam")] | |
| 239 extern "C" { | |
| 240 pub fn pam_fail_delay(pamh: *mut pam_handle, musec_delay: c_uint) -> c_int; | |
| 241 | |
| 242 /// Start a PAM transaction based on configuration in the given directory. | |
| 243 pub fn pam_start_confdir( | |
| 244 service_name: *const c_char, | |
| 245 user: *const c_char, | |
| 246 pam_conversation: *mut pam_conv, | |
| 247 confdir: *const c_char, | |
| 248 pamh: *mut *mut pam_handle, | |
| 249 ) -> c_int; | |
| 250 | |
| 251 // We don't export the v-variants of the formatting functions. | |
| 252 | |
| 253 pub fn pam_syslog(pamh: *const pam_handle, priority: c_int, fmt: *const c_char, ...); | |
| 254 | |
| 255 pub fn pam_get_authtok_noverify( | |
| 256 pamh: *const pam_handle, | |
| 257 authtok: *mut *const c_char, | |
| 258 prompt: *const c_char, | |
| 259 ) -> c_int; | |
| 260 | |
| 261 pub fn pam_get_authtok_verify( | |
| 262 pamh: *const pam_handle, | |
| 263 authtok: *mut *const c_char, | |
| 264 prompt: *const c_char, | |
| 265 ) -> c_int; | |
| 266 | |
| 267 // pam_modutil also lives in libpam for Linux. | |
| 268 | |
| 269 pub fn pam_modutil_check_user_in_passwd( | |
| 270 pamh: *mut pam_handle, | |
| 271 user_name: *const c_char, | |
| 272 file_name: *const c_char, | |
| 273 ) -> c_int; | |
| 274 | |
| 275 pub fn pam_modutil_getpwnam(pamh: *mut pam_handle, user: *const c_char) -> *mut libc::passwd; | |
| 276 | |
| 277 pub fn pam_modutil_getpwuid(pamh: *mut pam_handle, uid: libc::uid_t) -> *mut libc::passwd; | |
| 278 | |
| 279 pub fn pam_modutil_getgrnam(pamh: *mut pam_handle, group: *const c_char) -> *mut libc::group; | |
| 280 | |
| 281 pub fn pam_modutil_getgrgid(pamh: *mut pam_handle, gid: libc::gid_t) -> *mut libc::group; | |
| 282 | |
| 283 pub fn pam_modutil_getspnam(pamh: *mut pam_handle, user: *const c_char) -> *mut libc::spwd; | |
| 284 | |
| 285 pub fn pam_modutil_user_in_group_nam_nam( | |
| 286 pamh: *mut pam_handle, | |
| 287 user: *const c_char, | |
| 288 group: *const c_char, | |
| 289 ) -> c_int; | |
| 290 | |
| 291 pub fn pam_modutil_user_in_group_nam_gid( | |
| 292 pamh: *mut pam_handle, | |
| 293 user: *const c_char, | |
| 294 group: libc::gid_t, | |
| 295 ) -> c_int; | |
| 296 | |
| 297 pub fn pam_modutil_user_in_group_uid_nam( | |
| 298 pamh: *mut pam_handle, | |
| 299 user: libc::uid_t, | |
| 300 group: *const c_char, | |
| 301 ) -> c_int; | |
| 302 | |
| 303 pub fn pam_modutil_user_in_group_uid_gid( | |
| 304 pamh: *mut pam_handle, | |
| 305 user: libc::uid_t, | |
| 306 group: libc::gid_t, | |
| 307 ) -> c_int; | |
| 308 | |
| 309 pub fn pam_modutil_getlogin(pamh: *mut pam_handle) -> *const c_char; | |
| 310 | |
| 311 pub fn pam_modutil_read(fd: c_int, buffer: *mut c_char, count: c_int) -> c_int; | |
| 312 | |
| 313 pub fn pam_modutil_write(fd: c_int, buffer: *const c_char, count: c_int) -> c_int; | |
| 314 | |
| 315 pub fn pam_modutil_audit_write( | |
| 316 pamh: *mut pam_handle, | |
| 317 type_: c_int, | |
| 318 message: *const c_char, | |
| 319 retval: c_int, | |
| 320 ) -> c_int; | |
| 321 | |
| 322 pub fn pam_modutil_drop_priv( | |
| 323 pamh: *mut pam_handle, | |
| 324 p: *mut pam_modutil_privs, | |
| 325 pw: *const libc::passwd, | |
| 326 ) -> c_int; | |
| 327 | |
| 328 pub fn pam_modutil_regain_priv(pamh: *mut pam_handle, p: *mut pam_modutil_privs) -> c_int; | |
| 329 | |
| 330 pub fn pam_modutil_sanitize_helper_fds( | |
| 331 pamh: *mut pam_handle, | |
| 332 redirect_stdin: pam_modutil_redirect_fd, | |
| 333 redirect_stdout: pam_modutil_redirect_fd, | |
| 334 redirect_stderr: pam_modutil_redirect_fd, | |
| 335 ) -> c_int; | |
| 336 | |
| 337 pub fn pam_modutil_search_key( | |
| 338 pamh: *mut pam_handle, | |
| 339 file_name: *const c_char, | |
| 340 key: *const c_char, | |
| 341 ) -> *mut c_char; | |
| 342 } | |
| 343 | |
| 344 #[cfg(pam_impl = "OpenPam")] | |
| 345 extern "C" { | |
| 346 pub fn openpam_borrow_cred(pamh: *mut pam_handle, passwd: *const libc::passwd) -> c_int; | |
| 347 | |
| 348 pub fn openpam_subst( | |
| 349 pamh: *const pam_handle, | |
| 350 buf: *mut c_char, | |
| 351 _bufsize: *mut usize, | |
| 352 _template: *const c_char, | |
| 353 ) -> c_int; | |
| 354 | |
| 355 pub fn openpam_free_data(pamh: *mut pam_handle, data: *mut c_void, status: c_int); | |
| 356 | |
| 357 pub fn openpam_free_envlist(_envlist: *mut *mut c_char); | |
| 358 | |
| 359 pub fn openpam_get_option(_pamh: *mut pam_handle, _option: *const c_char) -> *const c_char; | |
| 360 | |
| 361 pub fn openpam_restore_cred(pamh: *mut pam_handle) -> c_int; | |
| 362 | |
| 363 pub fn openpam_set_option( | |
| 364 _pamh: *mut pam_handle, | |
| 365 _option: *const c_char, | |
| 366 _value: *const c_char, | |
| 367 ) -> c_int; | |
| 368 | |
| 369 pub fn pam_error(pamh: *const pam_handle, _fmt: *const c_char, ...) -> c_int; | |
| 370 | |
| 371 pub fn pam_info(_pamh: *const pam_handle, _fmt: *const c_char, ...) -> c_int; | |
| 372 | |
| 373 pub fn openpam_readline( | |
| 374 _f: *mut libc::FILE, | |
| 375 _lineno: *mut c_int, | |
| 376 _lenp: *mut usize, | |
| 377 ) -> *mut c_char; | |
| 378 | |
| 379 pub fn openpam_readlinev( | |
| 380 _f: *mut libc::FILE, | |
| 381 _lineno: *mut c_int, | |
| 382 _lenp: *mut c_int, | |
| 383 ) -> *mut *mut c_char; | |
| 384 | |
| 385 pub fn openpam_readword( | |
| 386 _f: *mut libc::FILE, | |
| 387 _lineno: *mut c_int, | |
| 388 _lenp: *mut usize, | |
| 389 ) -> *mut c_char; | |
| 390 | |
| 391 pub fn openpam_straddch( | |
| 392 _str: *mut *mut c_char, | |
| 393 _sizep: *mut usize, | |
| 394 _lenp: *mut usize, | |
| 395 ch: c_int, | |
| 396 ) -> c_int; | |
| 397 | |
| 398 pub fn openpam_set_feature(_feature: c_int, _onoff: c_int) -> c_int; | |
| 399 | |
| 400 pub fn openpam_get_feature(_feature: c_int, _onoff: *mut c_int) -> c_int; | |
| 401 | |
| 402 pub fn _openpam_log(_level: c_int, _func: *const c_char, _fmt: *const c_char, ...); | |
| 403 | |
| 404 /// A premade conversation function that talks to the TTY. | |
| 405 /// | |
| 406 /// ```no_run | |
| 407 /// # use std::ffi::CString; | |
| 408 /// # use std::ptr; | |
| 409 /// use libpam_sys::*; | |
| 410 /// # let service = CString::new("whatever").unwrap(); | |
| 411 /// # let user = CString::new("whatever").unwrap(); | |
| 412 /// let mut handle: *mut pam_handle = ptr::null_mut(); | |
| 413 /// let mut conv = pam_conv { | |
| 414 /// conv: openpam_ttyconv, | |
| 415 /// appdata_ptr: ptr::null_mut(), | |
| 416 /// }; | |
| 417 /// let result = unsafe { pam_start(service.as_ptr(), user.as_ptr(), &mut conv, &mut handle) }; | |
| 418 /// ``` | |
| 419 pub fn openpam_ttyconv( | |
| 420 n: c_int, | |
| 421 _msg: *const *const pam_message, | |
| 422 _resp: *mut *mut pam_response, | |
| 423 _data: *mut c_void, | |
| 424 ) -> c_int; | |
| 425 | |
| 426 pub static mut openpam_ttyconv_timeout: c_int; | |
| 427 | |
| 428 /// A null conversation function. | |
| 429 /// | |
| 430 /// ```no_run | |
| 431 /// # use std::ffi::CString; | |
| 432 /// # use std::ptr; | |
| 433 /// use libpam_sys::*; | |
| 434 /// # let service = CString::new("whatever").unwrap(); | |
| 435 /// # let user = CString::new("whatever").unwrap(); | |
| 436 /// let mut handle: *mut pam_handle = ptr::null_mut(); | |
| 437 /// let mut conv = pam_conv { | |
| 438 /// conv: openpam_nullconv, | |
| 439 /// appdata_ptr: ptr::null_mut(), | |
| 440 /// }; | |
| 441 /// let result = unsafe { pam_start(service.as_ptr(), user.as_ptr(), &mut conv, &mut handle) }; | |
| 442 /// ``` | |
| 443 pub fn openpam_nullconv( | |
| 444 n: c_int, | |
| 445 _msg: *const *const pam_message, | |
| 446 _resp: *mut *mut pam_response, | |
| 447 _data: *mut c_void, | |
| 448 ) -> c_int; | |
| 449 } | |
| 450 | |
| 451 #[cfg(pam_impl = "Sun")] | |
| 452 extern "C" { | |
| 453 pub fn __pam_get_authtok( | |
| 454 pamh: *mut pam_handle, | |
| 455 source: c_int, | |
| 456 type_: c_int, | |
| 457 prompt: *const c_char, | |
| 458 authtok: *mut *mut c_char, | |
| 459 ) -> c_int; | |
| 460 | |
| 461 pub fn __pam_log(priority: c_int, format: *const c_char, ...); | |
| 462 } |
