comparison src/libpam/handle.rs @ 92:5ddbcada30f2

Add the ability to log against a PAM handle. PAM impls provide a way to log to syslog. This exposes it via nonstick.
author Paul Fisher <paul@pfish.zone>
date Sun, 22 Jun 2025 19:29:32 -0400
parents f6186e41399b
children 51c9d7e8261a
comparison
equal deleted inserted replaced
91:039aae9a01f7 92:5ddbcada30f2
2 use crate::constants::{ErrorCode, Result}; 2 use crate::constants::{ErrorCode, Result};
3 use crate::conv::Message; 3 use crate::conv::Message;
4 use crate::handle::PamShared; 4 use crate::handle::PamShared;
5 pub use crate::libpam::pam_ffi::LibPamHandle; 5 pub use crate::libpam::pam_ffi::LibPamHandle;
6 use crate::libpam::{memory, pam_ffi}; 6 use crate::libpam::{memory, pam_ffi};
7 use crate::logging::Level;
7 use crate::{Conversation, PamHandleModule}; 8 use crate::{Conversation, PamHandleModule};
8 use num_enum::{IntoPrimitive, TryFromPrimitive}; 9 use num_enum::{IntoPrimitive, TryFromPrimitive};
9 use std::cell::Cell; 10 use std::cell::Cell;
10 use std::ffi::{c_char, c_int}; 11 use std::ffi::{c_char, c_int, CString};
11 use std::marker::PhantomData; 12 use std::marker::PhantomData;
12 use std::ops::{Deref, DerefMut}; 13 use std::ops::{Deref, DerefMut};
13 use std::ptr; 14 use std::ptr;
14 15
16 /// Owner for a PAM handle.
15 struct HandleWrap(*mut LibPamHandle); 17 struct HandleWrap(*mut LibPamHandle);
16 18
17 impl Deref for HandleWrap { 19 impl Deref for HandleWrap {
18 type Target = LibPamHandle; 20 type Target = LibPamHandle;
19 fn deref(&self) -> &Self::Target { 21 fn deref(&self) -> &Self::Target {
58 ); 60 );
59 } 61 }
60 } 62 }
61 } 63 }
62 64
65 /// Macro to implement getting/setting a CStr-based item.
63 macro_rules! cstr_item { 66 macro_rules! cstr_item {
64 (get = $getter:ident, item = $item_type:path) => { 67 (get = $getter:ident, item = $item_type:path) => {
65 fn $getter(&self) -> Result<Option<&str>> { 68 fn $getter(&self) -> Result<Option<&str>> {
66 unsafe { self.get_cstr_item($item_type) } 69 unsafe { self.get_cstr_item($item_type) }
67 } 70 }
72 } 75 }
73 }; 76 };
74 } 77 }
75 78
76 impl PamShared for LibPamHandle { 79 impl PamShared for LibPamHandle {
80 fn log(&self, level: Level, entry: &str) {
81 let entry = match CString::new(entry).or_else(|_| CString::new(dbg!(entry))) {
82 Ok(cstr) => cstr,
83 _ => return,
84 };
85 #[cfg(pam_impl = "linux-pam")]
86 {
87 // SAFETY: We're calling this function with a known value.
88 unsafe {
89 pam_ffi::pam_syslog(self, level as c_int, c"%s".as_ptr().cast(), entry.as_ptr())
90 }
91 }
92 #[cfg(pam_impl = "openpam")]
93 {
94 // SAFETY: We're calling this function with a known value.
95 unsafe {
96 pam_ffi::openpam_log(self, level as c_int, c"%s".as_ptr().cast(), entry.as_ptr())
97 }
98 }
99 }
100
77 fn username(&mut self, prompt: Option<&str>) -> Result<&str> { 101 fn username(&mut self, prompt: Option<&str>) -> Result<&str> {
78 let prompt = memory::option_cstr(prompt)?; 102 let prompt = memory::option_cstr(prompt)?;
79 let mut output: *const c_char = ptr::null(); 103 let mut output: *const c_char = ptr::null();
80 let ret = unsafe { 104 let ret = unsafe {
81 pam_ffi::pam_get_user(self, &mut output, memory::prompt_ptr(prompt.as_ref())) 105 pam_ffi::pam_get_user(self, &mut output, memory::prompt_ptr(prompt.as_ref()))
222 fn split<T>(result: &Result<T>) -> Result<()> { 246 fn split<T>(result: &Result<T>) -> Result<()> {
223 result.as_ref().map(drop).map_err(|&e| e) 247 result.as_ref().map(drop).map_err(|&e| e)
224 } 248 }
225 249
226 impl PamShared for OwnedLibPamHandle<'_> { 250 impl PamShared for OwnedLibPamHandle<'_> {
251 fn log(&self, level: Level, entry: &str) {
252 self.handle.log(level, entry)
253 }
227 delegate!(fn username(&mut self, prompt: Option<&str>) -> Result<&str>); 254 delegate!(fn username(&mut self, prompt: Option<&str>) -> Result<&str>);
228 delegate!(get = user_item, set = set_user_item); 255 delegate!(get = user_item, set = set_user_item);
229 delegate!(get = service, set = set_service); 256 delegate!(get = service, set = set_service);
230 delegate!(get = user_prompt, set = set_user_prompt); 257 delegate!(get = user_prompt, set = set_user_prompt);
231 delegate!(get = tty_name, set = set_tty_name); 258 delegate!(get = tty_name, set = set_tty_name);