feat: allow to set defaut environment variables when opening a new session
This commit was merged in pull request #2.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "dysm-rs"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
authors = ["Dany LE"]
|
||||
description = "Diya Session Manager"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
# PAM service
|
||||
# the pam service used for authentication
|
||||
# if not specified, default to diya
|
||||
pam_service = "diya"
|
||||
|
||||
# Default session command
|
||||
@@ -14,6 +15,7 @@ pam_service = "diya"
|
||||
# any session ruining. Often, this default session will be a login
|
||||
# session that handles the user input and send user
|
||||
# credentials to the daemon via Dbus message
|
||||
# this configuration is mandatory
|
||||
default_session_command = "/usr/bin/diyac -x /usr/bin/diya-login-shell"
|
||||
|
||||
# default session user
|
||||
@@ -23,12 +25,21 @@ default_session_user = "xdg"
|
||||
|
||||
# if false keep only one session at a time
|
||||
# open a new session will close any previously opened session
|
||||
# default true, optional
|
||||
# default true (if not specified), optional
|
||||
enable_multiple_session = false
|
||||
|
||||
# User session command
|
||||
# The command to run to start a user session after the
|
||||
# login session is successful
|
||||
# the logged in user will own this session
|
||||
|
||||
# this configuration is mandatory
|
||||
user_session_command = "/usr/bin/diyac -x /usr/bin/diya-shell"
|
||||
|
||||
# setting environment variables
|
||||
# when opening a session, optional
|
||||
[session.envars]
|
||||
# format key = string value
|
||||
# example
|
||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=/tmp/dbus-1"
|
||||
DBUS_SESSION_BUS_PID = "3598"
|
||||
|
||||
|
||||
39
src/auth.rs
39
src/auth.rs
@@ -35,6 +35,7 @@ use nix::unistd::execvpe;
|
||||
use nix::unistd::setgroups;
|
||||
use nix::unistd::User;
|
||||
use nix::unistd::{getgrouplist, initgroups, setgid, setuid};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr;
|
||||
@@ -196,6 +197,7 @@ pub trait Session {
|
||||
///
|
||||
/// - `&self` - Object that implement this trait
|
||||
/// - `command` (`&str`) - Command to executed in a new user session
|
||||
/// - `envars` (`&HashMap<String, String>`) - environment variable for the new session
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@@ -205,7 +207,11 @@ pub trait Session {
|
||||
///
|
||||
/// Any error raised during session opening
|
||||
///
|
||||
fn run(&self, command: &str) -> Result<(), Box<dyn std::error::Error>>;
|
||||
fn run(
|
||||
&self,
|
||||
command: &str,
|
||||
envars: &HashMap<String, String>,
|
||||
) -> Result<(), Box<dyn std::error::Error>>;
|
||||
|
||||
/// End the currently running session
|
||||
///
|
||||
@@ -234,6 +240,7 @@ trait DropPrivilege {
|
||||
///
|
||||
/// - `&self` - Object that define this trait
|
||||
/// - `command` (`&str`) - Command that will be executed un the user session after privilege dropping
|
||||
/// - `envars` (`&HashMap<String, String>`) - environment variable for the new session
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
@@ -242,7 +249,11 @@ trait DropPrivilege {
|
||||
/// # Errors
|
||||
/// Any error
|
||||
///
|
||||
fn drop_and_run(&self, command: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn drop_and_run(
|
||||
&self,
|
||||
command: &str,
|
||||
envars: &HashMap<String, String>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
DEBUG!("Run command: {} as user: {}", command, self.username());
|
||||
let user =
|
||||
User::from_name(self.username())?.ok_or(ERR!("Unknown user {}", self.username()))?;
|
||||
@@ -258,8 +269,12 @@ trait DropPrivilege {
|
||||
let arg_c = CString::new("-c")?;
|
||||
let arg_cmd = CString::new(command)?;
|
||||
let args = vec![arg0.as_c_str(), arg_c.as_c_str(), arg_cmd.as_c_str()];
|
||||
let env_user = CString::new(format!("USER={}", self.username()))?;
|
||||
let envs = vec![env_user.as_c_str()];
|
||||
|
||||
let mut envs_c_string = vec![CString::new(format!("USER={}", self.username()))?];
|
||||
for (k, v) in envars {
|
||||
envs_c_string.push(CString::new(format!("{}={}", k, v))?);
|
||||
}
|
||||
let envs: Vec<&CStr> = envs_c_string.iter().map(|e| e.as_c_str()).collect();
|
||||
execvpe(shell.as_c_str(), &args, &envs)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -511,8 +526,12 @@ impl Session for AnonymousSession {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&self, command: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
self.drop_and_run(command)
|
||||
fn run(
|
||||
&self,
|
||||
command: &str,
|
||||
envars: &HashMap<String, String>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
self.drop_and_run(command, envars)
|
||||
}
|
||||
|
||||
fn end(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
@@ -535,10 +554,14 @@ impl Session for PamSession {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&self, command: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn run(
|
||||
&self,
|
||||
command: &str,
|
||||
envars: &HashMap<String, String>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
self.pam_set_credentials(PAM_ESTABLISH_CRED)?
|
||||
.pam_open_session()?
|
||||
.drop_and_run(command)
|
||||
.drop_and_run(command, envars)
|
||||
}
|
||||
|
||||
fn end(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//! the `Display` trait for easy debugging and logging.
|
||||
use crate::INFO;
|
||||
use core::fmt;
|
||||
use std::path::PathBuf;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
use toml::Value;
|
||||
|
||||
/// Configuration
|
||||
@@ -25,6 +25,8 @@ pub struct Configuration {
|
||||
user_session_command: String,
|
||||
/// flag to enable multiple session
|
||||
enable_multiple_session: bool,
|
||||
/// Session environment variables
|
||||
session_envars: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Configuration {
|
||||
@@ -77,6 +79,23 @@ impl Configuration {
|
||||
.get("enable_multiple_session")
|
||||
.and_then(Value::as_bool)
|
||||
.unwrap_or(true),
|
||||
session_envars: table
|
||||
.get("session")
|
||||
.and_then(Value::as_table)
|
||||
.and_then(|table| table.get("envars"))
|
||||
.and_then(Value::as_table)
|
||||
.and_then(|table| {
|
||||
Some(
|
||||
table
|
||||
.into_iter()
|
||||
.filter_map(|(k, v)| {
|
||||
v.as_str()
|
||||
.and_then(|value| Some((k.to_string(), value.to_string())))
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.unwrap_or(HashMap::new()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -120,6 +139,14 @@ impl Configuration {
|
||||
pub fn enable_multiple_session(&self) -> bool {
|
||||
self.enable_multiple_session
|
||||
}
|
||||
|
||||
/// Session default environment variables
|
||||
///
|
||||
/// # Returs
|
||||
/// HashMap<String, String>
|
||||
pub fn session_envars(&self) -> &HashMap<String, String> {
|
||||
&self.session_envars
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Configuration {
|
||||
@@ -141,6 +168,10 @@ impl fmt::Display for Configuration {
|
||||
" - Enable multiple session: {}",
|
||||
self.enable_multiple_session
|
||||
)?;
|
||||
writeln!(f, " - Session environment variables:")?;
|
||||
for (k, v) in &self.session_envars {
|
||||
writeln!(f, " + {} = '{}'", k, v)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ impl SessionManager {
|
||||
Ok(()) => {
|
||||
DEBUG!("Authenticate success");
|
||||
invocation.return_value(Some(&Variant::tuple_from_iter([true.to_variant()])));
|
||||
if ! self.config.enable_multiple_session() {
|
||||
if !self.config.enable_multiple_session() {
|
||||
self.drop_all_sessions();
|
||||
}
|
||||
match self.open_session(self.config.user_session_command(), &session) {
|
||||
@@ -445,7 +445,9 @@ impl SessionManager {
|
||||
Ok(child)
|
||||
}
|
||||
ForkResult::Child => {
|
||||
session.run(command).expect("This should not happend");
|
||||
session
|
||||
.run(command, self.config.session_envars())
|
||||
.expect("This should not happend");
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
||||
12
src/tests.rs
12
src/tests.rs
@@ -20,4 +20,16 @@ fn test_configuration_loading() {
|
||||
"/usr/bin/diyac -x /usr/bin/diya-shell"
|
||||
);
|
||||
assert_eq!(config.enable_multiple_session(), false);
|
||||
|
||||
assert_eq!(
|
||||
config
|
||||
.session_envars()
|
||||
.get("DBUS_SESSION_BUS_ADDRESS")
|
||||
.unwrap(),
|
||||
"unix:path=/tmp/dbus-1"
|
||||
);
|
||||
assert_eq!(
|
||||
config.session_envars().get("DBUS_SESSION_BUS_PID").unwrap(),
|
||||
"3598"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user