summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs20
-rw-r--r--src/pam.rs39
2 files changed, 49 insertions, 10 deletions
diff --git a/src/lib.rs b/src/lib.rs
index c104a23..3fd0630 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,11 +1,12 @@
// Copyright (C) 2023 Tomasz Kramkowski <tomasz@kramkow.ski>
// SPDX-License-Identifier: MIT
+mod pam;
mod passwd;
use cap_std::fs::{Dir, OpenOptions};
-use pam::module::PamHandle;
-use std::ffi::{c_char, c_int, CString};
+use pam::PAMHandle;
+use std::ffi::{c_char, c_int, CStr};
use std::io::{ErrorKind, Write};
use std::panic;
use std::path::Path;
@@ -31,9 +32,8 @@ impl From<std::io::Error> for SessionError {
}
}
-fn open_session(h: &PamHandle, mountpoint: &str) -> Result<(), SessionError> {
- let user = h.get_user(None).or(Err(SessionError))?;
- let user = CString::new(user).or(Err(SessionError))?;
+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 d = Dir::open_ambient_dir(mountpoint, cap_std::ambient_authority())?;
@@ -52,23 +52,23 @@ const CG_MOUNT: &str = "/sys/fs/cgroup";
#[no_mangle]
pub extern "C" fn pam_sm_open_session(
- h: &mut PamHandle,
+ h: &mut PAMHandle,
_flags: c_int,
_argc: c_int,
_argv: *const *const c_char,
) -> c_int {
match panic::catch_unwind(|| open_session(h, CG_MOUNT)) {
- Ok(Ok(())) => 0,
- _ => 14,
+ Ok(Ok(())) => pam::SUCCESS,
+ _ => pam::SESSION_ERR,
}
}
#[no_mangle]
pub extern "C" fn pam_sm_close_session(
- _h: &mut PamHandle,
+ _h: &mut PAMHandle,
_flags: c_int,
_argc: c_int,
_argv: *const *const c_char,
) -> c_int {
- 0
+ pam::SUCCESS
}
diff --git a/src/pam.rs b/src/pam.rs
new file mode 100644
index 0000000..17e4590
--- /dev/null
+++ b/src/pam.rs
@@ -0,0 +1,39 @@
+use core::marker::{PhantomData, PhantomPinned};
+use std::ffi::{c_char, c_int, CStr, CString};
+
+#[repr(C)]
+pub struct PAMHandle {
+ _data: [u8; 0],
+ _marker: PhantomData<(*mut u8, PhantomPinned)>,
+}
+
+pub const SUCCESS: c_int = 0;
+pub const SESSION_ERR: c_int = 14;
+
+extern "C" {
+ fn pam_get_user(
+ pamh: *const PAMHandle,
+ user: &*const c_char,
+ prompt: *const c_char,
+ ) -> c_int;
+}
+
+impl PAMHandle {
+ pub fn get_user<S: AsRef<CStr> + ?Sized>(
+ &self,
+ prompt: Option<&S>,
+ ) -> Result<CString, c_int> {
+ let ptr: *const c_char = std::ptr::null_mut();
+ let prompt = match prompt {
+ Some(prompt) => prompt.as_ref().as_ptr(),
+ None => core::ptr::null(),
+ };
+ match unsafe { pam_get_user(self, &ptr, prompt) } {
+ SUCCESS if !ptr.is_null() => {
+ let cstr = unsafe { CStr::from_ptr(ptr) };
+ Ok(CString::from(cstr))
+ }
+ e => Err(e),
+ }
+ }
+}