Server daemon logging and exit codes (#1475)

This commit is contained in:
MinhPhan8803 2023-03-22 23:35:42 -05:00 committed by GitHub
parent 27f54c0e36
commit 00f36f280e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 164 additions and 119 deletions

View file

@ -14,11 +14,11 @@
#[global_allocator] #[global_allocator]
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
use std::fs::{metadata, Metadata}; use std::fs::metadata;
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::exit; use std::process::ExitCode;
use clap::{Args, Parser, Subcommand}; use clap::{Args, Parser, Subcommand};
use kanidmd_core::config::{Configuration, ServerConfig}; use kanidmd_core::config::{Configuration, ServerConfig};
@ -84,53 +84,17 @@ impl KanidmdOpt {
} }
} }
fn read_file_metadata(path: &PathBuf) -> Metadata {
match metadata(path) {
Ok(m) => m,
Err(e) => {
eprintln!(
"Unable to read metadata for '{}' - {:?}",
path.to_str().unwrap_or("invalid file path"),
e
);
std::process::exit(1);
}
}
}
/// Gets the user details if we're running in unix-land
#[cfg(not(target_family = "windows"))]
fn get_user_details_unix() -> (u32, u32) {
let cuid = get_current_uid();
let ceuid = get_effective_uid();
let cgid = get_current_gid();
let cegid = get_effective_gid();
if cuid == 0 || ceuid == 0 || cgid == 0 || cegid == 0 {
eprintln!("WARNING: This is running as uid == 0 (root) which may be a security risk.");
// eprintln!("ERROR: Refusing to run - this process must not operate as root.");
// std::process::exit(1);
}
if cuid != ceuid || cgid != cegid {
eprintln!("{} != {} || {} != {}", cuid, ceuid, cgid, cegid);
eprintln!("ERROR: Refusing to run - uid and euid OR gid and egid must be consistent.");
std::process::exit(1);
}
(cuid, ceuid)
}
/// Get information on the windows username /// Get information on the windows username
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
fn get_user_details_windows() { fn get_user_details_windows() {
eprintln!( debug!(
"Running on windows, current username is: {:?}", "Running on windows, current username is: {:?}",
whoami::username() whoami::username()
); );
} }
#[tokio::main(flavor = "multi_thread")] #[tokio::main(flavor = "multi_thread")]
async fn main() { async fn main() -> ExitCode {
tracing_forest::worker_task() tracing_forest::worker_task()
.set_global(true) .set_global(true)
.set_tag(sketching::event_tagger) .set_tag(sketching::event_tagger)
@ -149,7 +113,25 @@ async fn main() {
// Get info about who we are. // Get info about who we are.
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
let (cuid, ceuid) = get_user_details_unix(); let (cuid, ceuid) = {
let cuid = get_current_uid();
let ceuid = get_effective_uid();
let cgid = get_current_gid();
let cegid = get_effective_gid();
if cuid == 0 || ceuid == 0 || cgid == 0 || cegid == 0 {
warn!("This is running as uid == 0 (root) which may be a security risk.");
// eprintln!("ERROR: Refusing to run - this process must not operate as root.");
// std::process::exit(1);
}
if cuid != ceuid || cgid != cegid {
error!("{} != {} || {} != {}", cuid, ceuid, cgid, cegid);
error!("Refusing to run - uid and euid OR gid and egid must be consistent.");
return ExitCode::FAILURE
}
(cuid, ceuid)
};
// Read cli args, determine if we should backup/restore // Read cli args, determine if we should backup/restore
let opt = KanidmdParser::parse(); let opt = KanidmdParser::parse();
@ -157,28 +139,39 @@ async fn main() {
// print the app version and bail // print the app version and bail
if let KanidmdOpt::Version(_) = &opt.commands { if let KanidmdOpt::Version(_) = &opt.commands {
kanidm_proto::utils::show_version("kanidmd"); kanidm_proto::utils::show_version("kanidmd");
exit(0); return ExitCode::SUCCESS
}; };
let mut config = Configuration::new(); let mut config = Configuration::new();
// Check the permissions are OK. // Check the permissions are OK.
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
{ {
let cfg_meta = read_file_metadata(&(opt.commands.commonopt().config_path)); let cfg_path = &opt.commands.commonopt().config_path;
let cfg_meta = match metadata(cfg_path) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for '{}' - {:?}",
cfg_path.to_str().unwrap_or("invalid file path"),
e
);
return ExitCode::FAILURE
}
};
if !kanidm_lib_file_permissions::readonly(&cfg_meta) { if !kanidm_lib_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 ...", warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...",
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path")); opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path"));
} }
if cfg_meta.mode() & 0o007 != 0 { if cfg_meta.mode() & 0o007 != 0 {
eprintln!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...", warn!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...",
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path") opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path")
); );
} }
if cfg_meta.uid() == cuid || cfg_meta.uid() == ceuid { if cfg_meta.uid() == cuid || cfg_meta.uid() == ceuid {
eprintln!("WARNING: {} owned by the current uid, which may allow file permission changes. This could be a security risk ...", warn!("WARNING: {} owned by the current uid, which may allow file permission changes. This could be a security risk ...",
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path") opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path")
); );
} }
@ -188,8 +181,8 @@ async fn main() {
let sconfig = match ServerConfig::new(&(opt.commands.commonopt().config_path)) { let sconfig = match ServerConfig::new(&(opt.commands.commonopt().config_path)) {
Ok(c) => c, Ok(c) => c,
Err(e) => { Err(e) => {
eprintln!("Config Parse failure {:?}", e); error!("Config Parse failure {:?}", e);
std::process::exit(1); return ExitCode::FAILURE
} }
}; };
// Check the permissions of the files from the configuration. // Check the permissions of the files from the configuration.
@ -198,28 +191,38 @@ async fn main() {
// We can't check the db_path permissions because it may not exist yet! // We can't check the db_path permissions because it may not exist yet!
if let Some(db_parent_path) = db_path.parent() { if let Some(db_parent_path) = db_path.parent() {
if !db_parent_path.exists() { if !db_parent_path.exists() {
eprintln!( warn!(
"DB folder {} may not exist, server startup may FAIL!", "DB folder {} may not exist, server startup may FAIL!",
db_parent_path.to_str().unwrap_or("invalid file path") db_parent_path.to_str().unwrap_or("invalid file path")
); );
} }
let db_par_path_buf = db_parent_path.to_path_buf(); let db_par_path_buf = db_parent_path.to_path_buf();
let i_meta = read_file_metadata(&db_par_path_buf); let i_meta = match metadata(&db_par_path_buf) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for '{}' - {:?}",
&db_par_path_buf.to_str().unwrap_or("invalid file path"),
e
);
return ExitCode::FAILURE
}
};
if !i_meta.is_dir() { if !i_meta.is_dir() {
eprintln!( error!(
"ERROR: Refusing to run - DB folder {} may not be a directory", "ERROR: Refusing to run - DB folder {} may not be a directory",
db_par_path_buf.to_str().unwrap_or("invalid file path") db_par_path_buf.to_str().unwrap_or("invalid file path")
); );
std::process::exit(1); return ExitCode::FAILURE
} }
if kanidm_lib_file_permissions::readonly(&i_meta) { if kanidm_lib_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")); 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("invalid file path"));
} }
#[cfg(not(target_os="windows"))] #[cfg(not(target_os="windows"))]
if i_meta.mode() & 0o007 != 0 { if i_meta.mode() & 0o007 != 0 {
eprintln!("WARNING: DB folder {} has 'everyone' permission bits in the mode. This could be a security risk ...", db_par_path_buf.to_str().unwrap_or("invalid file path")); warn!("WARNING: DB folder {} has 'everyone' permission bits in the mode. This could be a security risk ...", db_par_path_buf.to_str().unwrap_or("invalid file path"));
} }
} }
@ -243,9 +246,9 @@ async fn main() {
KanidmdOpt::Server(_sopt) | KanidmdOpt::ConfigTest(_sopt) => { KanidmdOpt::Server(_sopt) | KanidmdOpt::ConfigTest(_sopt) => {
let config_test = matches!(&opt.commands, KanidmdOpt::ConfigTest(_)); let config_test = matches!(&opt.commands, KanidmdOpt::ConfigTest(_));
if config_test { if config_test {
eprintln!("Running in server configuration test mode ..."); info!("Running in server configuration test mode ...");
} else { } else {
eprintln!("Running in server mode ..."); info!("Running in server mode ...");
}; };
// configuration options that only relate to server mode // configuration options that only relate to server mode
@ -253,23 +256,42 @@ async fn main() {
if let Some(i_str) = &(sconfig.tls_chain) { if let Some(i_str) = &(sconfig.tls_chain) {
let i_path = PathBuf::from(i_str.as_str()); let i_path = PathBuf::from(i_str.as_str());
let i_meta = match metadata(&i_path) {
let i_meta = read_file_metadata(&i_path); Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for '{}' - {:?}",
&i_path.to_str().unwrap_or("invalid file path"),
e
);
return ExitCode::FAILURE
}
};
if !kanidm_lib_file_permissions::readonly(&i_meta) { if !kanidm_lib_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); warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
} }
} }
if let Some(i_str) = &(sconfig.tls_key) { if let Some(i_str) = &(sconfig.tls_key) {
let i_path = PathBuf::from(i_str.as_str()); let i_path = PathBuf::from(i_str.as_str());
let i_meta = read_file_metadata(&i_path); let i_meta = match metadata(&i_path) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for '{}' - {:?}",
&i_path.to_str().unwrap_or("invalid file path"),
e
);
return ExitCode::FAILURE
}
};
if !kanidm_lib_file_permissions::readonly(&i_meta) { if !kanidm_lib_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); warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
} }
#[cfg(not(target_os="windows"))] #[cfg(not(target_os="windows"))]
if i_meta.mode() & 0o007 != 0 { if i_meta.mode() & 0o007 != 0 {
eprintln!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...", i_str); warn!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...", i_str);
} }
} }
@ -325,18 +347,18 @@ async fn main() {
} }
} }
} }
eprintln!("Signal received, shutting down"); info!("Signal received, shutting down");
// Send a broadcast that we are done. // Send a broadcast that we are done.
sctx.shutdown().await; sctx.shutdown().await;
} }
Err(_) => { Err(_) => {
eprintln!("Failed to start server core!"); error!("Failed to start server core!");
// We may need to return an exit code here, but that may take some re-architecting // We may need to return an exit code here, but that may take some re-architecting
// to ensure we drop everything cleanly. // to ensure we drop everything cleanly.
return; return ExitCode::FAILURE
} }
} }
eprintln!("Stopped 🛑 "); info!("Stopped 🛑 ");
} }
@ -344,12 +366,12 @@ async fn main() {
KanidmdOpt::Database { KanidmdOpt::Database {
commands: DbCommands::Backup(bopt), commands: DbCommands::Backup(bopt),
} => { } => {
eprintln!("Running in backup mode ..."); info!("Running in backup mode ...");
let p = match bopt.path.to_str() { let p = match bopt.path.to_str() {
Some(p) => p, Some(p) => p,
None => { None => {
eprintln!("Invalid backup path"); error!("Invalid backup path");
std::process::exit(1); return ExitCode::FAILURE
} }
}; };
backup_server_core(&config, p); backup_server_core(&config, p);
@ -357,12 +379,12 @@ async fn main() {
KanidmdOpt::Database { KanidmdOpt::Database {
commands: DbCommands::Restore(ropt), commands: DbCommands::Restore(ropt),
} => { } => {
eprintln!("Running in restore mode ..."); info!("Running in restore mode ...");
let p = match ropt.path.to_str() { let p = match ropt.path.to_str() {
Some(p) => p, Some(p) => p,
None => { None => {
eprintln!("Invalid restore path"); error!("Invalid restore path");
std::process::exit(1); return ExitCode::FAILURE
} }
}; };
restore_server_core(&config, p).await; restore_server_core(&config, p).await;
@ -370,59 +392,59 @@ async fn main() {
KanidmdOpt::Database { KanidmdOpt::Database {
commands: DbCommands::Verify(_vopt), commands: DbCommands::Verify(_vopt),
} => { } => {
eprintln!("Running in db verification mode ..."); info!("Running in db verification mode ...");
verify_server_core(&config).await; verify_server_core(&config).await;
} }
KanidmdOpt::RecoverAccount(raopt) => { KanidmdOpt::RecoverAccount(raopt) => {
eprintln!("Running account recovery ..."); info!("Running account recovery ...");
recover_account_core(&config, &raopt.name).await; recover_account_core(&config, &raopt.name).await;
} }
KanidmdOpt::Database { KanidmdOpt::Database {
commands: DbCommands::Reindex(_copt), commands: DbCommands::Reindex(_copt),
} => { } => {
eprintln!("Running in reindex mode ..."); info!("Running in reindex mode ...");
reindex_server_core(&config).await; reindex_server_core(&config).await;
} }
KanidmdOpt::DbScan { KanidmdOpt::DbScan {
commands: DbScanOpt::ListIndexes(_), commands: DbScanOpt::ListIndexes(_),
} => { } => {
eprintln!("👀 db scan - list indexes"); info!("👀 db scan - list indexes");
dbscan_list_indexes_core(&config); dbscan_list_indexes_core(&config);
} }
KanidmdOpt::DbScan { KanidmdOpt::DbScan {
commands: DbScanOpt::ListId2Entry(_), commands: DbScanOpt::ListId2Entry(_),
} => { } => {
eprintln!("👀 db scan - list id2entry"); info!("👀 db scan - list id2entry");
dbscan_list_id2entry_core(&config); dbscan_list_id2entry_core(&config);
} }
KanidmdOpt::DbScan { KanidmdOpt::DbScan {
commands: DbScanOpt::ListIndexAnalysis(_), commands: DbScanOpt::ListIndexAnalysis(_),
} => { } => {
eprintln!("👀 db scan - list index analysis"); info!("👀 db scan - list index analysis");
dbscan_list_index_analysis_core(&config); dbscan_list_index_analysis_core(&config);
} }
KanidmdOpt::DbScan { KanidmdOpt::DbScan {
commands: DbScanOpt::ListIndex(dopt), commands: DbScanOpt::ListIndex(dopt),
} => { } => {
eprintln!("👀 db scan - list index content - {}", dopt.index_name); info!("👀 db scan - list index content - {}", dopt.index_name);
dbscan_list_index_core(&config, dopt.index_name.as_str()); dbscan_list_index_core(&config, dopt.index_name.as_str());
} }
KanidmdOpt::DbScan { KanidmdOpt::DbScan {
commands: DbScanOpt::GetId2Entry(dopt), commands: DbScanOpt::GetId2Entry(dopt),
} => { } => {
eprintln!("👀 db scan - get id2 entry - {}", dopt.id); info!("👀 db scan - get id2 entry - {}", dopt.id);
dbscan_get_id2entry_core(&config, dopt.id); dbscan_get_id2entry_core(&config, dopt.id);
} }
KanidmdOpt::DomainSettings { KanidmdOpt::DomainSettings {
commands: DomainSettingsCmds::DomainChange(_dopt), commands: DomainSettingsCmds::DomainChange(_dopt),
} => { } => {
eprintln!("Running in domain name change mode ... this may take a long time ..."); info!("Running in domain name change mode ... this may take a long time ...");
domain_rename_core(&config).await; domain_rename_core(&config).await;
} }
KanidmdOpt::Database { KanidmdOpt::Database {
commands: DbCommands::Vacuum(_copt), commands: DbCommands::Vacuum(_copt),
} => { } => {
eprintln!("Running in vacuum mode ..."); info!("Running in vacuum mode ...");
vacuum_server_core(&config); vacuum_server_core(&config);
} }
KanidmdOpt::HealthCheck(sopt) => { KanidmdOpt::HealthCheck(sopt) => {
@ -478,15 +500,16 @@ async fn main() {
format!("Failed to complete healthcheck: {:?}", error) format!("Failed to complete healthcheck: {:?}", error)
} }
}; };
eprintln!("CRITICAL: {error_message}"); error!("CRITICAL: {error_message}");
exit(1); return ExitCode::FAILURE
} }
}; };
debug!("Request: {req:?}"); debug!("Request: {req:?}");
println!("OK") info!("OK")
} }
KanidmdOpt::Version(_) => {} KanidmdOpt::Version(_) => {}
} }
ExitCode::SUCCESS
}) })
.await; .await
} }

