diff src/libpam/handle.rs @ 157:0099f2f79f86

Switch logging interface to accept fmt::Arguments. This means that we don't have to format arguments eagerly when logging; an implementation could choose to discard them if it wanted to, avoiding allocations and expensive format calls.
author Paul Fisher <paul@pfish.zone>
date Wed, 09 Jul 2025 16:59:30 -0400
parents 66e662cde087
children 634cd5f2ac8b
line wrap: on
line diff
--- a/src/libpam/handle.rs	Tue Jul 08 01:04:30 2025 -0400
+++ b/src/libpam/handle.rs	Wed Jul 09 16:59:30 2025 -0400
@@ -17,8 +17,8 @@
 use std::ffi::{c_char, c_int, c_void, CString, OsStr, OsString};
 use std::mem::ManuallyDrop;
 use std::os::unix::ffi::OsStrExt;
-use std::ptr;
 use std::ptr::NonNull;
+use std::{fmt, ptr};
 
 /// An owned PAM handle.
 pub struct LibPamTransaction<C: Conversation> {
@@ -223,7 +223,7 @@
 }
 
 impl<C: Conversation> PamShared for LibPamTransaction<C> {
-    delegate!(fn log(&self, level: Level, location: Location<'_>, entry: &str) -> ());
+    delegate!(fn log(&self, level: Level, location: Location<'_>, entry: fmt::Arguments) -> ());
     delegate!(fn environ(&self) -> impl EnvironMap);
     delegate!(fn environ_mut(&mut self) -> impl EnvironMapMut);
     delegate!(fn username(&mut self, prompt: Option<&OsStr>) -> Result<OsString>);
@@ -322,23 +322,28 @@
 }
 
 impl PamShared for LibPamHandle {
-    fn log(&self, level: Level, loc: Location<'_>, entry: &str) {
-        let entry = match CString::new(entry).or_else(|_| CString::new(dbg!(entry))) {
-            Ok(cstr) => cstr,
-            _ => return,
+    fn log(&self, level: Level, loc: Location<'_>, entry: fmt::Arguments) {
+        let entry = match CString::new(entry.to_string()).ok() {
+            Some(e) => e,
+            None => return,
         };
         #[cfg(pam_impl = "LinuxPam")]
         {
             let level = match level {
                 Level::Error => libc::LOG_ERR,
-                Level::Warning => libc::LOG_WARNING,
+                Level::Warn => libc::LOG_WARNING,
                 Level::Info => libc::LOG_INFO,
                 Level::Debug => libc::LOG_DEBUG,
             };
             _ = loc;
             // SAFETY: We're calling this function with a known value.
             unsafe {
-                libpam_sys::pam_syslog(self.raw_ref(), level, "%s\0".as_ptr().cast(), entry.as_ptr())
+                libpam_sys::pam_syslog(
+                    self.raw_ref(),
+                    level,
+                    b"%s\0".as_ptr().cast(),
+                    entry.as_ptr(),
+                )
             }
         }
         #[cfg(pam_impl = "OpenPam")]
@@ -346,7 +351,7 @@
             let func = CString::new(loc.function).unwrap_or(CString::default());
             let level = match level {
                 Level::Error => libpam_sys::PAM_LOG_ERROR,
-                Level::Warning => libpam_sys::PAM_LOG_NOTICE,
+                Level::Warn => libpam_sys::PAM_LOG_NOTICE,
                 Level::Info => libpam_sys::PAM_LOG_VERBOSE,
                 Level::Debug => libpam_sys::PAM_LOG_DEBUG,
             };
@@ -355,7 +360,7 @@
                 libpam_sys::_openpam_log(
                     level as c_int,
                     func.as_ptr(),
-                    "%s\0".as_ptr().cast(),
+                    b"%s\0".as_ptr().cast(),
                     entry.as_ptr(),
                 )
             }