comparison src/libpam/environ.rs @ 130:80c07e5ab22f

Transfer over (almost) completely to using libpam-sys. This reimplements everything in nonstick on top of the new -sys crate. We don't yet use libpam-sys's helpers for binary message payloads. Soon.
author Paul Fisher <paul@pfish.zone>
date Tue, 01 Jul 2025 06:11:43 -0400
parents 49d9e2b5c189
children
comparison
equal deleted inserted replaced
129:5b2de52dd8b2 130:80c07e5ab22f
1 use crate::constants::{ErrorCode, Result}; 1 use crate::constants::{ErrorCode, Result};
2 use crate::environ::{EnvironMap, EnvironMapMut}; 2 use crate::environ::{EnvironMap, EnvironMapMut};
3 use crate::libpam::memory::CHeapString; 3 use crate::libpam::memory::CHeapString;
4 use crate::libpam::{memory, pam_ffi, LibPamHandle}; 4 use crate::libpam::{memory, LibPamHandle};
5 use std::ffi::{c_char, CStr, CString, OsStr, OsString}; 5 use std::ffi::{c_char, CStr, CString, OsStr, OsString};
6 use std::marker::PhantomData; 6 use std::marker::PhantomData;
7 use std::os::unix::ffi::{OsStrExt, OsStringExt}; 7 use std::os::unix::ffi::{OsStrExt, OsStringExt};
8 use std::ptr; 8 use std::ptr;
9 use std::ptr::NonNull; 9 use std::ptr::NonNull;
18 18
19 impl LibPamHandle { 19 impl LibPamHandle {
20 fn environ_get(&self, key: &OsStr) -> Option<OsString> { 20 fn environ_get(&self, key: &OsStr) -> Option<OsString> {
21 let key = CString::new(key.as_bytes()).ok()?; 21 let key = CString::new(key.as_bytes()).ok()?;
22 // SAFETY: We are a valid handle and are calling with a good key. 22 // SAFETY: We are a valid handle and are calling with a good key.
23 unsafe { 23 unsafe { copy_env(libpam_sys::pam_getenv(self.0.as_ref(), key.as_ptr())) }
24 copy_env(pam_ffi::pam_getenv(
25 (self as *const LibPamHandle).cast_mut(),
26 key.as_ptr(),
27 ))
28 }
29 } 24 }
30 25
31 fn environ_set(&mut self, key: &OsStr, value: Option<&OsStr>) -> Result<Option<OsString>> { 26 fn environ_set(&mut self, key: &OsStr, value: Option<&OsStr>) -> Result<Option<OsString>> {
32 let old = self.environ_get(key); 27 let old = self.environ_get(key);
33 if old.is_none() && value.is_none() { 28 if old.is_none() && value.is_none() {
42 result.push(b'='); 37 result.push(b'=');
43 result.extend(value.as_bytes()); 38 result.extend(value.as_bytes());
44 } 39 }
45 let put = CString::new(result).map_err(|_| ErrorCode::ConversationError)?; 40 let put = CString::new(result).map_err(|_| ErrorCode::ConversationError)?;
46 // SAFETY: This is a valid handle and a valid environment string. 41 // SAFETY: This is a valid handle and a valid environment string.
47 ErrorCode::result_from(unsafe { pam_ffi::pam_putenv(self, put.as_ptr()) })?; 42 ErrorCode::result_from(unsafe { libpam_sys::pam_putenv(self.0.as_mut(), put.as_ptr()) })?;
48 Ok(old) 43 Ok(old)
49 } 44 }
50 45
51 fn environ_iter(&self) -> Result<impl Iterator<Item = (OsString, OsString)>> { 46 fn environ_iter(&self) -> Result<impl Iterator<Item = (OsString, OsString)>> {
52 // SAFETY: This is a valid PAM handle. It will return valid data. 47 // SAFETY: This is a valid PAM handle. It will return valid data.
53 unsafe { 48 unsafe {
54 NonNull::new(pam_ffi::pam_getenvlist( 49 NonNull::new(libpam_sys::pam_getenvlist(self.0.as_ref()))
55 (self as *const LibPamHandle).cast_mut(), 50 .map(|ptr| EnvList::from_ptr(ptr.cast()))
56 )) 51 .ok_or(ErrorCode::BufferError)
57 .map(|ptr| EnvList::from_ptr(ptr.cast()))
58 .ok_or(ErrorCode::BufferError)
59 } 52 }
60 } 53 }
61 } 54 }
62 55
63 /// Copies the data of the given C string pointer to an OsString, 56 /// Copies the data of the given C string pointer to an OsString,