View file

@ -13,6 +13,8 @@
#[macro_use] #[macro_use]
extern crate tracing; extern crate tracing;
use std::process::ExitCode;
use clap::Parser; use clap::Parser;
use futures::executor::block_on; use futures::executor::block_on;
use kanidm_unix_common::client::call_daemon; use kanidm_unix_common::client::call_daemon;
@ -23,14 +25,14 @@ use kanidm_unix_common::unix_proto::{ClientRequest, ClientResponse};
include!("./opt/cache_clear.rs"); include!("./opt/cache_clear.rs");
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> ExitCode {
let opt = CacheClearOpt::parse(); let opt = CacheClearOpt::parse();
if opt.debug { if opt.debug {
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug"); ::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
} }
if opt.version { if opt.version {
println!("{}", kanidm_proto::utils::get_version("kanidm_cache_clear")); println!("{}", kanidm_proto::utils::get_version("kanidm_cache_clear"));
std::process::exit(0); return ExitCode::SUCCESS;
} }
sketching::tracing_subscriber::fmt::init(); sketching::tracing_subscriber::fmt::init();
@ -41,13 +43,13 @@ async fn main() {
Ok(c) => c, Ok(c) => c,
Err(_e) => { Err(_e) => {
error!("Failed to parse {}", DEFAULT_CONFIG_PATH); error!("Failed to parse {}", DEFAULT_CONFIG_PATH);
std::process::exit(1); return ExitCode::FAILURE;
} }
}; };
if !opt.really { if !opt.really {
error!("Are you sure you want to proceed? If so use --really"); error!("Are you sure you want to proceed? If so use --really");
return; return ExitCode::SUCCESS;
} }
let req = ClientRequest::ClearCache; let req = ClientRequest::ClearCache;
@ -62,5 +64,6 @@ async fn main() {
Err(e) => { Err(e) => {
error!("Error -> {:?}", e); error!("Error -> {:?}", e);
} }
} };
ExitCode::SUCCESS
} }

