1mod c_box;
117mod context;
118#[cfg(feature = "cli")]
119pub mod conv_cli;
120pub mod conv_mock;
121pub mod conv_null;
122mod conversation;
123pub mod env_list;
124mod error;
125mod ffi;
126mod resp_buf;
127mod session;
128
129#[macro_use]
130extern crate bitflags;
131use libc::{c_char, c_int};
132use std::ffi::CStr;
133
134pub use context::Context;
135pub use conversation::ConversationHandler;
136pub use error::{Error, ErrorWith};
137pub use session::{Session, SessionToken};
138
139use pam_sys::*;
140pub extern crate pam_sys2 as pam_sys;
141
142fn char_ptr_to_str<'a>(ptr: *const c_char) -> Option<&'a str> {
143 if ptr.is_null() {
144 None
145 } else {
146 let cstr = unsafe { CStr::from_ptr(ptr) };
147 match cstr.to_str() {
148 Err(_) => None,
149 Ok(s) => Some(s),
150 }
151 }
152}
153
154bitflags! {
155 #[allow(clippy::upper_case_acronyms)]
157 #[repr(transparent)]
158 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent))]
159 #[derive(Copy, Clone)]
160 pub struct Flag: c_int {
161 const SILENT = PAM_SILENT as c_int;
163 const DISALLOW_NULL_AUTHTOK = PAM_DISALLOW_NULL_AUTHTOK as c_int;
165 const CHANGE_EXPIRED_AUTHTOK = PAM_CHANGE_EXPIRED_AUTHTOK as c_int;
167 #[doc(hidden)]
169 const ESTABLISH_CRED = PAM_ESTABLISH_CRED as c_int;
170 #[doc(hidden)]
172 const DELETE_CRED = PAM_DELETE_CRED as c_int;
173 #[doc(hidden)]
175 const REINITIALIZE_CRED = PAM_REINITIALIZE_CRED as c_int;
176 #[doc(hidden)]
178 const REFRESH_CRED = PAM_REFRESH_CRED as c_int;
179 }
180}
181
182#[allow(clippy::upper_case_acronyms)]
183impl Flag {
184 pub const NONE: Flag = Flag::empty();
186}
187
188#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
189#[repr(isize)]
190#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
191#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
192pub enum ErrorCode {
194 OPEN_ERR = PAM_OPEN_ERR as isize,
195 SYMBOL_ERR = PAM_SYMBOL_ERR as isize,
196 SERVICE_ERR = PAM_SERVICE_ERR as isize,
197 SYSTEM_ERR = PAM_SYSTEM_ERR as isize,
198 BUF_ERR = PAM_BUF_ERR as isize,
199 PERM_DENIED = PAM_PERM_DENIED as isize,
200 AUTH_ERR = PAM_AUTH_ERR as isize,
201 CRED_INSUFFICIENT = PAM_CRED_INSUFFICIENT as isize,
202 AUTHINFO_UNAVAIL = PAM_AUTHINFO_UNAVAIL as isize,
203 USER_UNKNOWN = PAM_USER_UNKNOWN as isize,
204 MAXTRIES = PAM_MAXTRIES as isize,
205 NEW_AUTHTOK_REQD = PAM_NEW_AUTHTOK_REQD as isize,
206 ACCT_EXPIRED = PAM_ACCT_EXPIRED as isize,
207 SESSION_ERR = PAM_SESSION_ERR as isize,
208 CRED_UNAVAIL = PAM_CRED_UNAVAIL as isize,
209 CRED_EXPIRED = PAM_CRED_EXPIRED as isize,
210 CRED_ERR = PAM_CRED_ERR as isize,
211 CONV_ERR = PAM_CONV_ERR as isize,
212 AUTHTOK_ERR = PAM_AUTHTOK_ERR as isize,
213 AUTHTOK_RECOVERY_ERR = PAM_AUTHTOK_RECOVERY_ERR as isize,
214 AUTHTOK_LOCK_BUSY = PAM_AUTHTOK_LOCK_BUSY as isize,
215 AUTHTOK_DISABLE_AGING = PAM_AUTHTOK_DISABLE_AGING as isize,
216 ABORT = PAM_ABORT as isize,
217 AUTHTOK_EXPIRED = PAM_AUTHTOK_EXPIRED as isize,
218 MODULE_UNKNOWN = PAM_MODULE_UNKNOWN as isize,
219 BAD_ITEM = PAM_BAD_ITEM as isize,
220 CONV_AGAIN = PAM_CONV_AGAIN as isize,
221 INCOMPLETE = PAM_INCOMPLETE as isize,
222}
223
224impl ErrorCode {
225 pub fn repr(&self) -> c_int {
226 match self {
227 ErrorCode::OPEN_ERR => PAM_OPEN_ERR as c_int,
228 ErrorCode::SYMBOL_ERR => PAM_SYMBOL_ERR as c_int,
229 ErrorCode::SERVICE_ERR => PAM_SERVICE_ERR as c_int,
230 ErrorCode::SYSTEM_ERR => PAM_SYSTEM_ERR as c_int,
231 ErrorCode::BUF_ERR => PAM_BUF_ERR as c_int,
232 ErrorCode::PERM_DENIED => PAM_PERM_DENIED as c_int,
233 ErrorCode::AUTH_ERR => PAM_AUTH_ERR as c_int,
234 ErrorCode::CRED_INSUFFICIENT => PAM_CRED_INSUFFICIENT as c_int,
235 ErrorCode::AUTHINFO_UNAVAIL => PAM_AUTHINFO_UNAVAIL as c_int,
236 ErrorCode::USER_UNKNOWN => PAM_USER_UNKNOWN as c_int,
237 ErrorCode::MAXTRIES => PAM_MAXTRIES as c_int,
238 ErrorCode::NEW_AUTHTOK_REQD => PAM_NEW_AUTHTOK_REQD as c_int,
239 ErrorCode::ACCT_EXPIRED => PAM_ACCT_EXPIRED as c_int,
240 ErrorCode::SESSION_ERR => PAM_SESSION_ERR as c_int,
241 ErrorCode::CRED_UNAVAIL => PAM_CRED_UNAVAIL as c_int,
242 ErrorCode::CRED_EXPIRED => PAM_CRED_EXPIRED as c_int,
243 ErrorCode::CRED_ERR => PAM_CRED_ERR as c_int,
244 ErrorCode::CONV_ERR => PAM_CONV_ERR as c_int,
245 ErrorCode::AUTHTOK_ERR => PAM_AUTHTOK_ERR as c_int,
246 ErrorCode::AUTHTOK_RECOVERY_ERR => PAM_AUTHTOK_RECOVERY_ERR as c_int,
247 ErrorCode::AUTHTOK_LOCK_BUSY => PAM_AUTHTOK_LOCK_BUSY as c_int,
248 ErrorCode::AUTHTOK_DISABLE_AGING => {
249 PAM_AUTHTOK_DISABLE_AGING as c_int
250 }
251 ErrorCode::ABORT => PAM_ABORT as c_int,
252 ErrorCode::AUTHTOK_EXPIRED => PAM_AUTHTOK_EXPIRED as c_int,
253 ErrorCode::MODULE_UNKNOWN => PAM_MODULE_UNKNOWN as c_int,
254 ErrorCode::BAD_ITEM => PAM_BAD_ITEM as c_int,
255 ErrorCode::CONV_AGAIN => PAM_CONV_AGAIN as c_int,
256 ErrorCode::INCOMPLETE => PAM_INCOMPLETE as c_int,
257 }
258 }
259 pub fn from_repr(x: c_int) -> Option<ErrorCode> {
260 match x {
261 PAM_OPEN_ERR => Some(ErrorCode::OPEN_ERR),
262 PAM_SYMBOL_ERR => Some(ErrorCode::SYMBOL_ERR),
263 PAM_SERVICE_ERR => Some(ErrorCode::SERVICE_ERR),
264 PAM_SYSTEM_ERR => Some(ErrorCode::SYSTEM_ERR),
265 PAM_BUF_ERR => Some(ErrorCode::BUF_ERR),
266 PAM_PERM_DENIED => Some(ErrorCode::PERM_DENIED),
267 PAM_AUTH_ERR => Some(ErrorCode::AUTH_ERR),
268 PAM_CRED_INSUFFICIENT => Some(ErrorCode::CRED_INSUFFICIENT),
269 PAM_AUTHINFO_UNAVAIL => Some(ErrorCode::AUTHINFO_UNAVAIL),
270 PAM_USER_UNKNOWN => Some(ErrorCode::USER_UNKNOWN),
271 PAM_MAXTRIES => Some(ErrorCode::MAXTRIES),
272 PAM_NEW_AUTHTOK_REQD => Some(ErrorCode::NEW_AUTHTOK_REQD),
273 PAM_ACCT_EXPIRED => Some(ErrorCode::ACCT_EXPIRED),
274 PAM_SESSION_ERR => Some(ErrorCode::SESSION_ERR),
275 PAM_CRED_UNAVAIL => Some(ErrorCode::CRED_UNAVAIL),
276 PAM_CRED_EXPIRED => Some(ErrorCode::CRED_EXPIRED),
277 PAM_CRED_ERR => Some(ErrorCode::CRED_ERR),
278 PAM_CONV_ERR => Some(ErrorCode::CONV_ERR),
279 PAM_AUTHTOK_ERR => Some(ErrorCode::AUTHTOK_ERR),
280 PAM_AUTHTOK_RECOVERY_ERR => Some(ErrorCode::AUTHTOK_RECOVERY_ERR),
281 PAM_AUTHTOK_LOCK_BUSY => Some(ErrorCode::AUTHTOK_LOCK_BUSY),
282 PAM_AUTHTOK_DISABLE_AGING => Some(ErrorCode::AUTHTOK_DISABLE_AGING),
283 PAM_ABORT => Some(ErrorCode::ABORT),
284 PAM_AUTHTOK_EXPIRED => Some(ErrorCode::AUTHTOK_EXPIRED),
285 PAM_MODULE_UNKNOWN => Some(ErrorCode::MODULE_UNKNOWN),
286 PAM_BAD_ITEM => Some(ErrorCode::BAD_ITEM),
287 PAM_CONV_AGAIN => Some(ErrorCode::CONV_AGAIN),
288 PAM_INCOMPLETE => Some(ErrorCode::INCOMPLETE),
289 _ => None,
290 }
291 }
292}
293
294pub type Result<T> = std::result::Result<T, Error>;
296pub type ExtResult<T, P> = std::result::Result<T, ErrorWith<P>>;
299
300const PAM_SUCCESS: c_int = pam_sys::PAM_SUCCESS as c_int;