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 + ?Sized>( &self, prompt: Option<&S>, ) -> Result { 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), } } }