View file

@ -13,6 +13,8 @@
#[macro_use] #[macro_use]
extern crate tracing; extern crate tracing;
use std::process::ExitCode;
use clap::Parser; use clap::Parser;
use futures::executor::block_on; use futures::executor::block_on;
use kanidm_unix_common::client::call_daemon; use kanidm_unix_common::client::call_daemon;
@ -23,7 +25,7 @@ use kanidm_unix_common::unix_proto::{ClientRequest, ClientResponse};
include!("./opt/cache_invalidate.rs"); include!("./opt/cache_invalidate.rs");
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> ExitCode {
let opt = CacheInvalidateOpt::parse(); let opt = CacheInvalidateOpt::parse();
if opt.debug { if opt.debug {
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug"); ::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
@ -33,7 +35,7 @@ async fn main() {
"{}", "{}",
kanidm_proto::utils::get_version("kanidm_cache_invalidate") kanidm_proto::utils::get_version("kanidm_cache_invalidate")
); );
std::process::exit(0); return ExitCode::SUCCESS;
} }
sketching::tracing_subscriber::fmt::init(); sketching::tracing_subscriber::fmt::init();
@ -44,7 +46,7 @@ async fn main() {
Ok(c) => c, Ok(c) => c,
Err(_e) => { Err(_e) => {
error!("Failed to parse {}", DEFAULT_CONFIG_PATH); error!("Failed to parse {}", DEFAULT_CONFIG_PATH);
std::process::exit(1); return ExitCode::FAILURE;
} }
}; };
@ -60,5 +62,6 @@ async fn main() {
Err(e) => { Err(e) => {
error!("Error -> {:?}", e); error!("Error -> {:?}", e);
} }
} };
ExitCode::SUCCESS
} }

