Changing to allow startup without a config file (#2582)

* Changing to allow startup without a config file, using environment variables
This commit is contained in:
James Hodgkinson 2024-02-27 15:40:00 +10:00 committed by GitHub
parent 7b490d73dc
commit 4096b8f02d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 302 additions and 148 deletions

1
Cargo.lock generated
View file

@ -1121,6 +1121,7 @@ dependencies = [
"serde",
"serde_json",
"sketching",
"tempfile",
"tikv-jemallocator",
"tokio",
"tokio-util",

View file

@ -186,6 +186,7 @@ doc/format: ## Format docs and the Kanidm book
-not -path './target/*' \
-not -path './docs/*' \
-not -path '*/.venv/*' -not -path './vendor/*'\
-not -path '*/.*/*' \
-name \*.md \
-exec deno fmt --check $(MARKDOWN_FORMAT_ARGS) "{}" +

View file

@ -26,10 +26,10 @@ The maximum length in seconds that an authentication session may exist for.
The minimum security strength of credentials that may be assigned to this account. In order from
weakest to strongest:
* `any`
* `mfa`
* `passkey`
* `attested_passkey`
- `any`
- `mfa`
- `passkey`
- `attested_passkey`
### Password Minimum Length

View file

@ -4,12 +4,29 @@ In this section we will configure your server and create its container instance.
## Configuring server.toml
You need a configuration file in the volume named `server.toml`. (Within the container it should be
`/data/server.toml`) The following is a commented example configuration.
There are two methods for configuration:
The full options and explanations are in the
1. Providing a configuration file in the volume named `server.toml`. (Within the container it should
be `/data/server.toml`)
2. Using environment variables to specify configuration options (uppercased, prefixed with
`KANIDM_`).
You can use one or both methods, but environment variables take precedence over options specified in
files.The full options and explanations are in the
[kanidmd_core::config::ServerConfig](https://kanidm.github.io/kanidm/master/rustdoc/kanidmd_core/config/struct.ServerConfig.html)
for your particular build.
docs page for your particular build.
<!-- deno-fmt-ignore-start -->
{{#template templates/kani-warning.md
imagepath=images
title=Warning!
text=You MUST set the "domain", "origin", "tls_chain" and "tls_path" options via one method or the other, or the server cannot start!
}}
<!-- deno-fmt-ignore-end -->
The following is a commented example configuration.
```toml
{{#rustdoc_include ../../examples/server_container.toml}}
@ -23,7 +40,7 @@ This example is located in
{{#template templates/kani-warning.md
imagepath=images
title=Warning!
text=You MUST set the `domain` name correctly, aligned with your `origin`, else the server may refuse to start or some features (e.g. webauthn, oauth) may not work correctly!
text=You MUST set the "domain" name correctly, aligned with your "origin", else the server may refuse to start or some features (e.g. WebAuthn, OAuth2) may not work correctly!
}}
<!-- deno-fmt-ignore-end -->
@ -40,8 +57,8 @@ docker run --rm -i -t -v kanidmd:/data \
## Run the Server
Now we can run the server so that it can accept connections. This defaults to using
`-c /data/server.toml`.
Now we can run the server so that it can accept connections. The container defaults to using a
configuration file in `/data/server.toml`.
```bash
docker run -p 443:8443 -v kanidmd:/data kanidm/server:latest
@ -50,12 +67,14 @@ docker run -p 443:8443 -v kanidmd:/data kanidm/server:latest
### Using the NET\_BIND\_SERVICE capability
If you plan to run without using docker port mapping or some other reverse proxy, and your
bindaddress or ldapbindaddress port is less than `1024` you will need the `NET_BIND_SERVICE` in
`bindaddress` or `ldapbindaddress` port is less than `1024` you will need the `NET_BIND_SERVICE` in
docker to allow these port binds. You can add this with `--cap-add` in your docker run command.
```bash
docker run --cap-add NET_BIND_SERVICE --network [host OR macvlan OR ipvlan] \
-v kanidmd:/data kanidm/server:latest
docker run --cap-add NET_BIND_SERVICE \
--network [host OR macvlan OR ipvlan] \
-v kanidmd:/data \
kanidm/server:latest
```
<!-- deno-fmt-ignore-start -->

View file

@ -7,8 +7,6 @@
# - set up a test oauth2 rp (https://kanidm.com)
# - prompt to reset testuser's creds online
set -e
if [ -n "${BUILD_MODE}" ]; then
BUILD_MODE="--${BUILD_MODE}"
else
@ -83,13 +81,16 @@ if [ "${REMOVE_TEST_DB}" -eq 1 ]; then
rm /tmp/kanidm/kanidm.db || true
fi
export KANIDM_CONFIG="../../examples/insecure_server.toml"
IDM_ADMIN_USER="idm_admin@localhost"
echo "Resetting the idm_admin user..."
IDM_ADMIN_PASS=$(${KANIDMD} recover-account idm_admin -o json 2>&1 | grep password | jq -r .password)
IDM_ADMIN_PASS_RAW="$(${KANIDMD} recover-account idm_admin -o json 2>&1)"
IDM_ADMIN_PASS="$(echo "${IDM_ADMIN_PASS_RAW}" | grep password | jq -r .password)"
if [ -z "${IDM_ADMIN_PASS}" ] || [ "${IDM_ADMIN_PASS}" == "null " ]; then
echo "Failed to reset idm_admin password!"
echo "Raw output:"
echo "${IDM_ADMIN_PASS_RAW}"
exit 1
fi
echo "idm_admin pass: '${IDM_ADMIN_PASS}'"

View file

@ -25,16 +25,18 @@ if [ ! -f "run_insecure_dev_server.sh" ]; then
exit 1
fi
export KANIDM_CONFIG="../../examples/insecure_server.toml"
mkdir -p /tmp/kanidm/client_ca
echo "Generating certificates..."
cargo run --bin kanidmd --release cert-generate --config ../../examples/insecure_server.toml
cargo run --bin kanidmd --release cert-generate
echo "Making sure it runs with the DB..."
cargo run --bin kanidmd --release recover-account idm_admin -o json --config ../../examples/insecure_server.toml
cargo run --bin kanidmd --release recover-account idm_admin -o json
echo "Running the server..."
cargo run --bin kanidmd --release server --config ../../examples/insecure_server.toml &
cargo run --bin kanidmd --release server &
KANIDMD_PID=$!
echo "Kanidm PID: ${KANIDMD_PID}"

View file

@ -80,25 +80,27 @@ pub struct TlsConfiguration {
pub client_ca: Option<PathBuf>,
}
/// This is the Server Configuration as read from `server.toml`.
/// This is the Server Configuration as read from `server.toml` or environment variables.
///
/// Fields noted as "REQUIRED" are required for the server to start, even if they show as optional due to how file parsing works.
///
/// If you want to set these as environment variables, prefix them with `KANIDM_` and they will be picked up. This does not include replication peer config.
///
/// NOTE: not all flags or values from the internal [Configuration] object are exposed via this structure
/// to prevent certain settings being set (e.g. integration test modes)
///
/// If you want to set these as environment variables, prefix them with `KANIDM_` and they will be picked up. This doesn't include replication peer config.
#[derive(Debug, Deserialize)]
#[derive(Debug, Deserialize, Default)]
#[serde(deny_unknown_fields)]
pub struct ServerConfig {
/// Kanidm Domain, eg `kanidm.example.com`.
pub domain: String,
/// The user-facing HTTPS URL for this server, eg <https://idm.example.com>
/// *REQUIRED* - Kanidm Domain, eg `kanidm.example.com`.
pub domain: Option<String>,
/// *REQUIRED* - The user-facing HTTPS URL for this server, eg <https://idm.example.com>
// TODO -this should be URL
pub origin: String,
pub origin: Option<String>,
/// File path of the database file
pub db_path: String,
/// The file path to the TLS Certificate Chain
pub db_path: Option<String>,
/// *REQUIRED* - The file path to the TLS Certificate Chain
pub tls_chain: Option<String>,
/// The file path to the TLS Private Key
/// *REQUIRED* - The file path to the TLS Private Key
pub tls_key: Option<String>,
/// The directory path of the client ca and crl dir.
@ -115,7 +117,7 @@ pub struct ServerConfig {
/// If unset, the LDAP server will be disabled.
pub ldapbindaddress: Option<String>,
/// The role of this server, one of write_replica, write_replica_no_ui, read_only_replica
/// The role of this server, one of write_replica, write_replica_no_ui, read_only_replica, defaults to [ServerRole::WriteReplica]
#[serde(default)]
pub role: ServerRole,
/// The log level, one of info, debug, trace. Defaults to "info" if not set.
@ -129,7 +131,8 @@ pub struct ServerConfig {
/// The filesystem type, either "zfs" or "generic". Defaults to "generic" if unset. I you change this, run a database vacuum.
pub db_fs_type: Option<kanidm_proto::internal::FsType>,
/// The path to the "admin" socket, used for local communication when performing cer ain server control tasks.
/// The path to the "admin" socket, used for local communication when performing certain server control tasks. Default is set on build, based on the system target.
pub adminbindpath: Option<String>,
/// Don't touch this unless you know what you're doing!
@ -139,43 +142,101 @@ pub struct ServerConfig {
#[serde(rename = "replication")]
/// Replication configuration, this is a development feature and not yet ready for production use.
pub repl_config: Option<ReplicationConfiguration>,
/// An optional OpenTelemetry collector (GRPC) url to send trace and log data to, eg http://localhost:4317
/// An optional OpenTelemetry collector (GRPC) url to send trace and log data to, eg `http://localhost:4317`. If not set, disables the feature.
pub otel_grpc_url: Option<String>,
}
impl ServerConfig {
/// loads the configuration file from the path specified, then overlays fields from environment variables starting with `KANIDM_``
pub fn new<P: AsRef<Path>>(config_path: P) -> Result<Self, std::io::Error> {
let mut f = File::open(config_path.as_ref()).map_err(|e| {
eprintln!("Unable to open config file [{:?}] 🥺", e);
let diag = kanidm_lib_file_permissions::diagnose_path(config_path.as_ref());
eprintln!("{}", diag);
e
})?;
pub fn new<P: AsRef<Path>>(config_path: Option<P>) -> Result<Self, std::io::Error> {
// start with a base config
let mut config = ServerConfig::default();
let mut contents = String::new();
f.read_to_string(&mut contents).map_err(|e| {
eprintln!("unable to read contents {:?}", e);
let diag = kanidm_lib_file_permissions::diagnose_path(config_path.as_ref());
eprintln!("{}", diag);
e
})?;
if let Some(config_path) = config_path {
// see if we can load it from the config file you asked for
if config_path.as_ref().exists() {
eprintln!("📜 Using config file: {:?}", config_path.as_ref());
let mut f: File = File::open(config_path.as_ref()).map_err(|e| {
eprintln!("Unable to open config file [{:?}] 🥺", e);
let diag = kanidm_lib_file_permissions::diagnose_path(config_path.as_ref());
eprintln!("{}", diag);
e
})?;
let res: ServerConfig = toml::from_str(contents.as_str()).map_err(|e| {
eprintln!(
"Unable to parse config from '{:?}': {:?}",
config_path.as_ref(),
e
);
std::io::Error::new(std::io::ErrorKind::Other, e)
})?;
let mut contents = String::new();
let res = res.try_from_env().map_err(|e| {
f.read_to_string(&mut contents).map_err(|e| {
eprintln!("unable to read contents {:?}", e);
let diag = kanidm_lib_file_permissions::diagnose_path(config_path.as_ref());
eprintln!("{}", diag);
e
})?;
// if we *can* load the config we'll set config to that.
match toml::from_str::<ServerConfig>(contents.as_str()) {
Err(err) => {
eprintln!(
"Unable to parse config from '{:?}': {:?}",
config_path.as_ref(),
err
);
}
Ok(val) => config = val,
};
} else {
eprintln!("📜 No config file found at {:?}", config_path.as_ref());
}
}
// build from the environment variables
let res = config.try_from_env().map_err(|e| {
println!("Failed to use environment variable config: {e}");
std::io::Error::new(std::io::ErrorKind::Other, e)
})?;
Ok(res)
// check if the required fields are there
let mut config_failed = false;
if res.domain.is_none() {
eprintln!("❌ 'domain' field in server configuration is not set, server cannot start!");
config_failed = true;
}
if res.origin.is_none() {
eprintln!("❌ 'origin' field in server configuration is not set, server cannot start!");
config_failed = true;
}
if res.db_path.is_none() {
eprintln!(
"❌ 'db_path' field in server configuration is not set, server cannot start!"
);
config_failed = true;
}
#[cfg(not(test))]
if res.tls_chain.is_none() {
eprintln!(
"❌ 'tls_chain' field in server configuration is not set, server cannot start!"
);
config_failed = true;
}
#[cfg(not(test))]
if res.tls_key.is_none() {
eprintln!(
"❌ 'tls_key' field in server configuration is not set, server cannot start!"
);
config_failed = true;
}
if config_failed {
eprintln!("Failed to parse configuration, server cannot start!");
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"Failed to parse configuration, server cannot start!",
))
} else {
Ok(res)
}
}
/// Updates the ServerConfig from environment variables starting with `KANIDM_`
@ -202,13 +263,13 @@ impl ServerConfig {
match key.replace("KANIDM_", "").as_str() {
"DOMAIN" => {
self.domain = value.to_string();
self.domain = Some(value.to_string());
}
"ORIGIN" => {
self.origin = value.to_string();
self.origin = Some(value.to_string());
}
"DB_PATH" => {
self.origin = value.to_string();
self.origin = Some(value.to_string());
}
"TLS_CHAIN" => {
self.tls_chain = Some(value.to_string());

View file

@ -35,6 +35,7 @@ tokio-util = { workspace = true, features = ["codec"] }
toml = { workspace = true }
opentelemetry = { workspace = true, features = ["logs"] }
opentelemetry_api = { workspace = true, features = ["logs"] }
tempfile = { workspace = true }
tracing = { workspace = true, features = [
"max_level_trace",
"release_max_level_debug",

View file

@ -15,7 +15,6 @@
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
use std::fs::{metadata, File};
use std::str::FromStr;
// This works on both unix and windows.
use fs2::FileExt;
use kanidm_proto::messages::ConsoleOutputMode;
@ -268,19 +267,8 @@ async fn kanidm_main() -> ExitCode {
//we set up a list of these so we can set the log config THEN log out the errors.
let mut config_error: Vec<String> = Vec::new();
let mut config = Configuration::new();
let cfg_path = opt
.commands
.commonopt()
.config_path
.clone()
.or_else(|| PathBuf::from_str(env!("KANIDM_DEFAULT_CONFIG_PATH")).ok());
let Some(cfg_path) = cfg_path else {
eprintln!("Unable to start - can not locate any configuration file");
return ExitCode::FAILURE;
};
let sconfig = match ServerConfig::new(&cfg_path) {
let sconfig = match ServerConfig::new(opt.config_path()) {
Ok(c) => Some(c),
Err(e) => {
config_error.push(format!("Config Parse failure {:?}", e));
@ -365,85 +353,104 @@ async fn kanidm_main() -> ExitCode {
}
};
#[cfg(target_family = "unix")]
{
let cfg_meta = match metadata(&cfg_path) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for '{}' - {:?}",
cfg_path.display(),
e
);
return ExitCode::FAILURE;
if let Some(cfg_path) = opt.config_path() {
#[cfg(target_family = "unix")]
{
if let Some(cfg_meta) = match metadata(&cfg_path) {
Ok(m) => Some(m),
Err(e) => {
error!(
"Unable to read metadata for configuration file '{}' - {:?}",
cfg_path.display(),
e
);
// return ExitCxode::FAILURE;
None
}
} {
if !kanidm_lib_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.to_str().unwrap_or("invalid file path"));
}
if cfg_meta.mode() & 0o007 != 0 {
warn!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...",
cfg_path.to_str().unwrap_or("invalid file path")
);
}
if cfg_meta.uid() == cuid || cfg_meta.uid() == ceuid {
warn!("WARNING: {} owned by the current uid, which may allow file permission changes. This could be a security risk ...",
cfg_path.to_str().unwrap_or("invalid file path")
);
}
}
};
if !kanidm_lib_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.to_str().unwrap_or("invalid file path"));
}
if cfg_meta.mode() & 0o007 != 0 {
warn!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...",
cfg_path.to_str().unwrap_or("invalid file path")
);
}
if cfg_meta.uid() == cuid || cfg_meta.uid() == ceuid {
warn!("WARNING: {} owned by the current uid, which may allow file permission changes. This could be a security risk ...",
cfg_path.to_str().unwrap_or("invalid file path")
);
}
}
// Check the permissions of the files from the configuration.
if let Some(db_path) = sconfig.db_path.clone() {
#[allow(clippy::expect_used)]
let db_pathbuf = PathBuf::from(db_path.as_str());
// We can't check the db_path permissions because it may not exist yet!
if let Some(db_parent_path) = db_pathbuf.parent() {
if !db_parent_path.exists() {
warn!(
"DB folder {} may not exist, server startup may FAIL!",
db_parent_path.to_str().unwrap_or("invalid file path")
);
let diag = kanidm_lib_file_permissions::diagnose_path(&db_pathbuf);
info!(%diag);
}
let db_path = PathBuf::from(sconfig.db_path.as_str());
// We can't check the db_path permissions because it may not exist yet!
if let Some(db_parent_path) = db_path.parent() {
if !db_parent_path.exists() {
warn!(
"DB folder {} may not exist, server startup may FAIL!",
db_parent_path.to_str().unwrap_or("invalid file path")
);
let diag = kanidm_lib_file_permissions::diagnose_path(&db_path);
info!(%diag);
}
let db_par_path_buf = db_parent_path.to_path_buf();
let i_meta = match metadata(&db_par_path_buf) {
Ok(m) => m,
Err(e) => {
let db_par_path_buf = db_parent_path.to_path_buf();
let i_meta = match metadata(&db_par_path_buf) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for database folder '{}' - {:?}",
&db_par_path_buf.to_str().unwrap_or("invalid file path"),
e
);
return ExitCode::FAILURE;
}
};
if !i_meta.is_dir() {
error!(
"Unable to read metadata for '{}' - {:?}",
&db_par_path_buf.to_str().unwrap_or("invalid file path"),
e
"ERROR: Refusing to run - DB folder {} may not be a directory",
db_par_path_buf.to_str().unwrap_or("invalid file path")
);
return ExitCode::FAILURE;
}
};
if !i_meta.is_dir() {
error!(
"ERROR: Refusing to run - DB folder {} may not be a directory",
db_par_path_buf.to_str().unwrap_or("invalid file path")
);
return ExitCode::FAILURE;
}
if kanidm_lib_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("invalid file path"));
}
#[cfg(not(target_os = "windows"))]
if i_meta.mode() & 0o007 != 0 {
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"));
if kanidm_lib_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("invalid file path"));
}
#[cfg(not(target_os = "windows"))]
if i_meta.mode() & 0o007 != 0 {
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"));
}
}
config.update_db_path(&db_path);
} else {
error!("No db_path set in configuration, server startup will FAIL!");
return ExitCode::FAILURE;
}
if let Some(origin) = sconfig.origin.clone() {
config.update_origin(&origin);
} else {
error!("No origin set in configuration, server startup will FAIL!");
return ExitCode::FAILURE;
}
if let Some(domain) = sconfig.domain.clone() {
config.update_domain(&domain);
} else {
error!("No domain set in configuration, server startup will FAIL!");
return ExitCode::FAILURE;
}
config.update_db_path(sconfig.db_path.as_str());
config.update_db_fs_type(&sconfig.db_fs_type);
config.update_origin(sconfig.origin.as_str());
config.update_domain(sconfig.domain.as_str());
config.update_db_arc_size(sconfig.get_db_arc_size());
config.update_role(sconfig.role);
config.update_output_mode(opt.commands.commonopt().output_mode.to_owned().into());
@ -461,7 +468,16 @@ async fn kanidm_main() -> ExitCode {
| KanidmdOpt::HealthCheck(_) => (),
_ => {
// Okay - Lets now create our lock and go.
let klock_path = format!("{}.klock", sconfig.db_path.as_str());
#[allow(clippy::expect_used)]
let klock_path = match sconfig.db_path.clone() {
Some(val) => format!("{}.klock", val),
None => std::env::temp_dir()
.join("kanidmd.klock")
.to_str()
.expect("Unable to create klock path")
.to_string(),
};
let flock = match File::create(&klock_path) {
Ok(flock) => flock,
Err(e) => {
@ -499,7 +515,7 @@ async fn kanidm_main() -> ExitCode {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for '{}' - {:?}",
"Unable to read metadata for TLS chain file '{}' - {:?}",
&i_path.to_str().unwrap_or("invalid file path"),
e
);
@ -520,7 +536,7 @@ async fn kanidm_main() -> ExitCode {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for '{}' - {:?}",
"Unable to read metadata for TLS key file '{}' - {:?}",
&i_path.to_str().unwrap_or("invalid file path"),
e
);

View file

@ -1,6 +1,6 @@
#[derive(Debug, Args)]
struct CommonOpt {
/// Path to the server's configuration file. If it does not exist, it will be created.
/// Path to the server's configuration file.
#[clap(short, long = "config", env = "KANIDM_CONFIG")]
config_path: Option<PathBuf>,
/// Log format (still in very early development)
@ -154,6 +154,58 @@ struct KanidmdParser {
commands: KanidmdOpt,
}
impl KanidmdParser {
/// Returns the configuration path that was specified on the command line, if any.
fn config_path(&self) -> Option<PathBuf> {
match self.commands {
KanidmdOpt::Server(ref c) => c.config_path.clone(),
KanidmdOpt::ConfigTest(ref c) => c.config_path.clone(),
KanidmdOpt::CertGenerate(ref c) => c.config_path.clone(),
KanidmdOpt::RecoverAccount { ref commonopts, .. } => commonopts.config_path.clone(),
KanidmdOpt::ShowReplicationCertificate { ref commonopts, .. } => {
commonopts.config_path.clone()
}
KanidmdOpt::RenewReplicationCertificate { ref commonopts, .. } => {
commonopts.config_path.clone()
}
KanidmdOpt::RefreshReplicationConsumer { ref commonopts, .. } => {
commonopts.config_path.clone()
}
KanidmdOpt::DbScan { ref commands } => match commands {
DbScanOpt::ListIndexes(ref c) => c.config_path.clone(),
DbScanOpt::ListIndex(ref c) => c.commonopts.config_path.clone(),
DbScanOpt::ListId2Entry(ref c) => c.config_path.clone(),
DbScanOpt::GetId2Entry(ref c) => c.commonopts.config_path.clone(),
DbScanOpt::ListIndexAnalysis(ref c) => c.config_path.clone(),
DbScanOpt::QuarantineId2Entry { ref commonopts, .. } => {
commonopts.config_path.clone()
}
DbScanOpt::ListQuarantined { ref commonopts } => commonopts.config_path.clone(),
DbScanOpt::RestoreQuarantined { ref commonopts, .. } => {
commonopts.config_path.clone()
}
},
KanidmdOpt::Database { ref commands } => match commands {
DbCommands::Vacuum(ref c) => c.config_path.clone(),
DbCommands::Backup(ref c) => c.commonopts.config_path.clone(),
DbCommands::Restore(ref c) => c.commonopts.config_path.clone(),
DbCommands::Verify(ref c) => c.config_path.clone(),
DbCommands::Reindex(ref c) => c.config_path.clone(),
},
KanidmdOpt::DomainSettings { ref commands } => match commands {
DomainSettingsCmds::Show { ref commonopts } => commonopts.config_path.clone(),
DomainSettingsCmds::Change { ref commonopts } => commonopts.config_path.clone(),
DomainSettingsCmds::Raise { ref commonopts } => commonopts.config_path.clone(),
DomainSettingsCmds::Remigrate { ref commonopts, .. } => {
commonopts.config_path.clone()
}
},
KanidmdOpt::HealthCheck(ref c) => c.commonopts.config_path.clone(),
KanidmdOpt::Version(ref c) => c.config_path.clone(),
}
}
}
#[derive(Debug, Subcommand)]
enum KanidmdOpt {
#[clap(name = "server")]

View file

@ -432,7 +432,7 @@ pub trait IdmServerTransaction<'a> {
}
},
(None, None) => {
warn!("No client certificate or bearer tokens were supplied");
debug!("No client certificate or bearer tokens were supplied");
Err(OperationError::NotAuthenticated)
}
}
@ -464,7 +464,7 @@ pub trait IdmServerTransaction<'a> {
}
},
(None, None) => {
warn!("No client certificate or bearer tokens were supplied");
debug!("No client certificate or bearer tokens were supplied");
Err(OperationError::NotAuthenticated)
}
}
@ -3810,7 +3810,7 @@ mod tests {
Err(e) => {
error!("A critical error has occurred! {:?}", e);
// Should not occur!
panic!();
panic!("A critical error has occurred! {:?}", e);
}
};

View file

@ -1093,7 +1093,7 @@ fn config_security_checks(cfg_path: &Path) -> bool {
Ok(v) => v,
Err(e) => {
error!(
"Unable to read metadata for '{}' during security checks - {:?}",
"Unable to read metadata for config file '{}' during security checks - {:?}",
cfg_path_str, e
);
return false;