comparison src/libpam/handle.rs @ 116:a12706e42c9d default tip

Logging, macros, and building: - Changes logging API to accept the `Location` of the log statement. Fixes OpenPAM implementation. - Stops publicly exporting doc macros. - Uses dlopen to detect the PAM library rather than header jankery.
author Paul Fisher <paul@pfish.zone>
date Sun, 29 Jun 2025 18:27:51 -0400
parents 13b4d2a19674
children
comparison
equal deleted inserted replaced
115:1e11a52b4665 116:a12706e42c9d
4 use crate::environ::EnvironMapMut; 4 use crate::environ::EnvironMapMut;
5 use crate::handle::PamShared; 5 use crate::handle::PamShared;
6 use crate::libpam::environ::{LibPamEnviron, LibPamEnvironMut}; 6 use crate::libpam::environ::{LibPamEnviron, LibPamEnvironMut};
7 pub use crate::libpam::pam_ffi::LibPamHandle; 7 pub use crate::libpam::pam_ffi::LibPamHandle;
8 use crate::libpam::{memory, pam_ffi}; 8 use crate::libpam::{memory, pam_ffi};
9 use crate::logging::Level; 9 use crate::logging::{Level, Location};
10 use crate::{ 10 use crate::{
11 Conversation, EnvironMap, Flags, PamHandleApplication, PamHandleModule, _guide, _linklist, 11 Conversation, EnvironMap, Flags, PamHandleApplication, PamHandleModule, guide, linklist,
12 _stdlinks, 12 stdlinks,
13 }; 13 };
14 use num_enum::{IntoPrimitive, TryFromPrimitive}; 14 use num_enum::{IntoPrimitive, TryFromPrimitive};
15 use std::cell::Cell; 15 use std::cell::Cell;
16 use std::ffi::{c_char, c_int, CString}; 16 use std::ffi::{c_char, c_int, CString};
17 use std::ops::{Deref, DerefMut}; 17 use std::ops::{Deref, DerefMut};
80 /// The service name is what controls the steps and checks PAM goes through 80 /// The service name is what controls the steps and checks PAM goes through
81 /// when authenticating a user. This corresponds to the configuration file 81 /// when authenticating a user. This corresponds to the configuration file
82 /// named <code>/etc/pam.d/<var>service_name</var></code>. 82 /// named <code>/etc/pam.d/<var>service_name</var></code>.
83 /// 83 ///
84 /// # References 84 /// # References
85 #[doc = _linklist!(pam_start: adg, _std)] 85 #[doc = linklist!(pam_start: adg, _std)]
86 /// 86 ///
87 #[doc = _stdlinks!(3 pam_start)] 87 #[doc = stdlinks!(3 pam_start)]
88 #[doc = _guide!(adg: "adg-interface-by-app-expected.html#adg-pam_start")] 88 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_start")]
89 pub fn build_with_service(service_name: String) -> HandleBuilder { 89 pub fn build_with_service(service_name: String) -> HandleBuilder {
90 HandleBuilder { 90 HandleBuilder {
91 service_name, 91 service_name,
92 username: None, 92 username: None,
93 } 93 }
159 /// Closes the PAM session on an owned PAM handle. 159 /// Closes the PAM session on an owned PAM handle.
160 /// 160 ///
161 /// This internally calls `pam_end` with the appropriate error code. 161 /// This internally calls `pam_end` with the appropriate error code.
162 /// 162 ///
163 /// # References 163 /// # References
164 #[doc = _linklist!(pam_end: adg, _std)] 164 #[doc = linklist!(pam_end: adg, _std)]
165 /// 165 ///
166 #[doc = _guide!(adg: "adg-interface-by-app-expected.html#adg-pam_end")] 166 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_end")]
167 #[doc = _stdlinks!(3 pam_end)] 167 #[doc = stdlinks!(3 pam_end)]
168 fn drop(&mut self) { 168 fn drop(&mut self) {
169 unsafe { 169 unsafe {
170 pam_ffi::pam_end( 170 pam_ffi::pam_end(
171 self.handle.0, 171 self.handle.0,
172 ErrorCode::result_to_c(self.last_return.get()), 172 ErrorCode::result_to_c(self.last_return.get()),
188 } 188 }
189 }; 189 };
190 } 190 }
191 191
192 impl PamShared for LibPamHandle { 192 impl PamShared for LibPamHandle {
193 fn log(&self, level: Level, entry: &str) { 193 fn log(&self, level: Level, loc: Location<'_>, entry: &str) {
194 let entry = match CString::new(entry).or_else(|_| CString::new(dbg!(entry))) { 194 let entry = match CString::new(entry).or_else(|_| CString::new(dbg!(entry))) {
195 Ok(cstr) => cstr, 195 Ok(cstr) => cstr,
196 _ => return, 196 _ => return,
197 }; 197 };
198 #[cfg(pam_impl = "linux-pam")] 198 #[cfg(pam_impl = "linux-pam")]
199 { 199 {
200 _ = loc;
200 // SAFETY: We're calling this function with a known value. 201 // SAFETY: We're calling this function with a known value.
201 unsafe { 202 unsafe {
202 pam_ffi::pam_syslog(self, level as c_int, "%s\0".as_ptr().cast(), entry.as_ptr()) 203 pam_ffi::pam_syslog(self, level as c_int, "%s\0".as_ptr().cast(), entry.as_ptr())
203 } 204 }
204 } 205 }
205 #[cfg(pam_impl = "openpam")] 206 #[cfg(pam_impl = "openpam")]
206 { 207 {
208 let func = CString::new(loc.function).unwrap_or(CString::default());
207 // SAFETY: We're calling this function with a known value. 209 // SAFETY: We're calling this function with a known value.
208 unsafe { 210 unsafe {
209 pam_ffi::openpam_log(self, level as c_int, "%s\0".as_ptr().cast(), entry.as_ptr()) 211 pam_ffi::_openpam_log(level as c_int, func.as_ptr(), "%s\0".as_ptr().cast(), entry.as_ptr())
210 } 212 }
211 } 213 }
212 } 214 }
213 215
214 fn username(&mut self, prompt: Option<&str>) -> Result<String> { 216 fn username(&mut self, prompt: Option<&str>) -> Result<String> {
380 fn split<T>(result: &Result<T>) -> Result<()> { 382 fn split<T>(result: &Result<T>) -> Result<()> {
381 result.as_ref().map(drop).map_err(|&e| e) 383 result.as_ref().map(drop).map_err(|&e| e)
382 } 384 }
383 385
384 impl PamShared for OwnedLibPamHandle<'_> { 386 impl PamShared for OwnedLibPamHandle<'_> {
385 delegate!(fn log(&self, level: Level, entry: &str) -> ()); 387 delegate!(fn log(&self, level: Level, location: Location<'_>, entry: &str) -> ());
386 delegate!(fn environ(&self) -> impl EnvironMap); 388 delegate!(fn environ(&self) -> impl EnvironMap);
387 delegate!(fn environ_mut(&mut self) -> impl EnvironMapMut); 389 delegate!(fn environ_mut(&mut self) -> impl EnvironMapMut);
388 delegate!(fn username(&mut self, prompt: Option<&str>) -> Result<String>); 390 delegate!(fn username(&mut self, prompt: Option<&str>) -> Result<String>);
389 delegate!(get = user_item, set = set_user_item); 391 delegate!(get = user_item, set = set_user_item);
390 delegate!(get = service, set = set_service); 392 delegate!(get = service, set = set_service);