View file

@ -14,6 +14,7 @@
extern crate tracing; extern crate tracing;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::ExitCode;
use clap::Parser; use clap::Parser;
use futures::executor::block_on; use futures::executor::block_on;
@ -25,7 +26,7 @@ use kanidm_unix_common::unix_proto::{ClientRequest, ClientResponse};
include!("./opt/ssh_authorizedkeys.rs"); include!("./opt/ssh_authorizedkeys.rs");
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> ExitCode {
let opt = SshAuthorizedOpt::parse(); let opt = SshAuthorizedOpt::parse();
if opt.debug { if opt.debug {
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug"); ::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
@ -35,7 +36,7 @@ async fn main() {
"{}", "{}",
kanidm_proto::utils::get_version("kanidm_ssh_authorizedkeys") kanidm_proto::utils::get_version("kanidm_ssh_authorizedkeys")
); );
std::process::exit(0); return ExitCode::SUCCESS;
} }
sketching::tracing_subscriber::fmt::init(); sketching::tracing_subscriber::fmt::init();
@ -46,7 +47,7 @@ async fn main() {
Ok(c) => c, Ok(c) => c,
Err(e) => { Err(e) => {
error!("Failed to parse {}: {:?}", DEFAULT_CONFIG_PATH, e); error!("Failed to parse {}: {:?}", DEFAULT_CONFIG_PATH, e);
std::process::exit(1); return ExitCode::FAILURE;
} }
}; };
@ -61,7 +62,7 @@ async fn main() {
"Failed to find unix socket at {}, quitting!", "Failed to find unix socket at {}, quitting!",
cfg.sock_path.as_str() cfg.sock_path.as_str()
); );
std::process::exit(1); return ExitCode::FAILURE;
} }
let req = ClientRequest::SshKey(opt.account_id); let req = ClientRequest::SshKey(opt.account_id);
@ -77,5 +78,6 @@ async fn main() {
Err(e) => { Err(e) => {
error!("Error calling kanidm_unixd -> {:?}", e); error!("Error calling kanidm_unixd -> {:?}", e);
} }
} };
ExitCode::SUCCESS
} }

