~kennylevinsen/greetd

8fea33c4767a0f16fd70cc53d6d34f7d895cb650 — Kenny Levinsen 14 days ago 4c2a2e8
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
M greetd/src/config/mod.rs => greetd/src/config/mod.rs +23 -0
@@ 36,8 36,14 @@ pub struct ConfigTerminal {
}

#[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,
    })
}

M greetd/src/context.rs => greetd/src/context.rs +19 -2
@@ 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);

M greetd/src/server.rs => greetd/src/server.rs +1 -0
@@ 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 {

M greetd/src/session/interface.rs => greetd/src/session/interface.rs +2 -0
@@ 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(())

M greetd/src/session/worker.rs => greetd/src/session/worker.rs +22 -15
@@ 40,6 40,7 @@ pub enum ParentToSessionChild {
        user: String,
        authenticate: bool,
        tty: TerminalMode,
        source_profile: bool,
    },
    PamResponse {
        resp: Option<String>,


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