Compare commits

1 Commits

Author SHA1 Message Date
208cd4a687 call pam_end from within the child session, not the parent
this allows modules like pam_cap to configure the capability bits of the
session process, particularly the ambient capability set.

further details/precedent can be found here:
- <https://github.com/shadow-maint/shadow/pull/408>
- <https://bugzilla.kernel.org/show_bug.cgi?id=214377>
2024-01-30 09:17:13 +00:00

View File

@@ -1,4 +1,4 @@
use std::{env, ffi::CString, os::unix::net::UnixDatagram};
use std::{env, ffi::CString, io::Write as _, os::unix::net::UnixDatagram};
use nix::{
sys::wait::waitpid,
@@ -123,6 +123,11 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
msg => return Err(format!("expected InitiateLogin or Cancel, got: {:?}", msg).into()),
};
println!("worker fn start (stdout)");
eprintln!("worker fn start (stderr)");
std::io::stdout().flush();
std::io::stderr().flush();
let conv = Box::pin(SessionConv::new(sock));
let mut pam = PamSession::start(service, user, conv)?;
@@ -242,6 +247,11 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
let pamenvlist = pam.getenvlist()?;
let envvec = pamenvlist.to_vec();
println!("about to fork (stdout)");
eprintln!("about to fork (stderr)");
std::io::stdout().flush();
std::io::stderr().flush();
// PAM is weird and gets upset if you exec from the process that opened
// the session, registering it automatically as a log-out. Thus, we must
// exec in a new child.
@@ -252,6 +262,11 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
// accidentally using '?'. The process *must* exit from within
// this match arm.
println!("entered fork (stdout)");
eprintln!("entered fork (stderr)");
std::io::stdout().flush();
std::io::stderr().flush();
// Drop privileges to target user
initgroups(&cusername, user.gid).expect("unable to init groups");
setgid(user.gid).expect("unable to set GID");
@@ -264,8 +279,19 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
// Change working directory
if let Err(e) = env::set_current_dir(user.dir) {
eprintln!("unable to set working directory: {}", e);
std::io::stderr().flush();
}
if let Err(e) = pam.end() {
eprintln!("pam.end failed: {}", e);
std::io::stderr().flush();
}
println!("called pam.end (stdout)");
eprintln!("called pam.end (stderr)");
std::io::stdout().flush();
std::io::stderr().flush();
// Run
let cpath = CString::new("/bin/sh").unwrap();
execve(
@@ -310,7 +336,6 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
// inner-most child.
pam.close_session(PamFlag::NONE)?;
pam.setcred(PamFlag::DELETE_CRED)?;
pam.end()?;
Ok(())
}