Mercurial > crates > nonstick
comparison libpam-sys/src/ffi.rs @ 127:c77846f3a979
GET CTEST WORKING.
This will verify that the functions we're exporting are correct.
It has been a nightmare.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Mon, 30 Jun 2025 22:56:26 -0400 |
parents | libpam-sys/src/structs.rs@2b255c92417b |
children |
comparison
equal
deleted
inserted
replaced
126:57c812e308bd | 127:c77846f3a979 |
---|---|
1 #![allow(non_camel_case_types)] | |
2 | |
3 use std::ffi::{c_char, c_int, c_void}; | |
4 use std::fmt; | |
5 use std::marker::{PhantomData, PhantomPinned}; | |
6 | |
7 /// A marker struct to make whatever it's in `!Sync`, `!Send`, and `!Unpin`. | |
8 #[derive(Default, PartialOrd, PartialEq, Ord, Eq)] | |
9 #[repr(C)] | |
10 struct ExtremelyUnsafe { | |
11 _value: (), | |
12 _marker: PhantomData<(PhantomPinned, *mut c_void)>, | |
13 } | |
14 | |
15 impl fmt::Debug for ExtremelyUnsafe { | |
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
17 f.write_str("ExtremelyUnsafe") | |
18 } | |
19 } | |
20 | |
21 /// An opaque structure that PAM uses to communicate. | |
22 /// | |
23 /// This is only ever returned in pointer form and cannot be constructed. | |
24 #[repr(C)] | |
25 pub struct pam_handle(ExtremelyUnsafe); | |
26 | |
27 impl fmt::Debug for pam_handle { | |
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
29 write!(f, "PamHandle({self:p}") | |
30 } | |
31 } | |
32 | |
33 /// An opaque structure that is passed through PAM in a conversation. | |
34 #[repr(C)] | |
35 pub struct AppData(ExtremelyUnsafe); | |
36 | |
37 impl fmt::Debug for AppData { | |
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
39 write!(f, "AppData({self:p}") | |
40 } | |
41 } | |
42 | |
43 /// Just an alias for the type of [`pam_conv::conv`]. | |
44 /// | |
45 /// For important details about the format of `messages`, | |
46 /// see the [`helpers`](crate::helpers) module. | |
47 /// | |
48 /// ```no_run | |
49 /// # use libpam_sys::{ConversationCallback, pam_conv}; | |
50 /// fn convo() -> ConversationCallback { | |
51 /// // ... | |
52 /// # unimplemented!() | |
53 /// } | |
54 /// let conv = pam_conv{conv: convo(), appdata_ptr: std::ptr::null_mut()}; | |
55 /// ``` | |
56 pub type ConversationCallback = unsafe extern "C" fn( | |
57 num_msg: c_int, | |
58 msg: *const *const pam_message, | |
59 resp: *mut *mut pam_response, | |
60 appdata: *mut AppData, | |
61 ) -> c_int; | |
62 | |
63 /// Alias for the callback to [`pam_set_data`](crate::pam_set_data). | |
64 /// | |
65 /// ```no_run | |
66 /// # use std::ffi::CString; | |
67 /// use libpam_sys::{CleanupCallback, pam_set_data}; | |
68 /// # use libpam_sys::pam_handle; | |
69 /// # let handle: *mut pam_handle = std::ptr::null_mut(); | |
70 /// # let mut my_data = 100; | |
71 /// # let data_ptr = &mut my_data as *mut i32; | |
72 /// fn cleanup() -> CleanupCallback { | |
73 /// // ... | |
74 /// # unimplemented!() | |
75 /// } | |
76 /// let name = CString::new("name").unwrap(); | |
77 /// unsafe { | |
78 /// pam_set_data(handle, name.as_ptr().cast_mut(), data_ptr.cast(), cleanup()); | |
79 /// } | |
80 /// ``` | |
81 pub type CleanupCallback = unsafe extern "C" fn( | |
82 pamh: *mut pam_handle, | |
83 data: *mut c_void, | |
84 pam_end_status: c_int, | |
85 ); | |
86 | |
87 /// Used by PAM to communicate between the module and the application. | |
88 #[repr(C)] | |
89 pub struct pam_conv { | |
90 pub conv: unsafe extern "C" fn( | |
91 num_msg: c_int, | |
92 msg: *const *const pam_message, | |
93 resp: *mut *mut pam_response, | |
94 appdata: *mut AppData, | |
95 ) -> c_int, | |
96 pub appdata_ptr: *mut AppData, | |
97 } | |
98 | |
99 /// A message sent into a PAM conversation. | |
100 #[repr(C)] | |
101 pub struct pam_message { | |
102 pub msg_style: c_int, | |
103 pub msg: *const c_char, | |
104 } | |
105 | |
106 /// A response returned from a PAM conversation. | |
107 #[repr(C)] | |
108 pub struct pam_response { | |
109 pub resp: *mut c_char, | |
110 /// Completely unused. | |
111 pub resp_retcode: c_int, | |
112 } | |
113 | |
114 | |
115 // These are the functions specified in X/SSO. Everybody exports them. | |
116 extern "C" { | |
117 /// Account validation. | |
118 pub fn pam_acct_mgmt(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
119 | |
120 /// Authenticate a user. | |
121 pub fn pam_authenticate(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
122 | |
123 // Nobody implements pam_authenticate_secondary. | |
124 | |
125 /// Manage authentication tokens. | |
126 pub fn pam_chauthtok(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
127 | |
128 /// Close an opened user session. | |
129 pub fn pam_close_session(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
130 | |
131 /// Ends the PAM transaction. | |
132 pub fn pam_end(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
133 | |
134 /// Gets module-specific data. PAM still owns the data. | |
135 pub fn pam_get_data( | |
136 pamh: *mut pam_handle, | |
137 module_data_name: *const c_char, | |
138 data: *mut *const c_void, | |
139 ) -> c_int; | |
140 | |
141 /// Gets an environment variable. You own the return value. | |
142 pub fn pam_getenv(pamh: *mut pam_handle, name: *const c_char) -> *mut c_char; | |
143 | |
144 /// Gets all the environment variables. You own everything it points to. | |
145 pub fn pam_getenvlist(pamh: *mut pam_handle) -> *mut *mut c_char; | |
146 | |
147 /// Get information about the transaction. | |
148 /// | |
149 /// The item is owned by PAM. | |
150 pub fn pam_get_item( | |
151 pamh: *mut pam_handle, | |
152 item_type: c_int, | |
153 item: *mut *const c_void, | |
154 ) -> c_int; | |
155 | |
156 // Nobody implements pam_get_mapped_authtok. | |
157 // Nobody implements pam_get_mapped_username. | |
158 | |
159 /// Get the username. PAM owns it. | |
160 pub fn pam_get_user( | |
161 pamh: *mut pam_handle, | |
162 user: *mut *const c_char, | |
163 prompt: *const c_char, | |
164 ) -> c_int; | |
165 | |
166 /// Opens a user session. | |
167 pub fn pam_open_session(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
168 | |
169 /// Sets the value of an environment variable. `namevalue` is copied. | |
170 pub fn pam_putenv(pamh: *mut pam_handle, namevalue: *const c_char) -> c_int; | |
171 | |
172 /// Update or delete user credentials. | |
173 pub fn pam_setcred(pamh: *mut pam_handle, flags: c_int) -> c_int; | |
174 | |
175 /// Set module-specific data. PAM will call `cleanup` when completed. | |
176 pub fn pam_set_data( | |
177 pamh: *mut pam_handle, | |
178 module_data_name: *const c_char, | |
179 data: *mut c_void, | |
180 cleanup: unsafe extern "C" fn( | |
181 pamh: *mut pam_handle, | |
182 data: *mut c_void, | |
183 pam_end_status: c_int, | |
184 ), | |
185 ) -> c_int; | |
186 | |
187 /// Set information about the transaction. The `item` is copied. | |
188 pub fn pam_set_item(pamh: *mut pam_handle, item_type: c_int, item: *const c_void) -> c_int; | |
189 | |
190 // Nobody implements pam_set_mapped_authtok. | |
191 // Nobody implements pam_set_mapped_username. | |
192 | |
193 // The pam_sm_whatever functions are prototypes for the functions that | |
194 // a PAM module should implement, not symbols provided by PAM. | |
195 | |
196 // Nobody implements pam_authenticate_secondary. | |
197 | |
198 /// Starts a PAM transaction. The `conv` may or may not be copied. | |
199 pub fn pam_start( | |
200 service: *const c_char, | |
201 user: *const c_char, | |
202 pam_conv: *mut pam_conv, | |
203 pamh: *mut *mut pam_handle, | |
204 ) -> c_int; | |
205 | |
206 /// Gets a statically-allocated error string. | |
207 /// | |
208 /// All implementations of PAM known to this library (Linux-PAM, OpenPAM, | |
209 /// and Sun) ignore `pamh` and will accept a null pointer. | |
210 pub fn pam_strerror(pamh: *const pam_handle, error_number: c_int) -> *mut c_char; | |
211 } | |
212 | |
213 // We use `_private_pam_impl_hack` because ctest loses its mind | |
214 // when it comes across the `cfg_pam_impl` macro. | |
215 // This is a custom cfg variable set in our build.rs. Don't do this; just use | |
216 // cfg_pam_impl. | |
217 #[cfg(_private_pam_impl_hack = "LinuxPam")] | |
218 extern "C" { | |
219 pub fn pam_get_authtok(pamh: *mut pam_handle, x: c_int, token: *mut *const c_char, prompt: *const c_char) -> c_int; | |
220 } | |
221 | |
222 | |
223 // int (*)(struct pam_handle *, char *, void *, void (*)(struct pam_handle *, void *, int)) | |
224 // int (*)(struct pam_handle *, char *, void *, int (*)(struct pam_handle *, void *, int)) |