diff --git a/greetd/src/config/mod.rs b/greetd/src/config/mod.rs index c4cf6b3..3e77e76 100644 --- a/greetd/src/config/mod.rs +++ b/greetd/src/config/mod.rs @@ -35,9 +35,15 @@ pub struct ConfigTerminal { pub vt: VtSelection, } +#[derive(Debug, Eq, PartialEq, Default)] +pub struct ConfigGeneral { + pub source_profile: bool, +} + #[derive(Debug, Eq, PartialEq, Default)] pub struct ConfigFile { pub terminal: ConfigTerminal, + pub general: ConfigGeneral, pub default_session: ConfigSession, pub initial_session: Option, } @@ -91,6 +97,9 @@ fn parse_old_config(config: &HashMap<&str, HashMap<&str, &str>>) -> Result>) -> Result Err("no terminal specified"), }?; + let general = match config.get("general") { + Some(section) => ConfigGeneral { + source_profile: section + .get("source_profile") + .unwrap_or(&"true") + .parse() + .map_err(|e| format!("could not parse source_profile: {}", e))?, + }, + None => ConfigGeneral { + source_profile: true, + }, + }; + Ok(ConfigFile { initial_session, default_session, + general, terminal, }) } diff --git a/greetd/src/context.rs b/greetd/src/context.rs index 42067dc..a12f9e1 100644 --- a/greetd/src/context.rs +++ b/greetd/src/context.rs @@ -40,6 +40,7 @@ pub struct Context { greeter_service: String, pam_service: String, term_mode: TerminalMode, + source_profile: bool, } impl Context { @@ -49,6 +50,7 @@ impl Context { greeter_service: String, pam_service: String, term_mode: TerminalMode, + source_profile: bool, ) -> Context { Context { inner: RwLock::new(ContextInner { @@ -61,6 +63,7 @@ impl Context { greeter_service, pam_service, term_mode, + source_profile, } } @@ -76,7 +79,14 @@ impl Context { ) -> Result { let mut scheduled_session = Session::new_external()?; scheduled_session - .initiate(&service, class, user, false, &self.term_mode) + .initiate( + &service, + class, + user, + false, + &self.term_mode, + self.source_profile, + ) .await?; loop { match scheduled_session.get_state().await { @@ -162,7 +172,14 @@ impl Context { }; session_set .session - .initiate(&self.pam_service, "user", &username, true, &self.term_mode) + .initiate( + &self.pam_service, + "user", + &username, + true, + &self.term_mode, + self.source_profile, + ) .await?; let mut session = Some(session_set); diff --git a/greetd/src/server.rs b/greetd/src/server.rs index 45e9a0d..b094ced 100644 --- a/greetd/src/server.rs +++ b/greetd/src/server.rs @@ -221,6 +221,7 @@ pub async fn main(config: Config) -> Result<(), Error> { greeter_service.to_string(), service.to_string(), term_mode.clone(), + config.file.general.source_profile, )); if let Some(s) = config.file.initial_session { diff --git a/greetd/src/session/interface.rs b/greetd/src/session/interface.rs index d6f6e8c..7614de0 100644 --- a/greetd/src/session/interface.rs +++ b/greetd/src/session/interface.rs @@ -137,6 +137,7 @@ impl Session { user: &str, authenticate: bool, term_mode: &TerminalMode, + source_profile: bool, ) -> Result<(), Error> { let msg = ParentToSessionChild::InitiateLogin { service: service.to_string(), @@ -144,6 +145,7 @@ impl Session { user: user.to_string(), authenticate, tty: term_mode.clone(), + source_profile, }; msg.send(&mut self.sock).await?; Ok(()) diff --git a/greetd/src/session/worker.rs b/greetd/src/session/worker.rs index 9687374..8b87ac8 100644 --- a/greetd/src/session/worker.rs +++ b/greetd/src/session/worker.rs @@ -40,6 +40,7 @@ pub enum ParentToSessionChild { user: String, authenticate: bool, tty: TerminalMode, + source_profile: bool, }, PamResponse { resp: Option, @@ -80,17 +81,19 @@ impl SessionChildToParent { /// responsible for the entirety of the session setup and execution. It is /// started by Session::start. fn worker(sock: &UnixDatagram) -> Result<(), Error> { - let (service, class, user, authenticate, tty) = match ParentToSessionChild::recv(sock)? { - ParentToSessionChild::InitiateLogin { - service, - class, - user, - authenticate, - tty, - } => (service, class, user, authenticate, tty), - ParentToSessionChild::Cancel => return Err("cancelled".into()), - msg => return Err(format!("expected InitiateLogin or Cancel, got: {:?}", msg).into()), - }; + let (service, class, user, authenticate, tty, source_profile) = + match ParentToSessionChild::recv(sock)? { + ParentToSessionChild::InitiateLogin { + service, + class, + user, + authenticate, + tty, + source_profile, + } => (service, class, user, authenticate, tty, source_profile), + ParentToSessionChild::Cancel => return Err("cancelled".into()), + msg => return Err(format!("expected InitiateLogin or Cancel, got: {:?}", msg).into()), + }; let conv = Box::pin(SessionConv::new(sock)); let mut pam = PamSession::start(&service, &user, conv)?; @@ -206,10 +209,14 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> { // Prepare some strings in C format that we'll need. let cusername = CString::new(username)?; - let command = format!( - "[ -f /etc/profile ] && . /etc/profile; [ -f $HOME/.profile ] && . $HOME/.profile; exec {}", - cmd.join(" ") - ); + let command = if source_profile { + format!( + "[ -f /etc/profile ] && . /etc/profile; [ -f $HOME/.profile ] && . $HOME/.profile; exec {}", + cmd.join(" ") + ) + } else { + format!("exec {}", cmd.join(" ")) + }; // Extract PAM environment for use with execve below. let pamenvlist = pam.getenvlist()?;