config: Add general.source_profile

This adds a system-wide toggle for whether the system profile should be
sourced by /bin/sh before running the command. Note that the command
will still be run with /bin/sh, regardless of profile sourcing.

The option defaults to true for now.

Example usage:

	[general]
	source_profile = false
This commit is contained in:
Kenny Levinsen
2020-11-15 17:41:17 +01:00
parent 4c2a2e89d4
commit 8fea33c476
5 changed files with 67 additions and 17 deletions

View File

@@ -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<ConfigSession>,
}
@@ -91,6 +97,9 @@ fn parse_old_config(config: &HashMap<&str, HashMap<&str, &str>>) -> Result<Confi
user: greeter_user,
command: greeter,
},
general: ConfigGeneral {
source_profile: true,
},
initial_session: None,
})
}
@@ -150,9 +159,23 @@ fn parse_new_config(config: &HashMap<&str, HashMap<&str, &str>>) -> Result<Confi
None => 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,
})
}

View File

@@ -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<SessionChild, Error> {
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);

View File

@@ -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 {

View File

@@ -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(())

View File

@@ -40,6 +40,7 @@ pub enum ParentToSessionChild {
user: String,
authenticate: bool,
tty: TerminalMode,
source_profile: bool,
},
PamResponse {
resp: Option<String>,
@@ -80,14 +81,16 @@ 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)? {
let (service, class, user, authenticate, tty, source_profile) =
match ParentToSessionChild::recv(sock)? {
ParentToSessionChild::InitiateLogin {
service,
class,
user,
authenticate,
tty,
} => (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()),
};
@@ -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!(
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()?;