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 }