Fix readonly check (#496)

This commit is contained in:
Firstyear 2021-06-27 11:30:40 +10:00 committed by GitHub
parent 35d32bc5dd
commit 1b146bd00d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 8 deletions

View file

@ -40,6 +40,8 @@ use kanidm_unix_common::cache::CacheLayer;
use kanidm_unix_common::unix_config::KanidmUnixdConfig;
use kanidm_unix_common::unix_proto::{ClientRequest, ClientResponse, TaskRequest, TaskResponse};
use kanidm::utils::file_permissions_readonly;
//=== the codec
type AsyncTaskRequest = (TaskRequest, oneshot::Sender<()>);
@ -406,7 +408,7 @@ async fn main() {
std::process::exit(1);
}
};
if !cfg_meta.permissions().readonly() {
if !file_permissions_readonly(&cfg_meta) {
warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...",
cfg_path_str
);
@ -442,7 +444,7 @@ async fn main() {
std::process::exit(1);
}
};
if !unixd_meta.permissions().readonly() {
if !file_permissions_readonly(&unixd_meta) {
warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...",
unixd_path_str);
}
@ -525,7 +527,7 @@ async fn main() {
);
std::process::exit(1);
}
if i_meta.permissions().readonly() {
if !file_permissions_readonly(&i_meta) {
warn!("WARNING: DB folder permissions on {} indicate it may not be RW. This could cause the server start up to fail!", db_par_path_buf.to_str()
.unwrap_or_else(|| "<db_par_path_buf invalid>")
);

View file

@ -5,6 +5,14 @@ use uuid::{Builder, Uuid};
use rand::distributions::Distribution;
use rand::{thread_rng, Rng};
use std::fs::Metadata;
#[cfg(target_os = "linux")]
use std::os::linux::fs::MetadataExt;
#[cfg(target_os = "macos")]
use std::os::macos::fs::MetadataExt;
use users::{get_current_gid, get_current_uid};
#[derive(Debug)]
pub struct DistinctAlpha;
@ -101,6 +109,29 @@ impl Distribution<char> for DistinctAlpha {
}
}
#[cfg(target_family = "unix")]
pub fn file_permissions_readonly(meta: &Metadata) -> bool {
// Who are we running as?
let cuid = get_current_uid();
let cgid = get_current_gid();
// Who owns the file?
// Who is the group owner of the file?
let f_gid = meta.st_gid();
let f_uid = meta.st_uid();
let f_mode = meta.st_mode();
!(
// If we are the owner, we have write perms as we can alter the DAC rights
cuid == f_uid ||
// If we are the group owner, check the mode bits do not have write.
(cgid == f_gid && (f_mode & 0o0020) != 0) ||
// Finally, check that everyone bits don't have write.
((f_mode & 0o0002) != 0)
)
}
#[cfg(test)]
mod tests {
use crate::utils::{uuid_from_duration, uuid_to_gid_u32};

View file

@ -16,8 +16,11 @@ use users::{get_current_gid, get_current_uid, get_effective_gid, get_effective_u
use serde_derive::Deserialize;
use std::fs::{metadata, File, Metadata};
use std::io::Read;
#[cfg(target_family = "unix")]
use std::os::unix::fs::MetadataExt;
use std::io::Read;
use std::path::Path;
use std::path::PathBuf;
use std::str::FromStr;
@ -28,6 +31,7 @@ use kanidm::core::{
backup_server_core, create_server_core, domain_rename_core, recover_account_core,
reindex_server_core, restore_server_core, vacuum_server_core, verify_server_core,
};
use kanidm::utils::file_permissions_readonly;
use structopt::StructOpt;
@ -118,7 +122,7 @@ async fn main() {
let mut config = Configuration::new();
// Check the permissions are sane.
let cfg_meta = read_file_metadata(&(opt.commonopt().config_path));
if !cfg_meta.permissions().readonly() {
if !file_permissions_readonly(&cfg_meta) {
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...",
opt.commonopt().config_path.to_str().unwrap_or("invalid file path"));
}
@ -159,7 +163,7 @@ async fn main() {
if let Some(i_str) = &(sconfig.tls_chain) {
let i_path = PathBuf::from(i_str.as_str());
let i_meta = read_file_metadata(&i_path);
if !i_meta.permissions().readonly() {
if !file_permissions_readonly(&i_meta) {
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
}
}
@ -167,7 +171,7 @@ async fn main() {
if let Some(i_str) = &(sconfig.tls_key) {
let i_path = PathBuf::from(i_str.as_str());
let i_meta = read_file_metadata(&i_path);
if !i_meta.permissions().readonly() {
if !file_permissions_readonly(&i_meta) {
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
}
@ -195,7 +199,7 @@ async fn main() {
);
std::process::exit(1);
}
if i_meta.permissions().readonly() {
if !file_permissions_readonly(&i_meta) {
eprintln!("WARNING: DB folder permissions on {} indicate it may not be RW. This could cause the server start up to fail!", db_par_path_buf.to_str().unwrap_or("invalid file path"));
}