Mercurial > crates > nonstick
view src/libpam/items.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 | a75a66cb4181 |
children | a1bb1d013567 |
line wrap: on
line source
use crate::constants::ErrorCode; use crate::constants::Result; use crate::items::{Items, ItemsMut}; use crate::libpam::handle::ItemType; use crate::libpam::handle::LibPamHandle; use crate::libpam::memory; use std::ffi::{c_int, OsStr, OsString}; use std::ptr; pub struct LibPamItems<'a>(pub &'a LibPamHandle); pub struct LibPamItemsMut<'a>(pub &'a mut LibPamHandle); /// Macro to implement getting/setting a CStr-based item. macro_rules! cstr_item { (get = $getter:ident, item = $item_type:path) => { fn $getter(&self) -> Result<Option<OsString>> { unsafe { get_cstr_item(&self.0, $item_type) } } }; (set = $setter:ident, item = $item_type:path) => { fn $setter(&mut self, value: Option<&OsStr>) -> Result<()> { unsafe { set_cstr_item(&mut self.0, $item_type, value) } } }; } impl Items<'_> for LibPamItems<'_> { cstr_item!(get = user, item = ItemType::User); cstr_item!(get = service, item = ItemType::Service); cstr_item!(get = user_prompt, item = ItemType::UserPrompt); cstr_item!(get = tty_name, item = ItemType::Tty); cstr_item!(get = remote_user, item = ItemType::RemoteUser); cstr_item!(get = remote_host, item = ItemType::RemoteHost); } impl Items<'_> for LibPamItemsMut<'_> { cstr_item!(get = user, item = ItemType::User); cstr_item!(get = service, item = ItemType::Service); cstr_item!(get = user_prompt, item = ItemType::UserPrompt); cstr_item!(get = tty_name, item = ItemType::Tty); cstr_item!(get = remote_user, item = ItemType::RemoteUser); cstr_item!(get = remote_host, item = ItemType::RemoteHost); } impl ItemsMut<'_> for LibPamItemsMut<'_> { cstr_item!(set = set_user, item = ItemType::User); cstr_item!(set = set_service, item = ItemType::Service); cstr_item!(set = set_user_prompt, item = ItemType::UserPrompt); cstr_item!(set = set_tty_name, item = ItemType::Tty); cstr_item!(set = set_remote_user, item = ItemType::RemoteUser); cstr_item!(set = set_remote_host, item = ItemType::RemoteHost); cstr_item!(set = set_authtok, item = ItemType::AuthTok); cstr_item!(set = set_old_authtok, item = ItemType::OldAuthTok); } /// Gets a C string item. /// /// # Safety /// /// You better be requesting an item which is a C string. pub unsafe fn get_cstr_item(hdl: &LibPamHandle, item_type: ItemType) -> Result<Option<OsString>> { let mut output = ptr::null(); let ret = unsafe { libpam_sys::pam_get_item(hdl.inner(), item_type as c_int, &mut output) }; ErrorCode::result_from(ret)?; Ok(memory::copy_pam_string(output.cast())) } /// Sets a C string item. /// /// # Safety /// /// You better be setting an item which is a C string. pub unsafe fn set_cstr_item( hdl: &mut LibPamHandle, item_type: ItemType, data: Option<&OsStr>, ) -> Result<()> { let data_str = memory::option_cstr_os(data); let ret = unsafe { libpam_sys::pam_set_item( hdl.inner_mut(), item_type as c_int, memory::prompt_ptr(data_str.as_deref()).cast(), ) }; ErrorCode::result_from(ret) }