Mercurial > crates > nonstick
comparison src/libpam/items.rs @ 146:1bc52025156b
Split PAM items into their own separate struct.
To trim down the number of methods on `PamShared`, this puts all the
Items into their own struct(s). This also makes the split between
authtok/authtok_item easier to understand.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sun, 06 Jul 2025 19:10:26 -0400 |
| parents | |
| children | a75a66cb4181 |
comparison
equal
deleted
inserted
replaced
| 145:8f964b701652 | 146:1bc52025156b |
|---|---|
| 1 use crate::constants::ErrorCode; | |
| 2 use crate::constants::Result; | |
| 3 use crate::items::{Items, ItemsMut}; | |
| 4 use crate::libpam::handle::ItemType; | |
| 5 use crate::libpam::handle::LibPamHandle; | |
| 6 use crate::libpam::memory; | |
| 7 use std::ffi::{c_int, OsStr, OsString}; | |
| 8 use std::ptr; | |
| 9 | |
| 10 pub struct LibPamItems<'a>(pub &'a LibPamHandle); | |
| 11 pub struct LibPamItemsMut<'a>(pub &'a mut LibPamHandle); | |
| 12 | |
| 13 /// Macro to implement getting/setting a CStr-based item. | |
| 14 macro_rules! cstr_item { | |
| 15 (get = $getter:ident, item = $item_type:path) => { | |
| 16 fn $getter(&self) -> Result<Option<OsString>> { | |
| 17 unsafe { get_cstr_item(&self.0, $item_type) } | |
| 18 } | |
| 19 }; | |
| 20 (set = $setter:ident, item = $item_type:path) => { | |
| 21 fn $setter(&mut self, value: Option<&OsStr>) -> Result<()> { | |
| 22 unsafe { set_cstr_item(&mut self.0, $item_type, value) } | |
| 23 } | |
| 24 }; | |
| 25 } | |
| 26 | |
| 27 impl Items<'_> for LibPamItems<'_> { | |
| 28 cstr_item!(get = user, item = ItemType::User); | |
| 29 cstr_item!(get = service, item = ItemType::Service); | |
| 30 cstr_item!(get = user_prompt, item = ItemType::UserPrompt); | |
| 31 cstr_item!(get = tty_name, item = ItemType::Tty); | |
| 32 cstr_item!(get = remote_user, item = ItemType::RemoteUser); | |
| 33 cstr_item!(get = remote_host, item = ItemType::RemoteHost); | |
| 34 } | |
| 35 | |
| 36 impl Items<'_> for LibPamItemsMut<'_> { | |
| 37 cstr_item!(get = user, item = ItemType::User); | |
| 38 cstr_item!(get = service, item = ItemType::Service); | |
| 39 cstr_item!(get = user_prompt, item = ItemType::UserPrompt); | |
| 40 cstr_item!(get = tty_name, item = ItemType::Tty); | |
| 41 cstr_item!(get = remote_user, item = ItemType::RemoteUser); | |
| 42 cstr_item!(get = remote_host, item = ItemType::RemoteHost); | |
| 43 } | |
| 44 | |
| 45 impl ItemsMut<'_> for LibPamItemsMut<'_> { | |
| 46 cstr_item!(set = set_user, item = ItemType::User); | |
| 47 cstr_item!(set = set_service, item = ItemType::Service); | |
| 48 cstr_item!(set = set_user_prompt, item = ItemType::UserPrompt); | |
| 49 cstr_item!(set = set_tty_name, item = ItemType::Tty); | |
| 50 cstr_item!(set = set_remote_user, item = ItemType::RemoteUser); | |
| 51 cstr_item!(set = set_remote_host, item = ItemType::RemoteHost); | |
| 52 cstr_item!(set = set_authtok, item = ItemType::AuthTok); | |
| 53 cstr_item!(set = set_old_authtok, item = ItemType::OldAuthTok); | |
| 54 } | |
| 55 | |
| 56 /// Gets a C string item. | |
| 57 /// | |
| 58 /// # Safety | |
| 59 /// | |
| 60 /// You better be requesting an item which is a C string. | |
| 61 pub unsafe fn get_cstr_item( | |
| 62 hdl: &LibPamHandle, | |
| 63 item_type: ItemType, | |
| 64 ) -> crate::Result<Option<OsString>> { | |
| 65 let mut output = ptr::null(); | |
| 66 let ret = unsafe { libpam_sys::pam_get_item(hdl.raw_ref(), item_type as c_int, &mut output) }; | |
| 67 ErrorCode::result_from(ret)?; | |
| 68 Ok(memory::copy_pam_string(output.cast())) | |
| 69 } | |
| 70 | |
| 71 /// Sets a C string item. | |
| 72 /// | |
| 73 /// # Safety | |
| 74 /// | |
| 75 /// You better be setting an item which is a C string. | |
| 76 pub unsafe fn set_cstr_item( | |
| 77 hdl: &mut LibPamHandle, | |
| 78 item_type: ItemType, | |
| 79 data: Option<&OsStr>, | |
| 80 ) -> crate::Result<()> { | |
| 81 let data_str = memory::option_cstr_os(data); | |
| 82 let ret = unsafe { | |
| 83 libpam_sys::pam_set_item( | |
| 84 hdl.raw_mut(), | |
| 85 item_type as c_int, | |
| 86 memory::prompt_ptr(data_str.as_deref()).cast(), | |
| 87 ) | |
| 88 }; | |
| 89 ErrorCode::result_from(ret) | |
| 90 } |
