From 6b89e0dcb0d3a513d548fb38c08d4b66a353f364 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Mon, 30 Jan 2023 13:33:22 +0000 Subject: Basic pam_syslog error reporting --- src/lib.rs | 34 ++++++++++++++++++++++++++++++---- src/pam.rs | 7 +++++++ src/syslog.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 src/syslog.rs diff --git a/src/lib.rs b/src/lib.rs index 3ffbb69..42a9c1b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,14 +3,16 @@ mod pam; mod passwd; +mod syslog; use cap_std::fs::{Dir, OpenOptions}; use pam::PAMHandle; -use std::ffi::{c_char, c_int, CStr}; +use std::ffi::{c_char, c_int, CStr, CString}; use std::io::{ErrorKind, Write}; use std::panic; use std::path::Path; use std::process; +use syslog::{Facility, Level, Priority}; fn create_and_open_dir + ?Sized>( d: &Dir, @@ -32,10 +34,34 @@ impl From for SessionError { } } +const PRIORITY: Priority = Priority { + level: Level::Debug, + facility: Facility::Auth, +}; + fn open_session(h: &PAMHandle, mountpoint: &str) -> Result<(), SessionError> { - let user = h.get_user::(None).or(Err(SessionError))?; - let uid = passwd::get_uid_by_name(&user).ok_or(SessionError)?; - let uid = uid.to_string(); + let user = match h.get_user::(None) { + Ok(user) => user, + Err(e) => { + if let Ok(message) = + CString::new(format!("Failure to get username: {e}")) + { + h.syslog(PRIORITY, &message); + } + return Err(SessionError); + } + }; + let uid = match passwd::get_uid_by_name(&user) { + Some(uid) => uid.to_string(), + None => { + if let Ok(message) = + CString::new(format!("Failure to map user {user:?} to passwd entry")) + { + h.syslog(PRIORITY, &message); + } + return Err(SessionError); + } + }; let d = Dir::open_ambient_dir(mountpoint, cap_std::ambient_authority())?; let d = create_and_open_dir(&d, "user")?; let d = create_and_open_dir(&d, &uid)?; diff --git a/src/pam.rs b/src/pam.rs index 81d543e..7905a92 100644 --- a/src/pam.rs +++ b/src/pam.rs @@ -1,3 +1,4 @@ +use crate::syslog::Priority; use core::marker::{PhantomData, PhantomPinned}; use std::ffi::{c_char, c_int, CStr, CString}; @@ -17,6 +18,7 @@ extern "C" { user: &*const c_char, prompt: *const c_char, ) -> c_int; + fn pam_syslog(pamh: *const PAMHandle, priority: c_int, fmt: *const c_char, ...); } impl PAMHandle { @@ -37,4 +39,9 @@ impl PAMHandle { e => Err(e), } } + pub fn syslog + ?Sized>(&self, priority: Priority, entry: &S) { + let Ok(fmt) = CString::new("%s") else { return }; + let entry = entry.as_ref(); + unsafe { pam_syslog(self, priority.into(), fmt.as_ptr(), entry.as_ptr()) } + } } diff --git a/src/syslog.rs b/src/syslog.rs new file mode 100644 index 0000000..65c8283 --- /dev/null +++ b/src/syslog.rs @@ -0,0 +1,48 @@ +use std::ffi::c_int; + +#[rustfmt::skip] +pub enum Level { + Emergency = 0, + Alert = 1, + Critical = 2, + Error = 3, + Warning = 4, + Notice = 5, + Info = 6, + Debug = 7, +} + +#[rustfmt::skip] +pub enum Facility { + Kernel = 0 << 3, + User = 1 << 3, + Mail = 2 << 3, + Daemon = 3 << 3, + Auth = 4 << 3, + Syslog = 5 << 3, + Lpr = 6 << 3, + News = 7 << 3, + Uucp = 8 << 3, + Cron = 9 << 3, + AuthPriv = 10 << 3, + Ftp = 11 << 3, + Local0 = 12 << 3, + Local1 = 13 << 3, + Local2 = 14 << 3, + Local3 = 15 << 3, + Local4 = 16 << 3, + Local5 = 17 << 3, + Local6 = 18 << 3, + Local7 = 19 << 3, +} + +pub struct Priority { + pub level: Level, + pub facility: Facility, +} + +impl Into for Priority { + fn into(self) -> c_int { + self.level as c_int | self.facility as c_int + } +} -- cgit v1.2.3-54-g00ecf