comparison src/libpam/handle.rs @ 171:e27c5c667a5a

Create full new types for return code and flags, separate end to end. This plumbs the ReturnCode and RawFlags types through the places where we call into or are called from PAM. Also adds Sun documentation to the project.
author Paul Fisher <paul@pfish.zone>
date Fri, 25 Jul 2025 20:52:14 -0400
parents 77470e45e397
children 9e4ce1631bd3
comparison
equal deleted inserted replaced
170:f052e2417195 171:e27c5c667a5a
1 use super::conversation::{OwnedConversation, PamConv}; 1 use super::conversation::{OwnedConversation, PamConv};
2 use crate::_doc::{guide, linklist, man7, stdlinks}; 2 use crate::_doc::{guide, linklist, man7, stdlinks};
3 use crate::constants::{ErrorCode, Result}; 3 use crate::constants::{ErrorCode, RawFlags, Result, ReturnCode};
4 use crate::conv::Exchange; 4 use crate::conv::Exchange;
5 use crate::environ::EnvironMapMut; 5 use crate::environ::EnvironMapMut;
6 use crate::handle::PamShared; 6 use crate::handle::PamShared;
7 use crate::items::{Items, ItemsMut}; 7 use crate::items::{Items, ItemsMut};
8 use crate::libpam::environ::{LibPamEnviron, LibPamEnvironMut}; 8 use crate::libpam::environ::{LibPamEnviron, LibPamEnvironMut};
9 use crate::libpam::items::{LibPamItems, LibPamItemsMut}; 9 use crate::libpam::items::{LibPamItems, LibPamItemsMut};
10 use crate::libpam::{items, memory}; 10 use crate::libpam::{items, memory};
11 use crate::logging::{Level, Location, Logger}; 11 use crate::logging::{Level, Location, Logger};
12 use crate::{AuthnFlags, AuthtokFlags, Conversation, EnvironMap, ModuleClient, Transaction}; 12 use crate::{AuthnFlags, AuthtokFlags, Conversation, EnvironMap, ModuleClient, Transaction};
13 use libpam_sys_consts::constants;
14 use num_enum::{IntoPrimitive, TryFromPrimitive}; 13 use num_enum::{IntoPrimitive, TryFromPrimitive};
15 use std::any::TypeId; 14 use std::any::TypeId;
16 use std::cell::Cell; 15 use std::cell::Cell;
17 use std::ffi::{c_char, c_int, c_void, CString, OsStr, OsString}; 16 use std::ffi::{c_char, c_int, c_void, CString, OsStr, OsString};
18 use std::os::unix::ffi::OsStrExt; 17 use std::os::unix::ffi::OsStrExt;
144 // If it's not LinuxPam, we just drop normally. 143 // If it's not LinuxPam, we just drop normally.
145 } 144 }
146 145
147 /// Internal "end" function, which binary-ORs the status with `or_with`. 146 /// Internal "end" function, which binary-ORs the status with `or_with`.
148 fn end_internal(&mut self, or_with: i32) { 147 fn end_internal(&mut self, or_with: i32) {
149 let result = ErrorCode::result_to_c(self.last_return.get()) | or_with; 148 let last: i32 = ReturnCode::from(self.last_return.get()).into();
149 let result = last | or_with;
150 unsafe { libpam_sys::pam_end(self.handle.cast(), result) }; 150 unsafe { libpam_sys::pam_end(self.handle.cast(), result) };
151 } 151 }
152 } 152 }
153 153
154 macro_rules! wrap { 154 macro_rules! wrap {
155 (fn $name:ident($ftype:ident) { $pam_func:ident }) => { 155 (fn $name:ident($ftype:ident) { $pam_func:ident }) => {
156 fn $name(&mut self, flags: $ftype) -> Result<()> { 156 fn $name(&mut self, flags: $ftype) -> Result<()> {
157 let flags: RawFlags = flags.into();
157 ErrorCode::result_from(unsafe { 158 ErrorCode::result_from(unsafe {
158 libpam_sys::$pam_func((self as *mut Self).cast(), flags.bits()) 159 libpam_sys::$pam_func((self as *mut Self).cast(), flags.into())
159 }) 160 })
160 } 161 }
161 }; 162 };
162 } 163 }
163 164
263 #[doc = linklist!(pam_end: adg, _std)] 264 #[doc = linklist!(pam_end: adg, _std)]
264 /// 265 ///
265 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_end")] 266 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_end")]
266 #[doc = stdlinks!(3 pam_end)] 267 #[doc = stdlinks!(3 pam_end)]
267 pub fn end(&mut self, result: Result<()>) { 268 pub fn end(&mut self, result: Result<()>) {
268 unsafe { libpam_sys::pam_end(self.inner_mut(), ErrorCode::result_to_c(result)) }; 269 let code: ReturnCode = result.into();
270 unsafe { libpam_sys::pam_end(self.inner_mut(), code.into()) };
269 } 271 }
270 272
271 #[cfg_attr( 273 #[cfg_attr(
272 not(pam_impl = "LinuxPam"), 274 not(pam_impl = "LinuxPam"),
273 doc = "Exactly equivalent to [`Self::end`], except on Linux-PAM." 275 doc = "Exactly equivalent to [`Self::end`], except on Linux-PAM."
288 #[doc = linklist!(pam_end: adg, _std)] 290 #[doc = linklist!(pam_end: adg, _std)]
289 /// 291 ///
290 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_end")] 292 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_end")]
291 #[doc = stdlinks!(3 pam_end)] 293 #[doc = stdlinks!(3 pam_end)]
292 pub fn end_silent(&mut self, result: Result<()>) { 294 pub fn end_silent(&mut self, result: Result<()>) {
293 let result = ErrorCode::result_to_c(result); 295 let result: i32 = ReturnCode::from(result).into();
294 #[cfg(pam_impl = "LinuxPam")] 296 #[cfg(pam_impl = "LinuxPam")]
295 let result = result | libpam_sys::PAM_DATA_SILENT; 297 let result = result | libpam_sys::PAM_DATA_SILENT;
296 unsafe { 298 unsafe {
297 libpam_sys::pam_end(self.inner_mut(), result); 299 libpam_sys::pam_end(self.inner_mut(), result);
298 } 300 }
515 #[derive(Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] 517 #[derive(Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
516 #[repr(i32)] 518 #[repr(i32)]
517 #[non_exhaustive] // because C could give us anything! 519 #[non_exhaustive] // because C could give us anything!
518 pub enum ItemType { 520 pub enum ItemType {
519 /// The PAM service name. 521 /// The PAM service name.
520 Service = constants::PAM_SERVICE, 522 Service = libpam_sys::PAM_SERVICE,
521 /// The user's login name. 523 /// The user's login name.
522 User = constants::PAM_USER, 524 User = libpam_sys::PAM_USER,
523 /// The TTY name. 525 /// The TTY name.
524 Tty = constants::PAM_TTY, 526 Tty = libpam_sys::PAM_TTY,
525 /// The remote host (if applicable). 527 /// The remote host (if applicable).
526 RemoteHost = constants::PAM_RHOST, 528 RemoteHost = libpam_sys::PAM_RHOST,
527 /// The conversation struct (not a CStr-based item). 529 /// The conversation struct (not a CStr-based item).
528 Conversation = constants::PAM_CONV, 530 Conversation = libpam_sys::PAM_CONV,
529 /// The authentication token (password). 531 /// The authentication token (password).
530 AuthTok = constants::PAM_AUTHTOK, 532 AuthTok = libpam_sys::PAM_AUTHTOK,
531 /// The old authentication token (when changing passwords). 533 /// The old authentication token (when changing passwords).
532 OldAuthTok = constants::PAM_OLDAUTHTOK, 534 OldAuthTok = libpam_sys::PAM_OLDAUTHTOK,
533 /// The remote user's name. 535 /// The remote user's name.
534 RemoteUser = constants::PAM_RUSER, 536 RemoteUser = libpam_sys::PAM_RUSER,
535 /// The prompt shown when requesting a username. 537 /// The prompt shown when requesting a username.
536 UserPrompt = constants::PAM_USER_PROMPT, 538 UserPrompt = libpam_sys::PAM_USER_PROMPT,
537 #[cfg(feature = "linux-pam-ext")] 539 #[cfg(feature = "linux-pam-ext")]
538 /// App-supplied function to override failure delays. 540 /// App-supplied function to override failure delays.
539 FailDelay = constants::PAM_FAIL_DELAY, 541 FailDelay = libpam_sys::PAM_FAIL_DELAY,
540 #[cfg(feature = "linux-pam-ext")] 542 #[cfg(feature = "linux-pam-ext")]
541 /// X display name. 543 /// X display name.
542 XDisplay = constants::PAM_XDISPLAY, 544 XDisplay = libpam_sys::PAM_XDISPLAY,
543 #[cfg(feature = "linux-pam-ext")] 545 #[cfg(feature = "linux-pam-ext")]
544 /// X server authentication data. 546 /// X server authentication data.
545 XAuthData = constants::PAM_XAUTHDATA, 547 XAuthData = libpam_sys::PAM_XAUTHDATA,
546 #[cfg(feature = "linux-pam-ext")] 548 #[cfg(feature = "linux-pam-ext")]
547 /// The type of `pam_get_authtok`. 549 /// The type of `pam_get_authtok`.
548 AuthTokType = constants::PAM_AUTHTOK_TYPE, 550 AuthTokType = libpam_sys::PAM_AUTHTOK_TYPE,
549 } 551 }