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
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 }