comparison src/items.rs @ 72:47eb242a4f88

Fill out the PamHandle trait. This updates the PamHandle trait to have methods for each Item, and implements them on the LibPamHandle.
author Paul Fisher <paul@pfish.zone>
date Wed, 04 Jun 2025 03:53:36 -0400
parents a674799a5cd3
children
comparison
equal deleted inserted replaced
71:58f9d2a4df38 72:47eb242a4f88
1 //! Things that can be gotten with the `pam_get_item` function. 1 //! Things that can be gotten with the `pam_get_item` function.
2 2
3 use crate::constants::InvalidEnum; 3 use crate::constants::InvalidEnum;
4 use num_derive::FromPrimitive; 4 use num_derive::FromPrimitive;
5 use num_traits::FromPrimitive; 5 use num_traits::FromPrimitive;
6 use std::ffi::{c_int, CStr}; 6 use std::ffi::c_int;
7 7
8 /// Enum identifying what a `pam_get_item` return is. 8 /// Identifies what is being gotten or set with `pam_get_item`
9 /// 9 /// or `pam_set_item`.
10 /// Generally, you shouldn’t have to worry about this, and instead
11 /// just use the various [Item] implementations.
12 #[derive(FromPrimitive)] 10 #[derive(FromPrimitive)]
13 #[repr(i32)] 11 #[repr(i32)]
14 #[non_exhaustive] // because C could give us anything! 12 #[non_exhaustive] // because C could give us anything!
15 pub enum ItemType { 13 pub enum ItemType {
16 /// The PAM service name. 14 /// The PAM service name.
51 impl From<ItemType> for c_int { 49 impl From<ItemType> for c_int {
52 fn from(val: ItemType) -> Self { 50 fn from(val: ItemType) -> Self {
53 val as Self 51 val as Self
54 } 52 }
55 } 53 }
56
57 /// A type that can be requested by [`PamHandle::get_item`](crate::LibPamHandle::get_item).
58 pub trait Item {
59 /// The `repr(C)` type that is returned (by pointer) by the underlying `pam_get_item` function.
60 /// This memory is owned by the PAM session.
61 type Raw;
62
63 /// The [ItemType] corresponding to this Rust type.
64 fn type_id() -> ItemType;
65
66 /// The function to convert from the pointer to the C-representation to this safer wrapper type.
67 ///
68 /// # Safety
69 ///
70 /// This function assumes the pointer is a valid pointer to a [Self::Raw] instance.
71 unsafe fn from_raw(raw: *const Self::Raw) -> Self;
72
73 /// The function to convert from this wrapper type to a C-compatible pointer.
74 fn into_raw(self) -> *const Self::Raw;
75 }
76
77 /// Macro to generate PAM [Item]s represented as [CStr]s.
78 macro_rules! cstr_item {
79 ($name:ident) => {
80 #[doc = "The [CStr] representation of the "]
81 #[doc = concat!("[`", stringify!($name), "`](ItemType::", stringify!($name), ")")]
82 #[doc = " [Item]."]
83 #[derive(Debug)]
84 pub struct $name<'s>(pub &'s CStr);
85
86 impl<'s> std::ops::Deref for $name<'s> {
87 type Target = &'s CStr;
88 fn deref(&self) -> &Self::Target {
89 &self.0
90 }
91 }
92
93 impl<'s> Item for $name<'s> {
94 type Raw = libc::c_char;
95
96 fn type_id() -> ItemType {
97 ItemType::$name
98 }
99
100 unsafe fn from_raw(raw: *const Self::Raw) -> Self {
101 Self(std::ffi::CStr::from_ptr(raw))
102 }
103
104 fn into_raw(self) -> *const Self::Raw {
105 self.0.as_ptr()
106 }
107 }
108 };
109 }
110
111 // Conversation is not included here since it's special.
112
113 cstr_item!(Service);
114 cstr_item!(User);
115 cstr_item!(Tty);
116 cstr_item!(RemoteHost);
117 cstr_item!(AuthTok);
118 cstr_item!(OldAuthTok);
119 cstr_item!(RemoteUser);
120 cstr_item!(UserPrompt);