summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tomasz@kramkow.ski>2023-01-30 13:33:22 +0000
committerTomasz Kramkowski <tomasz@kramkow.ski>2023-01-30 18:41:42 +0000
commit6b89e0dcb0d3a513d548fb38c08d4b66a353f364 (patch)
tree57904b88909ba15bbca650d2116a1d91e7699086
parentdaf57f99f22cd105bf274cb856ae8e198388748e (diff)
downloadpam_usercg_rust-6b89e0dcb0d3a513d548fb38c08d4b66a353f364.tar.gz
pam_usercg_rust-6b89e0dcb0d3a513d548fb38c08d4b66a353f364.tar.xz
pam_usercg_rust-6b89e0dcb0d3a513d548fb38c08d4b66a353f364.zip
Basic pam_syslog error reporting
-rw-r--r--src/lib.rs34
-rw-r--r--src/pam.rs7
-rw-r--r--src/syslog.rs48
3 files changed, 85 insertions, 4 deletions
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<P: AsRef<Path> + ?Sized>(
d: &Dir,
@@ -32,10 +34,34 @@ impl From<std::io::Error> 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::<CStr>(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::<CStr>(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<S: AsRef<CStr> + ?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<c_int> for Priority {
+ fn into(self) -> c_int {
+ self.level as c_int | self.facility as c_int
+ }
+}