View file

@ -14,6 +14,7 @@ use std::ffi::CString;
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
use std::os::unix::fs::symlink; use std::os::unix::fs::symlink;
use std::path::Path; use std::path::Path;
use std::process::ExitCode;
use std::time::Duration; use std::time::Duration;
use std::{fs, io}; use std::{fs, io};
@ -217,18 +218,13 @@ async fn handle_tasks(stream: UnixStream, cfg: &KanidmUnixdConfig) {
} }
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> ExitCode {
// let cuid = get_current_uid(); // let cuid = get_current_uid();
// let cgid = get_current_gid(); // let cgid = get_current_gid();
// We only need to check effective id // We only need to check effective id
let ceuid = get_effective_uid(); let ceuid = get_effective_uid();
let cegid = get_effective_gid(); let cegid = get_effective_gid();
if ceuid != 0 || cegid != 0 {
eprintln!("Refusing to run - this process *MUST* operate as root.");
std::process::exit(1);
}
tracing_forest::worker_task() tracing_forest::worker_task()
.set_global(true) .set_global(true)
// Fall back to stderr // Fall back to stderr
@ -241,12 +237,17 @@ async fn main() {
) )
}) })
.on(async { .on(async {
if ceuid != 0 || cegid != 0 {
error!("Refusing to run - this process *MUST* operate as root.");
return ExitCode::FAILURE;
}
let unixd_path = Path::new(DEFAULT_CONFIG_PATH); let unixd_path = Path::new(DEFAULT_CONFIG_PATH);
let unixd_path_str = match unixd_path.to_str() { let unixd_path_str = match unixd_path.to_str() {
Some(cps) => cps, Some(cps) => cps,
None => { None => {
error!("Unable to turn unixd_path to str"); error!("Unable to turn unixd_path to str");
std::process::exit(1); return ExitCode::FAILURE;
} }
}; };
@ -254,7 +255,7 @@ async fn main() {
Ok(v) => v, Ok(v) => v,
Err(_) => { Err(_) => {
error!("Failed to parse {}", unixd_path_str); error!("Failed to parse {}", unixd_path_str);
std::process::exit(1); return ExitCode::FAILURE;
} }
}; };
@ -284,6 +285,7 @@ async fn main() {
}; };
server.await; server.await;
ExitCode::SUCCESS
}) })
.await; .await
} }

