Mercurial > crates > nonstick
view src/items.rs @ 64:bbe84835d6db v0.0.5
More organization; add lots of docs.
- moves `PamHandle` to its own module, since it will be used
by both modules and clients.
- adds a ton of documentation to the `PamModule` trait
and reorders methods to most-interesting-first.
- adds more flag values from pam_modules.h.
- other misc cleanup.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 22 May 2025 01:52:32 -0400 |
parents | d83623951070 |
children |
line wrap: on
line source
//! Things that can be gotten with the `pam_get_item` function. use crate::constants::InvalidEnum; use num_derive::FromPrimitive; use num_traits::FromPrimitive; use std::ffi::{c_int, CStr}; /// Enum identifying what a `pam_get_item` return is. /// /// Generally, you shouldn’t have to worry about this, and instead /// just use the various [Item] implementations. #[derive(FromPrimitive)] #[repr(i32)] #[non_exhaustive] // because C could give us anything! pub enum ItemType { /// The PAM service name. Service = 1, /// The user's login name. User = 2, /// The TTY name. Tty = 3, /// The remote host (if applicable). RemoteHost = 4, /// The conversation struct (not a CStr-based item). Conversation = 5, /// The authentication token (password). AuthTok = 6, /// The old authentication token (when changing passwords). OldAuthTok = 7, /// The remote user's name. RemoteUser = 8, /// The prompt shown when requesting a username. UserPrompt = 9, /// App-supplied function to override failure delays. FailDelay = 10, /// X display name. XDisplay = 11, /// X server authentication data. XAuthData = 12, /// The type of `pam_get_authtok`. AuthTokType = 13, } impl TryFrom<c_int> for ItemType { type Error = InvalidEnum<Self>; fn try_from(value: c_int) -> Result<Self, Self::Error> { Self::from_i32(value).ok_or(value.into()) } } impl From<ItemType> for c_int { fn from(val: ItemType) -> Self { val as Self } } /// A type that can be requested by [`PamHandle::get_item`](crate::PamHandle::get_item). pub trait Item { /// The `repr(C)` type that is returned (by pointer) by the underlying `pam_get_item` function. /// This memory is owned by the PAM session. type Raw; /// The [ItemType] corresponding to this Rust type. fn type_id() -> ItemType; /// The function to convert from the pointer to the C-representation to this safer wrapper type. /// /// # Safety /// /// This function assumes the pointer is a valid pointer to a [Self::Raw] instance. unsafe fn from_raw(raw: *const Self::Raw) -> Self; /// The function to convert from this wrapper type to a C-compatible pointer. fn into_raw(self) -> *const Self::Raw; } /// Macro to generate PAM [Item]s represented as [CStr]s. macro_rules! cstr_item { ($name:ident) => { #[doc = "The [CStr] representation of the "] #[doc = concat!("[`", stringify!($name), "`](ItemType::", stringify!($name), ")")] #[doc = " [Item]."] #[derive(Debug)] pub struct $name<'s>(pub &'s CStr); impl<'s> std::ops::Deref for $name<'s> { type Target = &'s CStr; fn deref(&self) -> &Self::Target { &self.0 } } impl<'s> Item for $name<'s> { type Raw = libc::c_char; fn type_id() -> ItemType { ItemType::$name } unsafe fn from_raw(raw: *const Self::Raw) -> Self { Self(std::ffi::CStr::from_ptr(raw)) } fn into_raw(self) -> *const Self::Raw { self.0.as_ptr() } } }; } // Conversation is not included here since it's special. cstr_item!(Service); cstr_item!(User); cstr_item!(Tty); cstr_item!(RemoteHost); cstr_item!(AuthTok); cstr_item!(OldAuthTok); cstr_item!(RemoteUser); cstr_item!(UserPrompt);