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