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); |