Mercurial > crates > nonstick
comparison libpam-sys/src/ffi.rs @ 131:a632a8874131
Get all the Linux-PAM functions into libpam-sys, and get tests right.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Wed, 02 Jul 2025 02:24:21 -0400 |
| parents | 80c07e5ab22f |
| children | 32b2a545ca3e |
comparison
equal
deleted
inserted
replaced
| 130:80c07e5ab22f | 131:a632a8874131 |
|---|---|
| 1 //! The actual PAM FFI bindings. | |
| 2 //! | |
| 3 //! They live in this specific file rather than lib.rs because otherwise | |
| 4 //! ctest gets very upset about some of the macros we use. | |
| 1 #![allow(non_camel_case_types)] | 5 #![allow(non_camel_case_types)] |
| 2 | 6 #![allow(unused_imports)] |
| 3 use std::ffi::{c_char, c_int, c_void}; | 7 |
| 8 use num_enum::{IntoPrimitive, TryFromPrimitive}; | |
| 9 use std::ffi::{c_char, c_int, c_uint, c_void}; | |
| 4 use std::fmt; | 10 use std::fmt; |
| 5 use std::marker::{PhantomData, PhantomPinned}; | 11 use std::marker::{PhantomData, PhantomPinned}; |
| 6 | 12 |
| 7 /// A marker struct to make whatever it's in `!Sync`, `!Send`, and `!Unpin`. | 13 /// A marker struct to make whatever it's in `!Sync`, `!Send`, and `!Unpin`. |
| 8 #[derive(Default, PartialOrd, PartialEq, Ord, Eq)] | 14 #[derive(Default, PartialOrd, PartialEq, Ord, Eq)] |
| 12 _marker: PhantomData<(PhantomPinned, *mut c_void)>, | 18 _marker: PhantomData<(PhantomPinned, *mut c_void)>, |
| 13 } | 19 } |
| 14 | 20 |
| 15 impl fmt::Debug for ExtremelyUnsafe { | 21 impl fmt::Debug for ExtremelyUnsafe { |
| 16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 17 f.write_str("ExtremelyUnsafe") | 23 write!(f, "ExtremelyUnsafe({self:p})") |
| 18 } | 24 } |
| 19 } | 25 } |
| 20 | 26 |
| 21 /// An opaque structure that PAM uses to communicate. | 27 /// An opaque structure that PAM uses to communicate. |
| 22 /// | 28 /// |
| 24 #[repr(C)] | 30 #[repr(C)] |
| 25 pub struct pam_handle(ExtremelyUnsafe); | 31 pub struct pam_handle(ExtremelyUnsafe); |
| 26 | 32 |
| 27 impl fmt::Debug for pam_handle { | 33 impl fmt::Debug for pam_handle { |
| 28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 29 write!(f, "PamHandle({self:p}") | 35 write!(f, "pam_handle({self:p}") |
| 30 } | 36 } |
| 31 } | 37 } |
| 32 | 38 |
| 33 /// An opaque structure that is passed through PAM in a conversation. | 39 /// An opaque structure that is passed through PAM in a conversation. |
| 34 #[repr(C)] | 40 #[repr(C)] |
| 106 pub resp: *mut c_char, | 112 pub resp: *mut c_char, |
| 107 /// Completely unused. | 113 /// Completely unused. |
| 108 pub resp_retcode: c_int, | 114 pub resp_retcode: c_int, |
| 109 } | 115 } |
| 110 | 116 |
| 117 /// Definition of the PAM_XAUTHDATA item. Compatible with `xcb_auth_info_t`. | |
| 118 #[cfg(_hack_impl = "LinuxPam")] | |
| 119 #[repr(C)] | |
| 120 pub struct pam_xauth_data { | |
| 121 namelen: c_int, | |
| 122 name: *mut c_char, | |
| 123 datalen: c_int, | |
| 124 data: *mut c_char, | |
| 125 } | |
| 126 | |
| 127 #[cfg(_hack_impl = "LinuxPam")] | |
| 128 #[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] | |
| 129 #[repr(i32)] | |
| 130 pub enum pam_modutil_redirect_fd { | |
| 131 PAM_MODUTIL_IGNORE_FD, | |
| 132 PAM_MODUTIL_PIPE_FD, | |
| 133 PAM_MODUTIL_NULL_FD, | |
| 134 } | |
| 135 | |
| 136 #[cfg(_hack_impl = "LinuxPam")] | |
| 137 pub use pam_modutil_redirect_fd::*; | |
| 138 | |
| 139 #[cfg(_hack_impl = "LinuxPam")] | |
| 140 #[derive(Debug)] | |
| 141 #[repr(C)] | |
| 142 pub struct pam_modutil_privs { | |
| 143 grplist: *mut libc::gid_t, | |
| 144 number_of_groups: c_int, | |
| 145 allocated: c_int, | |
| 146 old_gid: libc::gid_t, | |
| 147 old_uid: libc::uid_t, | |
| 148 is_dropped: c_int, | |
| 149 } | |
| 150 | |
| 111 // These are the functions specified in X/SSO. Everybody exports them. | 151 // These are the functions specified in X/SSO. Everybody exports them. |
| 112 extern "C" { | 152 extern "C" { |
| 113 /// Account validation. | 153 /// Account validation. |
| 114 pub fn pam_acct_mgmt(pamh: *mut pam_handle, flags: c_int) -> c_int; | 154 pub fn pam_acct_mgmt(pamh: *mut pam_handle, flags: c_int) -> c_int; |
| 115 | 155 |
| 204 /// All implementations of PAM known to this library (Linux-PAM, OpenPAM, | 244 /// All implementations of PAM known to this library (Linux-PAM, OpenPAM, |
| 205 /// and Sun) ignore `pamh` and will accept a null pointer. | 245 /// and Sun) ignore `pamh` and will accept a null pointer. |
| 206 pub fn pam_strerror(pamh: *const pam_handle, error_number: c_int) -> *mut c_char; | 246 pub fn pam_strerror(pamh: *const pam_handle, error_number: c_int) -> *mut c_char; |
| 207 } | 247 } |
| 208 | 248 |
| 209 // We use `_private_pam_impl_hack` because ctest loses its mind | 249 // We use `_hack_impl` because ctest loses its mind |
| 210 // when it comes across the `cfg_pam_impl` macro. | 250 // when it comes across the `cfg_pam_impl` macro. |
| 211 // This is a custom cfg variable set in our build.rs. Don't do this; just use | 251 // This is a custom cfg variable set in our build.rs. Don't do this; just use |
| 212 // cfg_pam_impl. | 252 // cfg_pam_impl. |
| 213 #[cfg(any(_private_pam_impl_hack = "LinuxPam", _private_pam_impl_hack = "OpenPam"))] | 253 #[cfg(any(_hack_impl = "LinuxPam", _hack_impl = "OpenPam"))] |
| 214 extern "C" { | 254 extern "C" { |
| 255 /// Gets `PAM_AUTHTOK`, or asks the user if that is unset. | |
| 215 pub fn pam_get_authtok( | 256 pub fn pam_get_authtok( |
| 216 pamh: *mut pam_handle, | 257 pamh: *mut pam_handle, |
| 217 x: c_int, | 258 item: c_int, |
| 218 token: *mut *const c_char, | 259 authtok: *mut *const c_char, |
| 219 prompt: *const c_char, | 260 prompt: *const c_char, |
| 220 ) -> c_int; | 261 ) -> c_int; |
| 221 } | 262 } |
| 263 | |
| 264 #[cfg(_hack_impl = "LinuxPam")] | |
| 265 extern "C" { | |
| 266 pub fn pam_fail_delay(pamh: *mut pam_handle, musec_delay: c_uint) -> c_int; | |
| 267 | |
| 268 /// Start a PAM transaction based on configuration in the given directory. | |
| 269 pub fn pam_start_confdir( | |
| 270 service_name: *const c_char, | |
| 271 user: *const c_char, | |
| 272 pam_conversation: *mut pam_conv, | |
| 273 confdir: *const c_char, | |
| 274 pamh: *mut *mut pam_handle, | |
| 275 ) -> c_int; | |
| 276 | |
| 277 // We don't export the v-variants of the formatting functions. | |
| 278 | |
| 279 pub fn pam_syslog(pamh: *const pam_handle, priority: c_int, fmt: *const c_char, ...); | |
| 280 | |
| 281 pub fn pam_prompt( | |
| 282 pamh: *const pam_handle, | |
| 283 style: c_int, | |
| 284 response: *mut *mut c_char, | |
| 285 fmt: *const c_char, | |
| 286 ... | |
| 287 ) -> c_int; | |
| 288 | |
| 289 pub fn pam_get_authtok_noverify( | |
| 290 pamh: *const pam_handle, | |
| 291 authtok: *mut *const c_char, | |
| 292 prompt: *const c_char, | |
| 293 ) -> c_int; | |
| 294 | |
| 295 pub fn pam_get_authtok_verify( | |
| 296 pamh: *const pam_handle, | |
| 297 authtok: *mut *const c_char, | |
| 298 prompt: *const c_char, | |
| 299 ) -> c_int; | |
| 300 | |
| 301 // pam_modutil also lives in libpam for Linux. | |
| 302 | |
| 303 pub fn pam_modutil_check_user_in_passwd( | |
| 304 pamh: *mut pam_handle, | |
| 305 user_name: *const c_char, | |
| 306 file_name: *const c_char, | |
| 307 ) -> c_int; | |
| 308 | |
| 309 pub fn pam_modutil_getpwnam(pamh: *mut pam_handle, user: *const c_char) -> *mut libc::passwd; | |
| 310 | |
| 311 pub fn pam_modutil_getpwuid(pamh: *mut pam_handle, uid: libc::uid_t) -> *mut libc::passwd; | |
| 312 | |
| 313 pub fn pam_modutil_getgrnam(pamh: *mut pam_handle, group: *const c_char) -> *mut libc::group; | |
| 314 | |
| 315 pub fn pam_modutil_getgrgid(pamh: *mut pam_handle, gid: libc::gid_t) -> *mut libc::group; | |
| 316 | |
| 317 pub fn pam_modutil_getspnam(pamh: *mut pam_handle, user: *const c_char) -> *mut libc::spwd; | |
| 318 | |
| 319 pub fn pam_modutil_user_in_group_nam_nam( | |
| 320 pamh: *mut pam_handle, | |
| 321 user: *const c_char, | |
| 322 group: *const c_char, | |
| 323 ) -> c_int; | |
| 324 pub fn pam_modutil_user_in_group_nam_gid( | |
| 325 pamh: *mut pam_handle, | |
| 326 user: *const c_char, | |
| 327 group: libc::gid_t, | |
| 328 ) -> c_int; | |
| 329 | |
| 330 pub fn pam_modutil_user_in_group_uid_nam( | |
| 331 pamh: *mut pam_handle, | |
| 332 user: libc::uid_t, | |
| 333 group: *const c_char, | |
| 334 ) -> c_int; | |
| 335 | |
| 336 pub fn pam_modutil_user_in_group_uid_gid( | |
| 337 pamh: *mut pam_handle, | |
| 338 user: libc::uid_t, | |
| 339 group: libc::gid_t, | |
| 340 ) -> c_int; | |
| 341 | |
| 342 pub fn pam_modutil_getlogin(pamh: *mut pam_handle) -> *const c_char; | |
| 343 | |
| 344 pub fn pam_modutil_read(fd: c_int, buffer: *mut c_char, count: c_int) -> c_int; | |
| 345 | |
| 346 pub fn pam_modutil_write(fd: c_int, buffer: *const c_char, count: c_int) -> c_int; | |
| 347 | |
| 348 pub fn pam_modutil_audit_write( | |
| 349 pamh: *mut pam_handle, | |
| 350 typ: c_int, | |
| 351 message: *const c_char, | |
| 352 retval: c_int, | |
| 353 ) -> c_int; | |
| 354 | |
| 355 pub fn pam_modutil_drop_priv( | |
| 356 pamh: *mut pam_handle, | |
| 357 p: *mut pam_modutil_privs, | |
| 358 pw: *const libc::passwd, | |
| 359 ) -> c_int; | |
| 360 | |
| 361 pub fn pam_modutil_regain_priv(pamh: *mut pam_handle, p: *mut pam_modutil_privs) -> c_int; | |
| 362 | |
| 363 pub fn pam_modutil_sanitize_helper_fds( | |
| 364 pamh: *mut pam_handle, | |
| 365 redirect_stdin: pam_modutil_redirect_fd, | |
| 366 redirect_stdout: pam_modutil_redirect_fd, | |
| 367 redirect_stderr: pam_modutil_redirect_fd, | |
| 368 ) -> c_int; | |
| 369 | |
| 370 pub fn pam_modutil_search_key( | |
| 371 pamh: *mut pam_handle, | |
| 372 file_name: *const c_char, | |
| 373 key: *const c_char, | |
| 374 ) -> *mut c_char; | |
| 375 } |
