Mercurial > crates > nonstick
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); |
