Implement home_mount_path logic (#2894)

This commit is contained in:
Anton Loukianov 2024-07-15 17:34:11 -07:00 committed by GitHub
parent 7373d9abbe
commit 028e7c1694
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 5 deletions

View file

@ -38,6 +38,7 @@
- Merlijn Verstraete (ToxicMushroom)
- Tobias Krischer (tobikris)
- Daniil Egortsev (playhardgopro)
- Anton Loukianov (antonl)
## Acknowledgements

View file

@ -60,6 +60,23 @@ pam_allowed_login_groups = ["posix_group"]
# home_attr = "uuid"
# Controls the prefix that will be appended to the home alias when mounting home directories. Must
# end with a trailing `/`. If unset, defaults to the value of the `home_prefix`.
#
# This is option is useful when implementing a networked home directory layout. A common implementation
# is to configure a networked filesystem that contains user directories mounted at `/u/` (eg /u/$user_uuid)
# and then symlink the mounted directory into /home/$user_name when the user logs in. This can be accomplished
# with a configuration that includes the following:
#
# > home_attr = "uuid"
# > home_alias = "name"
# > home_prefix = "/u/"
# > home_mount_prefix = "/home/"
#
# Default: unset
#
# home_mount_prefix = "/home/"
#
# The default token attribute used for generating symlinks pointing to the user's home
# directory. If set, this will become the value of the home path to nss calls. It is recommended you
@ -115,5 +132,3 @@ pam_allowed_login_groups = ["posix_group"]
# Default: Empty set (no overrides)
# allow_local_account_override = ["admin"]

View file

@ -6,6 +6,7 @@ task_sock_path = "/tmp/kanimd_unidx_task.sock"
pam_allowed_login_groups = ["posix_group"]
# default_shell = "/bin/sh"
# home_prefix = "/home/"
# home_mount_prefix = "/home/"
# home_attr = "uuid"
# home_alias = "spn"
# uid_attr_map = "spn"

View file

@ -35,7 +35,7 @@ use tokio_util::codec::{Decoder, Encoder, Framed};
use walkdir::WalkDir;
#[cfg(all(target_family = "unix", feature = "selinux"))]
use crate::selinux_util;
use kanidm_unix_resolver::selinux_util;
struct TaskCodec;
@ -89,6 +89,7 @@ fn chown(path: &Path, gid: u32) -> Result<(), String> {
fn create_home_directory(
info: &HomeDirectoryInfo,
home_prefix: &str,
home_mount_prefix: &Option<String>,
use_etc_skel: bool,
use_selinux: bool,
) -> Result<(), String> {
@ -96,12 +97,17 @@ fn create_home_directory(
let name = info.name.trim_start_matches('.').replace(['/', '\\'], "");
let home_prefix_path = Path::new(home_prefix);
let home_mount_prefix_path = Path::new(home_mount_prefix.as_deref().unwrap_or(home_prefix));
// Does our home_prefix actually exist?
if !home_prefix_path.exists() || !home_prefix_path.is_dir() {
return Err("Invalid home_prefix from configuration".to_string());
}
if !home_mount_prefix_path.exists() || !home_mount_prefix_path.is_dir() {
return Err("Invalid home_mount_prefix from configuration".to_string());
}
// Actually process the request here.
let hd_path_raw = format!("{}{}", home_prefix, name);
let hd_path = Path::new(&hd_path_raw);
@ -192,8 +198,10 @@ fn create_home_directory(
// Assert the resulting alias path is consistent and correct.
if let Some(pp) = alias_path.parent() {
if pp != home_prefix_path {
return Err("Invalid home directory alias - not within home_prefix".to_string());
if pp != home_mount_prefix_path {
return Err(
"Invalid home directory alias - not within home_mount_prefix".to_string(),
);
}
} else {
return Err("Invalid/Corrupt alias directory path - no prefix found".to_string());
@ -237,6 +245,7 @@ async fn handle_tasks(stream: UnixStream, cfg: &KanidmUnixdConfig) {
let resp = match create_home_directory(
&info,
&cfg.home_prefix,
&cfg.home_mount_prefix,
cfg.use_etc_skel,
cfg.selinux,
) {

View file

@ -25,6 +25,7 @@ struct ConfigInt {
pam_allowed_login_groups: Option<Vec<String>>,
default_shell: Option<String>,
home_prefix: Option<String>,
home_mount_prefix: Option<String>,
home_attr: Option<String>,
home_alias: Option<String>,
use_etc_skel: Option<bool>,
@ -70,6 +71,7 @@ pub struct KanidmUnixdConfig {
pub pam_allowed_login_groups: Vec<String>,
pub default_shell: String,
pub home_prefix: String,
pub home_mount_prefix: Option<String>,
pub home_attr: HomeAttr,
pub home_alias: Option<HomeAttr>,
pub use_etc_skel: bool,
@ -104,6 +106,10 @@ impl Display for KanidmUnixdConfig {
)?;
writeln!(f, "default_shell: {}", self.default_shell)?;
writeln!(f, "home_prefix: {}", self.home_prefix)?;
match self.home_mount_prefix.as_deref() {
Some(val) => writeln!(f, "home_mount_prefix: {}", val)?,
None => writeln!(f, "home_mount_prefix: unset")?,
}
writeln!(f, "home_attr: {}", self.home_attr)?;
match self.home_alias {
Some(val) => writeln!(f, "home_alias: {}", val)?,
@ -147,6 +153,7 @@ impl KanidmUnixdConfig {
pam_allowed_login_groups: Vec::new(),
default_shell: DEFAULT_SHELL.to_string(),
home_prefix: DEFAULT_HOME_PREFIX.to_string(),
home_mount_prefix: None,
home_attr: DEFAULT_HOME_ATTR,
home_alias: DEFAULT_HOME_ALIAS,
use_etc_skel: DEFAULT_USE_ETC_SKEL,
@ -222,6 +229,7 @@ impl KanidmUnixdConfig {
.unwrap_or(self.pam_allowed_login_groups),
default_shell: config.default_shell.unwrap_or(self.default_shell),
home_prefix: config.home_prefix.unwrap_or(self.home_prefix),
home_mount_prefix: config.home_mount_prefix,
home_attr: config
.home_attr
.and_then(|v| match v.as_str() {