View file

@ -2,6 +2,8 @@
#[macro_use] #[macro_use]
extern crate tracing; extern crate tracing;
use std::process::ExitCode;
use clap::Parser; use clap::Parser;
use futures::executor::block_on; use futures::executor::block_on;
use kanidm_unix_common::client::call_daemon; use kanidm_unix_common::client::call_daemon;
@ -18,7 +20,7 @@ struct ClientOpt {
} }
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> ExitCode {
let opt = ClientOpt::parse(); let opt = ClientOpt::parse();
if opt.debug { if opt.debug {
::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug"); ::std::env::set_var("RUST_LOG", "kanidm=debug,kanidm_client=debug");
@ -27,11 +29,20 @@ async fn main() {
debug!("Starting PAM auth tester tool ..."); debug!("Starting PAM auth tester tool ...");
let cfg = KanidmUnixdConfig::new() let Ok(cfg) = KanidmUnixdConfig::new()
.read_options_from_optional_config(DEFAULT_CONFIG_PATH) .read_options_from_optional_config(DEFAULT_CONFIG_PATH)
.unwrap_or_else(|_| panic!("Failed to parse {}", DEFAULT_CONFIG_PATH)); else {
error!("Failed to parse {}", DEFAULT_CONFIG_PATH);
return ExitCode::FAILURE
};
let password = rpassword::prompt_password("Enter Unix password: ").unwrap(); let password = match rpassword::prompt_password("Enter Unix password: ") {
Ok(p) => p,
Err(e) => {
error!("Problem getting input password: {}", e);
return ExitCode::FAILURE;
}
};
let req = ClientRequest::PamAuthenticate(opt.account_id.clone(), password); let req = ClientRequest::PamAuthenticate(opt.account_id.clone(), password);
let sereq = ClientRequest::PamAccountAllowed(opt.account_id); let sereq = ClientRequest::PamAccountAllowed(opt.account_id);
@ -55,7 +66,7 @@ async fn main() {
Err(e) => { Err(e) => {
error!("Error -> {:?}", e); error!("Error -> {:?}", e);
} }
} };
match block_on(call_daemon(cfg.sock_path.as_str(), sereq)) { match block_on(call_daemon(cfg.sock_path.as_str(), sereq)) {
Ok(r) => match r { Ok(r) => match r {
@ -76,5 +87,6 @@ async fn main() {
Err(e) => { Err(e) => {
error!("Error -> {:?}", e); error!("Error -> {:?}", e);
} }
} };
ExitCode::SUCCESS
} }