From 85ec82832e4f8b4df644088a07d94646dd2197c2 Mon Sep 17 00:00:00 2001 From: William Brown Date: Tue, 4 Aug 2020 12:58:11 +1000 Subject: [PATCH] V large cleanup --- Cargo.lock | 160 +++++++++ kanidm_client/src/lib.rs | 4 +- kanidm_proto/src/lib.rs | 7 + kanidm_proto/src/v1.rs | 1 + kanidm_tools/src/badlist_preprocess.rs | 45 ++- kanidm_tools/src/cli/main.rs | 10 + kanidm_tools/src/ssh_authorizedkeys.rs | 62 +++- kanidm_unix_int/Cargo.toml | 1 + kanidm_unix_int/src/cache.rs | 174 +++++----- kanidm_unix_int/src/cache_clear.rs | 10 + kanidm_unix_int/src/cache_invalidate.rs | 10 + kanidm_unix_int/src/daemon.rs | 5 + kanidm_unix_int/src/daemon_status.rs | 10 + kanidm_unix_int/src/db.rs | 33 +- kanidm_unix_int/src/ssh_authorizedkeys.rs | 9 + kanidm_unix_int/tests/cache_layer_test.rs | 21 +- kanidmd/src/lib/access.rs | 8 +- kanidmd/src/lib/actors/v1_read.rs | 19 +- kanidmd/src/lib/actors/v1_write.rs | 66 ++-- kanidmd/src/lib/async_log.rs | 2 +- kanidmd/src/lib/audit.rs | 47 ++- kanidmd/src/lib/be/idl_arc_sqlite.rs | 13 +- kanidmd/src/lib/be/idl_sqlite.rs | 6 + kanidmd/src/lib/be/mod.rs | 39 ++- kanidmd/src/lib/constants/uuids.rs | 361 ++++++++++++++------- kanidmd/src/lib/core/ctx.rs | 1 + kanidmd/src/lib/core/ldaps.rs | 19 +- kanidmd/src/lib/core/mod.rs | 61 ++-- kanidmd/src/lib/credential/mod.rs | 51 +-- kanidmd/src/lib/entry.rs | 32 +- kanidmd/src/lib/event.rs | 16 +- kanidmd/src/lib/filter.rs | 72 ++-- kanidmd/src/lib/idm/account.rs | 16 +- kanidmd/src/lib/idm/authsession.rs | 12 +- kanidmd/src/lib/idm/group.rs | 5 +- kanidmd/src/lib/idm/radius.rs | 2 +- kanidmd/src/lib/idm/server.rs | 69 ++-- kanidmd/src/lib/idm/unix.rs | 22 +- kanidmd/src/lib/ldap.rs | 9 +- kanidmd/src/lib/lib.rs | 2 +- kanidmd/src/lib/macros.rs | 2 +- kanidmd/src/lib/plugins/attrunique.rs | 4 +- kanidmd/src/lib/plugins/domain.rs | 2 +- kanidmd/src/lib/plugins/memberof.rs | 2 +- kanidmd/src/lib/plugins/password_import.rs | 17 +- kanidmd/src/lib/plugins/protected.rs | 4 +- kanidmd/src/lib/plugins/refint.rs | 2 +- kanidmd/src/lib/plugins/spn.rs | 25 +- kanidmd/src/lib/repl/cid.rs | 7 +- kanidmd/src/lib/schema.rs | 163 ++++------ kanidmd/src/lib/server.rs | 77 ++--- kanidmd/src/lib/utils.rs | 8 +- kanidmd/src/lib/value.rs | 99 +++--- kanidmd/src/server/main.rs | 59 ++-- 54 files changed, 1227 insertions(+), 756 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a4e9ecfd..32a25519c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -390,6 +390,46 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +[[package]] +name = "async-channel" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43de69555a39d52918e2bc33a408d3c0a86c829b212d898f4ca25d21a6387478" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-std" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d68a33ebc8b57800847d00787307f84a562224a14db069b0acefe4c2abbf5d" +dependencies = [ + "async-task", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "kv-log-macro", + "log", + "memchr", + "num_cpus", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "smol", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3" + [[package]] name = "async-trait" version = "0.1.36" @@ -401,6 +441,12 @@ dependencies = [ "syn", ] +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + [[package]] name = "atty" version = "0.2.14" @@ -533,6 +579,20 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "blocking" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2468ff7bf85066b4a3678fede6fe66db31846d753ff0adfbfab2c6a6e81612b" +dependencies = [ + "async-channel", + "atomic-waker", + "futures-lite", + "once_cell", + "parking", + "waker-fn", +] + [[package]] name = "brotli-sys" version = "0.3.2" @@ -598,6 +658,12 @@ dependencies = [ "bytes", ] +[[package]] +name = "cache-padded" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" + [[package]] name = "cargo-husky" version = "1.5.0" @@ -681,6 +747,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "concurrent-queue" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e296417c8154304ac70aceda41f05318f986f7c0c767bcb0a2366fbb890e78e1" +dependencies = [ + "cache-padded", +] + [[package]] name = "const-random" version = "0.1.8" @@ -1066,6 +1141,12 @@ dependencies = [ "version_check 0.9.2", ] +[[package]] +name = "event-listener" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298f00c3b04c1d9b4cb86aefaaa35348af0957d98b30a5306fc635f8e718923d" + [[package]] name = "failure" version = "0.1.8" @@ -1116,6 +1197,12 @@ dependencies = [ "regex", ] +[[package]] +name = "fastrand" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a9cb09840f81cd211e435d00a4e487edd263dc3c8ff815c32dd76ad668ebed" + [[package]] name = "flate2" version = "1.0.16" @@ -1213,6 +1300,21 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" +[[package]] +name = "futures-lite" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe71459749b2e8e66fb95df721b22fa08661ad384a0c5b519e11d3893b4692a" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.5" @@ -1647,6 +1749,7 @@ name = "kanidm_unix_int" version = "1.1.0-alpha" dependencies = [ "actix", + "async-std", "bytes", "env_logger", "futures", @@ -1681,6 +1784,15 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "language-tags" version = "0.2.2" @@ -2126,6 +2238,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "parking" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c" + [[package]] name = "parking_lot" version = "0.10.2" @@ -2628,6 +2746,12 @@ dependencies = [ "parking_lot 0.11.0", ] +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + [[package]] name = "scopeguard" version = "1.1.0" @@ -2777,6 +2901,27 @@ dependencies = [ "serde", ] +[[package]] +name = "smol" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "620cbb3c6e34da57d3a248cda0cd01cd5848164dc062e764e65d06fe3ea7aed5" +dependencies = [ + "async-task", + "blocking", + "concurrent-queue", + "fastrand", + "futures-io", + "futures-util", + "libc", + "once_cell", + "scoped-tls", + "slab", + "socket2", + "wepoll-sys-stjepang", + "winapi 0.3.9", +] + [[package]] name = "socket2" version = "0.3.12" @@ -3373,6 +3518,12 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +[[package]] +name = "waker-fn" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9571542c2ce85ce642e6b58b3364da2fb53526360dfb7c211add4f5c23105ff7" + [[package]] name = "walkdir" version = "2.3.1" @@ -3478,6 +3629,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "wepoll-sys-stjepang" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694" +dependencies = [ + "cc", +] + [[package]] name = "widestring" version = "0.4.2" diff --git a/kanidm_client/src/lib.rs b/kanidm_client/src/lib.rs index 99e4a8e80..71c451297 100644 --- a/kanidm_client/src/lib.rs +++ b/kanidm_client/src/lib.rs @@ -75,7 +75,9 @@ fn read_file_metadata>(path: &P) -> Result { metadata(path).map_err(|e| { error!( "Unable to read metadata for {} - {:?}", - path.as_ref().to_str().unwrap(), + path.as_ref() + .to_str() + .unwrap_or_else(|| "alert: invalid path"), e ); }) diff --git a/kanidm_proto/src/lib.rs b/kanidm_proto/src/lib.rs index 91d51af1f..71232ccc0 100644 --- a/kanidm_proto/src/lib.rs +++ b/kanidm_proto/src/lib.rs @@ -1,5 +1,12 @@ #![deny(warnings)] #![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] #[macro_use] extern crate serde_derive; diff --git a/kanidm_proto/src/v1.rs b/kanidm_proto/src/v1.rs index 68f20f68d..ec761dfcd 100644 --- a/kanidm_proto/src/v1.rs +++ b/kanidm_proto/src/v1.rs @@ -100,6 +100,7 @@ pub enum OperationError { PasswordTooShort(usize), PasswordEmpty, PasswordBadListed, + CryptographyError, } impl PartialEq for OperationError { diff --git a/kanidm_tools/src/badlist_preprocess.rs b/kanidm_tools/src/badlist_preprocess.rs index 24e45b889..fc2eaf152 100644 --- a/kanidm_tools/src/badlist_preprocess.rs +++ b/kanidm_tools/src/badlist_preprocess.rs @@ -1,3 +1,13 @@ +#![deny(warnings)] +#![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] + use std::fs::File; use std::io::prelude::*; use std::io::BufWriter; @@ -38,6 +48,15 @@ fn main() { } info!("Kanidm badlist preprocessor - this may take a long time ..."); + // We open the file early to find out if we can create it or not. + let fileout = match File::create(opt.outfile) { + Ok(f) => f, + Err(e) => { + error!("Failed to create file - {:?}", e); + return; + } + }; + // Build a temp struct for all the pws. // Shellexpand all of these. /* @@ -96,9 +115,15 @@ fn main() { if v.len() < 10 { return false; } - let r = zxcvbn::zxcvbn(v.as_str(), site_opts.as_slice()).expect("Empty Password?"); - // score of 2 or less is too weak and we'd already reject it. - r.score() >= 3 + match zxcvbn::zxcvbn(v.as_str(), site_opts.as_slice()) { + // score of 2 or less is too weak and we'd already reject it. + Ok(r) => r.score() >= 3, + Err(e) => { + error!("zxcvbn unable to process '{}' - {:?}", v.as_str(), e); + error!("adding to badlist anyway ..."); + true + } + } }) .collect(); @@ -110,7 +135,6 @@ fn main() { debug!("Starting file write ..."); // Now we write these out. - let fileout = File::create(opt.outfile).expect("Failed to create file"); let bwrite = BufWriter::new(fileout); // All remaining are either @@ -120,10 +144,17 @@ fn main() { .into_iter() .map(|p| Modify::Present("badlist_password".to_string(), p)) .collect(); - serde_json::to_writer_pretty(bwrite, &modlist).expect("Failed to serialise modlist"); - // println!("next step: kanidm raw modify -D admin '{{\"Eq\": [\"uuid\", \"00000000-0000-0000-0000-ffffff000026\"]}}' "); + match serde_json::to_writer(bwrite, &modlist) { + Ok(_) => + info!("next step: kanidm raw modify -D admin '{{\"Eq\": [\"uuid\", \"00000000-0000-0000-0000-ffffff000026\"]}}' "), + Err(e) => { + error!("Failed to serialised modifications - {:?}", e) + } + } } else { // - printed in json format - serde_json::to_writer_pretty(bwrite, &filt_pwset).expect("Failed to serialise modlist"); + if let Err(e) = serde_json::to_writer_pretty(bwrite, &filt_pwset) { + error!("Failed to serialised badlist - {:?}", e) + } } } diff --git a/kanidm_tools/src/cli/main.rs b/kanidm_tools/src/cli/main.rs index 67691199b..e1c11bcd2 100644 --- a/kanidm_tools/src/cli/main.rs +++ b/kanidm_tools/src/cli/main.rs @@ -1,3 +1,13 @@ +#![deny(warnings)] +#![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] + use kanidm_cli::ClientOpt; use structopt::StructOpt; diff --git a/kanidm_tools/src/ssh_authorizedkeys.rs b/kanidm_tools/src/ssh_authorizedkeys.rs index d21e9117a..087f5d7dd 100644 --- a/kanidm_tools/src/ssh_authorizedkeys.rs +++ b/kanidm_tools/src/ssh_authorizedkeys.rs @@ -1,8 +1,18 @@ +#![deny(warnings)] +#![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] + use std::path::PathBuf; use kanidm_client::KanidmClientBuilder; -use log::debug; +use log::{debug, error}; use structopt::StructOpt; #[derive(Debug, StructOpt)] @@ -34,35 +44,54 @@ fn main() { let config_path: String = shellexpand::tilde("~/.config/kanidm").into_owned(); debug!("Attempting to use config {}", "/etc/kanidm/config"); - let client_builder = KanidmClientBuilder::new() + let client_builder = match KanidmClientBuilder::new() .read_options_from_optional_config("/etc/kanidm/config") .and_then(|cb| { debug!("Attempting to use config {}", config_path); cb.read_options_from_optional_config(config_path) - }) - .expect("Failed to parse config (if present)"); + }) { + Ok(c) => c, + Err(e) => { + error!("Failed to parse config (if present) -- {:?}", e); + std::process::exit(1); + } + }; let client_builder = match &opt.addr { Some(a) => client_builder.address(a.to_string()), None => client_builder, }; - let ca_path: Option<&str> = opt.ca_path.as_ref().map(|p| p.to_str().unwrap()); + let ca_path: Option<&str> = opt.ca_path.as_ref().map(|p| p.to_str()).flatten(); let client_builder = match ca_path { - Some(p) => client_builder - .add_root_certificate_filepath(p) - .expect("Failed to access CA file"), + Some(p) => match client_builder.add_root_certificate_filepath(p) { + Ok(cb) => cb, + Err(e) => { + error!("Failed to add ca certificate -- {:?}", e); + std::process::exit(1); + } + }, None => client_builder, }; - let client = client_builder - .build() - .expect("Failed to build client instance"); + let client = match client_builder.build() { + Ok(c) => c, + Err(e) => { + error!("Failed to build client instance -- {:?}", e); + std::process::exit(1); + } + }; let r = if opt.username == "anonymous" { client.auth_anonymous() } else { - let password = rpassword::prompt_password_stderr("Enter password: ").unwrap(); + let password = match rpassword::prompt_password_stderr("Enter password: ") { + Ok(pw) => pw, + Err(e) => { + error!("Failed to retrieve password - {:?}", e); + std::process::exit(1); + } + }; client.auth_simple_password(opt.username.as_str(), password.as_str()) }; @@ -71,11 +100,8 @@ fn main() { std::process::exit(1); } - let pkeys = client - .idm_account_get_ssh_pubkeys(opt.account_id.as_str()) - .unwrap(); - - for pkey in pkeys { - println!("{}", pkey) + match client.idm_account_get_ssh_pubkeys(opt.account_id.as_str()) { + Ok(pkeys) => pkeys.iter().for_each(|pkey| println!("{}", pkey)), + Err(e) => error!("Failed to retrieve pubkeys - {:?}", e), } } diff --git a/kanidm_unix_int/Cargo.toml b/kanidm_unix_int/Cargo.toml index 4ea1dd2ad..831f63d7c 100644 --- a/kanidm_unix_int/Cargo.toml +++ b/kanidm_unix_int/Cargo.toml @@ -66,6 +66,7 @@ r2d2_sqlite = "0.16" reqwest = { version = "0.10" } users = "0.10" +async-std = "1.6" [features] default = [ "libsqlite3-sys/bundled" ] diff --git a/kanidm_unix_int/src/cache.rs b/kanidm_unix_int/src/cache.rs index 861045144..80da8dd87 100644 --- a/kanidm_unix_int/src/cache.rs +++ b/kanidm_unix_int/src/cache.rs @@ -49,7 +49,7 @@ impl ToString for Id { impl CacheLayer { // TODO: Could consider refactoring this to be better ... #[allow(clippy::too_many_arguments)] - pub fn new( + pub async fn new( // need db path path: &str, // cache timeout @@ -67,7 +67,7 @@ impl CacheLayer { // setup and do a migrate. { - let dbtxn = db.write(); + let dbtxn = db.write().await; dbtxn.migrate()?; dbtxn.commit()?; } @@ -108,34 +108,37 @@ impl CacheLayer { self.set_cachestate(CacheState::Offline).await; } - pub fn clear_cache(&self) -> Result<(), ()> { - let dbtxn = self.db.write(); + pub async fn clear_cache(&self) -> Result<(), ()> { + let dbtxn = self.db.write().await; dbtxn.clear_cache().and_then(|_| dbtxn.commit()) } - pub fn invalidate(&self) -> Result<(), ()> { - let dbtxn = self.db.write(); + pub async fn invalidate(&self) -> Result<(), ()> { + let dbtxn = self.db.write().await; dbtxn.invalidate().and_then(|_| dbtxn.commit()) } - fn get_cached_usertokens(&self) -> Result, ()> { - let dbtxn = self.db.write(); + async fn get_cached_usertokens(&self) -> Result, ()> { + let dbtxn = self.db.write().await; dbtxn.get_accounts() } - fn get_cached_grouptokens(&self) -> Result, ()> { - let dbtxn = self.db.write(); + async fn get_cached_grouptokens(&self) -> Result, ()> { + let dbtxn = self.db.write().await; dbtxn.get_groups() } - fn get_cached_usertoken(&self, account_id: &Id) -> Result<(bool, Option), ()> { + async fn get_cached_usertoken( + &self, + account_id: &Id, + ) -> Result<(bool, Option), ()> { // Account_id could be: // * gidnumber // * name // * spn // * uuid // Attempt to search these in the db. - let dbtxn = self.db.write(); + let dbtxn = self.db.write().await; let r = dbtxn.get_account(&account_id)?; match r { @@ -155,14 +158,17 @@ impl CacheLayer { } } - fn get_cached_grouptoken(&self, grp_id: &Id) -> Result<(bool, Option), ()> { + async fn get_cached_grouptoken( + &self, + grp_id: &Id, + ) -> Result<(bool, Option), ()> { // grp_id could be: // * gidnumber // * name // * spn // * uuid // Attempt to search these in the db. - let dbtxn = self.db.write(); + let dbtxn = self.db.write().await; let r = dbtxn.get_group(&grp_id)?; match r { @@ -182,7 +188,7 @@ impl CacheLayer { } } - fn set_cache_usertoken(&self, token: &UnixUserToken) -> Result<(), ()> { + async fn set_cache_usertoken(&self, token: &UnixUserToken) -> Result<(), ()> { // Set an expiry let ex_time = SystemTime::now() + Duration::from_secs(self.timeout_seconds); let offset = ex_time @@ -191,7 +197,7 @@ impl CacheLayer { error!("time conversion error - ex_time less than epoch? {:?}", e); })?; - let dbtxn = self.db.write(); + let dbtxn = self.db.write().await; // We need to add the groups first token .groups @@ -204,7 +210,7 @@ impl CacheLayer { .and_then(|_| dbtxn.commit()) } - fn set_cache_grouptoken(&self, token: &UnixGroupToken) -> Result<(), ()> { + async fn set_cache_grouptoken(&self, token: &UnixGroupToken) -> Result<(), ()> { // Set an expiry let ex_time = SystemTime::now() + Duration::from_secs(self.timeout_seconds); let offset = ex_time @@ -213,31 +219,31 @@ impl CacheLayer { error!("time conversion error - ex_time less than epoch? {:?}", e); })?; - let dbtxn = self.db.write(); + let dbtxn = self.db.write().await; dbtxn .update_group(token, offset.as_secs()) .and_then(|_| dbtxn.commit()) } - fn delete_cache_usertoken(&self, a_uuid: &str) -> Result<(), ()> { - let dbtxn = self.db.write(); + async fn delete_cache_usertoken(&self, a_uuid: &str) -> Result<(), ()> { + let dbtxn = self.db.write().await; dbtxn.delete_account(a_uuid).and_then(|_| dbtxn.commit()) } - fn delete_cache_grouptoken(&self, g_uuid: &str) -> Result<(), ()> { - let dbtxn = self.db.write(); + async fn delete_cache_grouptoken(&self, g_uuid: &str) -> Result<(), ()> { + let dbtxn = self.db.write().await; dbtxn.delete_group(g_uuid).and_then(|_| dbtxn.commit()) } - fn set_cache_userpassword(&self, a_uuid: &str, cred: &str) -> Result<(), ()> { - let dbtxn = self.db.write(); + async fn set_cache_userpassword(&self, a_uuid: &str, cred: &str) -> Result<(), ()> { + let dbtxn = self.db.write().await; dbtxn .update_account_password(a_uuid, cred) .and_then(|x| dbtxn.commit().map(|_| x)) } - fn check_cache_userpassword(&self, a_uuid: &str, cred: &str) -> Result { - let dbtxn = self.db.write(); + async fn check_cache_userpassword(&self, a_uuid: &str, cred: &str) -> Result { + let dbtxn = self.db.write().await; dbtxn .check_account_password(a_uuid, cred) .and_then(|x| dbtxn.commit().map(|_| x)) @@ -255,7 +261,7 @@ impl CacheLayer { { Ok(n_tok) => { // We have the token! - self.set_cache_usertoken(&n_tok)?; + self.set_cache_usertoken(&n_tok).await?; Ok(Some(n_tok)) } Err(e) => { @@ -296,12 +302,10 @@ impl CacheLayer { // We wele able to contact the server but the entry has been removed, or // is not longer a valid posix account. debug!("entry has been removed or is no longer a valid posix account, clearing from cache ... - eventid {}", opid); - token - .map(|tok| self.delete_cache_usertoken(&tok.uuid)) - // Now an option> - .transpose() - // now result, _> - .map(|_| None) + if let Some(tok) = token { + self.delete_cache_usertoken(&tok.uuid).await?; + }; + Ok(None) } er => { error!("client error -> {:?}", er); @@ -325,7 +329,7 @@ impl CacheLayer { { Ok(n_tok) => { // We have the token! - self.set_cache_grouptoken(&n_tok)?; + self.set_cache_grouptoken(&n_tok).await?; Ok(Some(n_tok)) } Err(e) => { @@ -364,12 +368,10 @@ impl CacheLayer { opid, ) => { debug!("entry has been removed or is no longer a valid posix group, clearing from cache ... - eventid {}", opid); - token - .map(|tok| self.delete_cache_grouptoken(&tok.uuid)) - // Now an option> - .transpose() - // now result, _> - .map(|_| None) + if let Some(tok) = token { + self.delete_cache_grouptoken(&tok.uuid).await?; + }; + Ok(None) } er => { error!("client error -> {:?}", er); @@ -384,7 +386,7 @@ impl CacheLayer { async fn get_usertoken(&self, account_id: Id) -> Result, ()> { debug!("get_usertoken"); // get the item from the cache - let (expired, item) = self.get_cached_usertoken(&account_id).map_err(|e| { + let (expired, item) = self.get_cached_usertoken(&account_id).await.map_err(|e| { debug!("get_usertoken error -> {:?}", e); })?; @@ -431,7 +433,7 @@ impl CacheLayer { async fn get_grouptoken(&self, grp_id: Id) -> Result, ()> { debug!("get_grouptoken"); - let (expired, item) = self.get_cached_grouptoken(&grp_id).map_err(|e| { + let (expired, item) = self.get_cached_grouptoken(&grp_id).await.map_err(|e| { debug!("get_grouptoken error -> {:?}", e); })?; @@ -476,8 +478,8 @@ impl CacheLayer { } } - fn get_groupmembers(&self, uuid: &str) -> Vec { - let dbtxn = self.db.write(); + async fn get_groupmembers(&self, uuid: &str) -> Vec { + let dbtxn = self.db.write().await; dbtxn .get_group_members(uuid) @@ -515,8 +517,8 @@ impl CacheLayer { .to_string() } - pub fn get_nssaccounts(&self) -> Result, ()> { - self.get_cached_usertokens().map(|l| { + pub async fn get_nssaccounts(&self) -> Result, ()> { + self.get_cached_usertokens().await.map(|l| { l.into_iter() .map(|tok| NssUser { homedir: self.token_homedirectory(&tok), @@ -557,32 +559,34 @@ impl CacheLayer { .to_string() } - pub fn get_nssgroups(&self) -> Result, ()> { - self.get_cached_grouptokens().map(|l| { - l.into_iter() - .map(|tok| { - let members = self.get_groupmembers(&tok.uuid); - NssGroup { - name: self.token_gidattr(&tok), - gid: tok.gidnumber, - members, - } - }) - .collect() - }) + pub async fn get_nssgroups(&self) -> Result, ()> { + let l = self.get_cached_grouptokens().await?; + let mut r: Vec<_> = Vec::with_capacity(l.len()); + for tok in l.into_iter() { + let members = self.get_groupmembers(&tok.uuid).await; + r.push(NssGroup { + name: self.token_gidattr(&tok), + gid: tok.gidnumber, + members, + }) + } + Ok(r) } async fn get_nssgroup(&self, grp_id: Id) -> Result, ()> { let token = self.get_grouptoken(grp_id).await?; // Get members set. - Ok(token.map(|tok| { - let members = self.get_groupmembers(&tok.uuid); - NssGroup { - name: self.token_gidattr(&tok), - gid: tok.gidnumber, - members, + match token { + Some(tok) => { + let members = self.get_groupmembers(&tok.uuid).await; + Ok(Some(NssGroup { + name: self.token_gidattr(&tok), + gid: tok.gidnumber, + members, + })) } - })) + None => Ok(None), + } } pub async fn get_nssgroup_name(&self, grp_id: &str) -> Result, ()> { @@ -608,8 +612,8 @@ impl CacheLayer { { Ok(Some(n_tok)) => { debug!("online password check success."); - self.set_cache_usertoken(&n_tok)?; - self.set_cache_userpassword(&n_tok.uuid, cred)?; + self.set_cache_usertoken(&n_tok).await?; + self.set_cache_userpassword(&n_tok.uuid, cred).await?; Ok(Some(true)) } Ok(None) => { @@ -624,10 +628,10 @@ impl CacheLayer { let time = SystemTime::now().add(Duration::from_secs(15)); self.set_cachestate(CacheState::OfflineNextCheck(time)) .await; - token - .as_ref() - .map(|t| self.check_cache_userpassword(&t.uuid, cred)) - .transpose() + match token.as_ref() { + Some(t) => self.check_cache_userpassword(&t.uuid, cred).await.map(Some), + None => Ok(None), + } } ClientError::Http( StatusCode::UNAUTHORIZED, @@ -642,10 +646,10 @@ impl CacheLayer { let time = SystemTime::now().add(Duration::from_secs(15)); self.set_cachestate(CacheState::OfflineNextCheck(time)) .await; - token - .as_ref() - .map(|t| self.check_cache_userpassword(&t.uuid, cred)) - .transpose() + match token.as_ref() { + Some(t) => self.check_cache_userpassword(&t.uuid, cred).await.map(Some), + None => Ok(None), + } } ClientError::Http( StatusCode::BAD_REQUEST, @@ -672,16 +676,22 @@ impl CacheLayer { } } - fn offline_account_authenticate( + async fn offline_account_authenticate( &self, token: &Option, cred: &str, ) -> Result, ()> { debug!("Attempt offline password check"); + match token.as_ref() { + Some(t) => self.check_cache_userpassword(&t.uuid, cred).await.map(Some), + None => Ok(None), + } + /* token .as_ref() - .map(|t| self.check_cache_userpassword(&t.uuid, cred)) + .map(async |t| self.check_cache_userpassword(&t.uuid, cred).await) .transpose() + */ } pub async fn pam_account_allowed(&self, account_id: &str) -> Result, ()> { @@ -710,7 +720,9 @@ impl CacheLayer { cred: &str, ) -> Result, ()> { let state = self.get_cachestate().await; - let (_expired, token) = self.get_cached_usertoken(&Id::Name(account_id.to_string()))?; + let (_expired, token) = self + .get_cached_usertoken(&Id::Name(account_id.to_string())) + .await?; match state { CacheState::Online => { @@ -725,12 +737,12 @@ impl CacheLayer { .await } else { // We are offline, check from the cache if possible. - self.offline_account_authenticate(&token, cred) + self.offline_account_authenticate(&token, cred).await } } _ => { // We are offline, check from the cache if possible. - self.offline_account_authenticate(&token, cred) + self.offline_account_authenticate(&token, cred).await } } } diff --git a/kanidm_unix_int/src/cache_clear.rs b/kanidm_unix_int/src/cache_clear.rs index 6b59c00ca..f3a141543 100644 --- a/kanidm_unix_int/src/cache_clear.rs +++ b/kanidm_unix_int/src/cache_clear.rs @@ -1,3 +1,13 @@ +#![deny(warnings)] +#![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] + #[macro_use] extern crate log; diff --git a/kanidm_unix_int/src/cache_invalidate.rs b/kanidm_unix_int/src/cache_invalidate.rs index 1bc8d7a2d..cbab0c873 100644 --- a/kanidm_unix_int/src/cache_invalidate.rs +++ b/kanidm_unix_int/src/cache_invalidate.rs @@ -1,3 +1,13 @@ +#![deny(warnings)] +#![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] + #[macro_use] extern crate log; diff --git a/kanidm_unix_int/src/daemon.rs b/kanidm_unix_int/src/daemon.rs index 4948cbebe..a7ad1e000 100644 --- a/kanidm_unix_int/src/daemon.rs +++ b/kanidm_unix_int/src/daemon.rs @@ -105,6 +105,7 @@ async fn handle_client( debug!("nssaccounts req"); cachelayer .get_nssaccounts() + .await .map(ClientResponse::NssAccounts) .unwrap_or_else(|_| { error!("unable to enum accounts"); @@ -137,6 +138,7 @@ async fn handle_client( debug!("nssgroups req"); cachelayer .get_nssgroups() + .await .map(ClientResponse::NssGroups) .unwrap_or_else(|_| { error!("unable to enum groups"); @@ -185,6 +187,7 @@ async fn handle_client( debug!("invalidate cache"); cachelayer .invalidate() + .await .map(|_| ClientResponse::Ok) .unwrap_or(ClientResponse::Error) } @@ -192,6 +195,7 @@ async fn handle_client( debug!("clear cache"); cachelayer .clear_cache() + .await .map(|_| ClientResponse::Ok) .unwrap_or(ClientResponse::Error) } @@ -359,6 +363,7 @@ async fn main() { cfg.uid_attr_map, cfg.gid_attr_map, ) + .await .expect("Failed to build cache layer."), ); diff --git a/kanidm_unix_int/src/daemon_status.rs b/kanidm_unix_int/src/daemon_status.rs index f00f4a642..13f9965f2 100644 --- a/kanidm_unix_int/src/daemon_status.rs +++ b/kanidm_unix_int/src/daemon_status.rs @@ -1,3 +1,13 @@ +#![deny(warnings)] +#![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] + #[macro_use] extern crate log; diff --git a/kanidm_unix_int/src/db.rs b/kanidm_unix_int/src/db.rs index 3f00e0588..7464dfb0d 100644 --- a/kanidm_unix_int/src/db.rs +++ b/kanidm_unix_int/src/db.rs @@ -41,8 +41,9 @@ impl Db { }) } - pub fn write(&self) -> DbTxn { - let guard = self.lock.try_lock().expect("Unable to lock"); + #[allow(clippy::expect_used)] + pub async fn write(&self) -> DbTxn<'_> { + let guard = self.lock.lock().await; let conn = self .pool .get() @@ -64,6 +65,7 @@ impl<'a> DbTxn<'a> { ) -> Self { // Start the transaction // debug!("Starting db WR txn ..."); + #[allow(clippy::expect_used)] conn.execute("BEGIN TRANSACTION", NO_PARAMS) .expect("Unable to begin transaction!"); DbTxn { @@ -140,7 +142,10 @@ impl<'a> DbTxn<'a> { pub fn commit(mut self) -> Result<(), ()> { // debug!("Commiting BE txn"); - assert!(!self.committed); + if self.committed { + error!("Invalid state, txn already commited!"); + return Err(()); + } self.committed = true; self.conn @@ -403,7 +408,9 @@ impl<'a> DbTxn<'a> { } pub fn update_account_password(&self, a_uuid: &str, cred: &str) -> Result<(), ()> { - let pw = Password::new(cred); + let pw = Password::new(cred).map_err(|e| { + error!("password error -> {:?}", e); + })?; let dbpw = pw.to_dbpasswordv1(); let data = serde_cbor::to_vec(&dbpw).map_err(|e| { error!("cbor error -> {:?}", e); @@ -462,7 +469,9 @@ impl<'a> DbTxn<'a> { error!("cbor error -> {:?}", e); })?; let pw = Password::try_from(dbpw)?; - Ok(pw.verify(cred)) + pw.verify(cred).map_err(|e| { + error!("password error -> {:?}", e); + }) }) .unwrap_or(Ok(false)); r @@ -664,6 +673,7 @@ impl<'a> Drop for DbTxn<'a> { fn drop(self: &mut Self) { if !self.committed { // debug!("Aborting BE WR txn"); + #[allow(clippy::expect_used)] self.conn .execute("ROLLBACK TRANSACTION", NO_PARAMS) .expect("Unable to rollback transaction! Can not proceed!!!"); @@ -675,6 +685,7 @@ impl<'a> Drop for DbTxn<'a> { mod tests { use super::Db; use crate::cache::Id; + use async_std::task; use kanidm_proto::v1::{UnixGroupToken, UnixUserToken}; const TESTACCOUNT1_PASSWORD_A: &str = "password a for account1 test"; @@ -684,7 +695,7 @@ mod tests { fn test_cache_db_account_basic() { let _ = env_logger::builder().is_test(true).try_init(); let db = Db::new("").expect("failed to create."); - let dbtxn = db.write(); + let dbtxn = task::block_on(db.write()); assert!(dbtxn.migrate().is_ok()); let mut ut1 = UnixUserToken { @@ -767,7 +778,7 @@ mod tests { fn test_cache_db_group_basic() { let _ = env_logger::builder().is_test(true).try_init(); let db = Db::new("").expect("failed to create."); - let dbtxn = db.write(); + let dbtxn = task::block_on(db.write()); assert!(dbtxn.migrate().is_ok()); let mut gt1 = UnixGroupToken { @@ -842,7 +853,7 @@ mod tests { fn test_cache_db_account_group_update() { let _ = env_logger::builder().is_test(true).try_init(); let db = Db::new("").expect("failed to create."); - let dbtxn = db.write(); + let dbtxn = task::block_on(db.write()); assert!(dbtxn.migrate().is_ok()); let gt1 = UnixGroupToken { @@ -909,7 +920,7 @@ mod tests { fn test_cache_db_account_password() { let _ = env_logger::builder().is_test(true).try_init(); let db = Db::new("").expect("failed to create."); - let dbtxn = db.write(); + let dbtxn = task::block_on(db.write()); assert!(dbtxn.migrate().is_ok()); let uuid1 = "0302b99c-f0f6-41ab-9492-852692b0fd16"; @@ -957,7 +968,7 @@ mod tests { fn test_cache_db_group_rename_duplicate() { let _ = env_logger::builder().is_test(true).try_init(); let db = Db::new("").expect("failed to create."); - let dbtxn = db.write(); + let dbtxn = task::block_on(db.write()); assert!(dbtxn.migrate().is_ok()); let mut gt1 = UnixGroupToken { @@ -1012,7 +1023,7 @@ mod tests { fn test_cache_db_account_rename_duplicate() { let _ = env_logger::builder().is_test(true).try_init(); let db = Db::new("").expect("failed to create."); - let dbtxn = db.write(); + let dbtxn = task::block_on(db.write()); assert!(dbtxn.migrate().is_ok()); let mut ut1 = UnixUserToken { diff --git a/kanidm_unix_int/src/ssh_authorizedkeys.rs b/kanidm_unix_int/src/ssh_authorizedkeys.rs index a9739b66b..ce8bc380b 100644 --- a/kanidm_unix_int/src/ssh_authorizedkeys.rs +++ b/kanidm_unix_int/src/ssh_authorizedkeys.rs @@ -1,4 +1,13 @@ #![deny(warnings)] +#![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] + #[macro_use] extern crate log; diff --git a/kanidm_unix_int/tests/cache_layer_test.rs b/kanidm_unix_int/tests/cache_layer_test.rs index d0afd80e0..1e47c3b1b 100644 --- a/kanidm_unix_int/tests/cache_layer_test.rs +++ b/kanidm_unix_int/tests/cache_layer_test.rs @@ -17,6 +17,8 @@ use tokio::runtime::Runtime; use kanidm_client::asynchronous::KanidmAsyncClient; use kanidm_client::{KanidmClient, KanidmClientBuilder}; +use async_std::task; + static PORT_ALLOC: AtomicUsize = AtomicUsize::new(18080); const ADMIN_TEST_PASSWORD: &str = "integration test admin password"; const TESTACCOUNT1_PASSWORD_A: &str = "password a for account1 test"; @@ -76,7 +78,7 @@ fn run_test(fix_fn: fn(&KanidmClient) -> (), test_fn: fn(CacheLayer, KanidmAsync .build_async() .expect("Failed to build client"); - let cachelayer = CacheLayer::new( + let cachelayer = task::block_on(CacheLayer::new( "", // The sqlite db path, this is in memory. 300, rsclient, @@ -86,7 +88,7 @@ fn run_test(fix_fn: fn(&KanidmClient) -> (), test_fn: fn(CacheLayer, KanidmAsync DEFAULT_HOME_ATTR, DEFAULT_UID_ATTR_MAP, DEFAULT_GID_ATTR_MAP, - ) + )) .expect("Failed to build cache layer."); test_fn(cachelayer, client); @@ -213,6 +215,7 @@ fn test_cache_account() { // Finally, check we have "all accounts" in the list. let us = cachelayer .get_nssaccounts() + .await .expect("failed to list all accounts"); assert!(us.len() == 1); }; @@ -254,7 +257,7 @@ fn test_cache_group() { assert!(gt.unwrap().members.len() == 0); // clear cache, go online - assert!(cachelayer.invalidate().is_ok()); + assert!(cachelayer.invalidate().await.is_ok()); cachelayer.attempt_online().await; assert!(cachelayer.test_connection().await); @@ -281,6 +284,7 @@ fn test_cache_group() { // Finally, check we have "all groups" in the list. let gs = cachelayer .get_nssgroups() + .await .expect("failed to list all groups"); assert!(gs.len() == 2); }; @@ -313,7 +317,7 @@ fn test_cache_group_delete() { .expect("failed to delete"); // invalidate cache - assert!(cachelayer.invalidate().is_ok()); + assert!(cachelayer.invalidate().await.is_ok()); // "get it" // should be empty. @@ -352,7 +356,7 @@ fn test_cache_account_delete() { .expect("failed to delete"); // invalidate cache - assert!(cachelayer.invalidate().is_ok()); + assert!(cachelayer.invalidate().await.is_ok()); // "get it" let ut = cachelayer @@ -435,7 +439,10 @@ fn test_cache_account_password() { assert!(a6 == Some(false)); // clear cache - cachelayer.clear_cache().expect("failed to clear cache"); + cachelayer + .clear_cache() + .await + .expect("failed to clear cache"); // test auth good (fail) let a7 = cachelayer @@ -483,7 +490,7 @@ fn test_cache_account_pam_allowed() { .unwrap(); // Invalidate cache to force a refresh - assert!(cachelayer.invalidate().is_ok()); + assert!(cachelayer.invalidate().await.is_ok()); // Should pass let a2 = cachelayer diff --git a/kanidmd/src/lib/access.rs b/kanidmd/src/lib/access.rs index 3926c86f9..3d52dc691 100644 --- a/kanidmd/src/lib/access.rs +++ b/kanidmd/src/lib/access.rs @@ -695,7 +695,7 @@ pub trait AccessControlsTransaction { */ // Now purge the attrs that are NOT in this. - e.reduce_attributes(allowed_attrs) + e.reduce_attributes(&allowed_attrs) }) .collect() } @@ -810,14 +810,14 @@ pub trait AccessControlsTransaction { // existance, and second, we would have failed the mod at schema checking // earlier in the process as these were not correctly type. As a result // we can trust these to be correct here and not to be "None". - Some(v.to_str_unwrap()) + v.to_str() } else { None } } Modify::Removed(a, v) => { if a.as_str() == "class" { - Some(v.to_str_unwrap()) + v.to_str() } else { None } @@ -2018,7 +2018,7 @@ mod tests { ModifyEvent::new_impersonate_entry_ser( JSON_ADMIN_V1, filter_all!(f_eq("name", PartialValue::new_iname("testperson1"))), - modlist!([m_pres("name", &Value::new_iname_s("value"))]), + modlist!([m_pres("name", &Value::new_iname("value"))]), ) }; // Name rem diff --git a/kanidmd/src/lib/actors/v1_read.rs b/kanidmd/src/lib/actors/v1_read.rs index 45107043d..326f9e1d4 100644 --- a/kanidmd/src/lib/actors/v1_read.rs +++ b/kanidmd/src/lib/actors/v1_read.rs @@ -264,7 +264,7 @@ impl Handler for QueryServerReadV1 { match qs_read.search_ext(&mut audit, &srch) { Ok(entries) => { - SearchResult::new(&mut audit, &qs_read, entries).map(|ok_sr| ok_sr.response()) + SearchResult::new(&mut audit, &qs_read, &entries).map(|ok_sr| ok_sr.response()) } Err(e) => Err(e), } @@ -303,7 +303,10 @@ impl Handler for QueryServerReadV1 { let ct = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) - .expect("Clock failure!"); + .map_err(|e| { + ladmin_error!(audit, "Clock Error -> {:?}", e); + OperationError::InvalidState + })?; // Trigger a session clean *before* we take any auth steps. // It's important to do this before to ensure that timeouts on @@ -368,9 +371,10 @@ impl Handler for QueryServerReadV1 { match entries.len() { 0 => Err(OperationError::NoMatchingEntries), 1 => { + #[allow(clippy::expect_used)] let e = entries.pop().expect("Entry length mismatch!!!"); // Now convert to a response, and return - WhoamiResult::new(&mut audit, &qs_read, e, uat) + WhoamiResult::new(&mut audit, &qs_read, &e, uat) .map(|ok_wr| ok_wr.response()) } // Somehow we matched multiple, which should be impossible. @@ -414,7 +418,7 @@ impl Handler for QueryServerReadV1 { ltrace!(audit, "Begin event {:?}", srch); match qs_read.search_ext(&mut audit, &srch) { - Ok(entries) => SearchResult::new(&mut audit, &qs_read, entries) + Ok(entries) => SearchResult::new(&mut audit, &qs_read, &entries) .map(|ok_sr| ok_sr.into_proto_array()), Err(e) => Err(e), } @@ -460,7 +464,7 @@ impl Handler for QueryServerReadV1 { ltrace!(audit, "Begin event {:?}", srch); match qs_read.search_ext(&mut audit, &srch) { - Ok(entries) => SearchResult::new(&mut audit, &qs_read, entries) + Ok(entries) => SearchResult::new(&mut audit, &qs_read, &entries) .map(|ok_sr| ok_sr.into_proto_array()), Err(e) => Err(e), } @@ -877,7 +881,10 @@ impl Handler for QueryServerReadV1 { let ct = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) - .expect("Clock failure!"); + .map_err(|e| { + ladmin_error!(audit, "Clock Error -> {:?}", e); + OperationError::InvalidState + })?; let r = idm_write .auth_unix(&mut audit, &uuae, ct) diff --git a/kanidmd/src/lib/actors/v1_write.rs b/kanidmd/src/lib/actors/v1_write.rs index c44453e93..e8eed0827 100644 --- a/kanidmd/src/lib/actors/v1_write.rs +++ b/kanidmd/src/lib/actors/v1_write.rs @@ -178,14 +178,14 @@ impl IdmGroupUnixExtendMessage { pub fn new( uat: Option, uuid_or_name: String, - gx: GroupUnixExtend, + gx: &GroupUnixExtend, eventid: Uuid, ) -> Self { - let GroupUnixExtend { gidnumber } = gx; + // let GroupUnixExtend { gidnumber } = gx; IdmGroupUnixExtendMessage { uat, uuid_or_name, - gidnumber, + gidnumber: gx.gidnumber, eventid, } } @@ -353,18 +353,16 @@ impl QueryServerWriteV1 { &mut self, audit: &mut AuditScope, uat: Option, - uuid_or_name: String, - proto_ml: ProtoModifyList, + uuid_or_name: &str, + proto_ml: &ProtoModifyList, filter: Filter, ) -> Result<(), OperationError> { let qs_write = self.qs.write(duration_from_epoch_now()); - let target_uuid = qs_write - .name_to_uuid(audit, uuid_or_name.as_str()) - .map_err(|e| { - ladmin_error!(audit, "Error resolving id to target"); - e - })?; + let target_uuid = qs_write.name_to_uuid(audit, uuid_or_name).map_err(|e| { + ladmin_error!(audit, "Error resolving id to target"); + e + })?; let mdf = match ModifyEvent::from_parts(audit, uat, target_uuid, proto_ml, filter, &qs_write) { @@ -386,18 +384,16 @@ impl QueryServerWriteV1 { &mut self, audit: &mut AuditScope, uat: Option, - uuid_or_name: String, - ml: ModifyList, + uuid_or_name: &str, + ml: &ModifyList, filter: Filter, ) -> Result<(), OperationError> { let qs_write = self.qs.write(duration_from_epoch_now()); - let target_uuid = qs_write - .name_to_uuid(audit, uuid_or_name.as_str()) - .map_err(|e| { - ladmin_error!(audit, "Error resolving id to target"); - e - })?; + let target_uuid = qs_write.name_to_uuid(audit, uuid_or_name).map_err(|e| { + ladmin_error!(audit, "Error resolving id to target"); + e + })?; let mdf = match ModifyEvent::from_internal_parts( audit, @@ -535,7 +531,7 @@ impl Handler for QueryServerWriteV1 { || { let qs_write = self.qs.write(duration_from_epoch_now()); - let del = match DeleteEvent::from_parts(&mut audit, msg.uat, msg.filter, &qs_write) + let del = match DeleteEvent::from_parts(&mut audit, msg.uat, &msg.filter, &qs_write) { Ok(d) => d, Err(e) => { @@ -610,7 +606,7 @@ impl Handler for QueryServerWriteV1 { "actors::v1_write::handle", || { let ct = duration_from_epoch_now(); - let mut idms_prox_write = self.idms.proxy_write(ct.clone()); + let mut idms_prox_write = self.idms.proxy_write(ct); // Trigger a session clean *before* we take any auth steps. // It's important to do this before to ensure that timeouts on @@ -737,7 +733,7 @@ impl Handler for QueryServerWriteV1 { "actors::v1_write::handle", || { let ct = duration_from_epoch_now(); - let mut idms_prox_write = self.idms.proxy_write(ct.clone()); + let mut idms_prox_write = self.idms.proxy_write(ct); idms_prox_write.expire_mfareg_sessions(ct); let pce = PasswordChangeEvent::from_idm_account_set_password( @@ -779,7 +775,7 @@ impl Handler for QueryServerWriteV1 { "actors::v1_write::handle", || { let ct = duration_from_epoch_now(); - let mut idms_prox_write = self.idms.proxy_write(ct.clone()); + let mut idms_prox_write = self.idms.proxy_write(ct); idms_prox_write.expire_mfareg_sessions(ct); let target_uuid = idms_prox_write @@ -840,7 +836,7 @@ impl Handler for QueryServerWriteV1 { &mut audit, msg.uat, target_uuid, - msg.attr, + &msg.attr, msg.filter, &qs_write, ) { @@ -891,7 +887,7 @@ impl Handler for QueryServerWriteV1 { &mut audit, msg.uat, target_uuid, - proto_ml, + &proto_ml, msg.filter, &qs_write, ) { @@ -942,7 +938,7 @@ impl Handler for QueryServerWriteV1 { .map(|v| ProtoModify::Present(attr.clone(), v)) .collect(), ); - self.modify_from_parts(&mut audit, uat, uuid_or_name, proto_ml, filter) + self.modify_from_parts(&mut audit, uat, &uuid_or_name, &proto_ml, filter) } ); self.log.send(Some(audit)).map_err(|_| { @@ -981,7 +977,7 @@ impl Handler for QueryServerWriteV1 { ) .collect(), ); - self.modify_from_parts(&mut audit, uat, uuid_or_name, proto_ml, filter) + self.modify_from_parts(&mut audit, uat, &uuid_or_name, &proto_ml, filter) } ); self.log.send(Some(audit)).map_err(|_| { @@ -1013,7 +1009,7 @@ impl Handler for QueryServerWriteV1 { // than relying on the proto ones. let ml = ModifyList::new_append("ssh_publickey", Value::new_sshkey(tag, key)); - self.modify_from_internal_parts(&mut audit, uat, uuid_or_name, ml, filter) + self.modify_from_internal_parts(&mut audit, uat, &uuid_or_name, &ml, filter) } ); self.log.send(Some(audit)).map_err(|_| { @@ -1056,7 +1052,7 @@ impl Handler for QueryServerWriteV1 { let filter = filter_all!(f_eq("class", PartialValue::new_class("account"))); - self.modify_from_internal_parts(&mut audit, uat, uuid_or_name, ml, filter) + self.modify_from_internal_parts(&mut audit, uat, &uuid_or_name, &ml, filter) } ); self.log.send(Some(audit)).map_err(|_| { @@ -1092,7 +1088,9 @@ impl Handler for QueryServerWriteV1 { )), gidnumber .map(|n| Modify::Present("gidnumber".to_string(), Value::new_uint32(n))), - shell.map(|s| Modify::Present("loginshell".to_string(), Value::new_iutf8(s))), + shell.map(|s| { + Modify::Present("loginshell".to_string(), Value::new_iutf8(s.as_str())) + }), ] .into_iter() .filter_map(|v| v) @@ -1102,7 +1100,7 @@ impl Handler for QueryServerWriteV1 { let filter = filter_all!(f_eq("class", PartialValue::new_class("account"))); - self.modify_from_internal_parts(&mut audit, uat, uuid_or_name, ml, filter) + self.modify_from_internal_parts(&mut audit, uat, &uuid_or_name, &ml, filter) } ); self.log.send(Some(audit)).map_err(|_| { @@ -1146,7 +1144,7 @@ impl Handler for QueryServerWriteV1 { let filter = filter_all!(f_eq("class", PartialValue::new_class("group"))); - self.modify_from_internal_parts(&mut audit, uat, uuid_or_name, ml, filter) + self.modify_from_internal_parts(&mut audit, uat, &uuid_or_name, &ml, filter) } ); self.log.send(Some(audit)).map_err(|_| { @@ -1167,7 +1165,7 @@ impl Handler for QueryServerWriteV1 { "actors::v1_write::handle", || { let ct = duration_from_epoch_now(); - let mut idms_prox_write = self.idms.proxy_write(ct.clone()); + let mut idms_prox_write = self.idms.proxy_write(ct); idms_prox_write.expire_mfareg_sessions(ct); let target_uuid = Uuid::parse_str(msg.uuid_or_name.as_str()).or_else(|_| { @@ -1223,6 +1221,7 @@ impl Handler for QueryServerWriteV1 { .purge_tombstones(&mut audit) .and_then(|_| qs_write.commit(&mut audit)); ladmin_info!(audit, "Purge tombstones result: {:?}", res); + #[allow(clippy::expect_used)] res.expect("Invalid Server State"); } ); @@ -1249,6 +1248,7 @@ impl Handler for QueryServerWriteV1 { .purge_recycled(&mut audit) .and_then(|_| qs_write.commit(&mut audit)); ladmin_info!(audit, "Purge recycled result: {:?}", res); + #[allow(clippy::expect_used)] res.expect("Invalid Server State"); } ); diff --git a/kanidmd/src/lib/async_log.rs b/kanidmd/src/lib/async_log.rs index a55e595bf..54d2c8cd7 100644 --- a/kanidmd/src/lib/async_log.rs +++ b/kanidmd/src/lib/async_log.rs @@ -1,7 +1,7 @@ use crate::audit::AuditScope; use crossbeam::channel::Receiver; -pub fn run(rx: Receiver>) { +pub fn run(rx: &Receiver>) { info!("Log thread started ..."); loop { match rx.recv() { diff --git a/kanidmd/src/lib/audit.rs b/kanidmd/src/lib/audit.rs index 30aff9010..4cf27bcba 100644 --- a/kanidmd/src/lib/audit.rs +++ b/kanidmd/src/lib/audit.rs @@ -309,7 +309,8 @@ struct AuditLog { pub struct PerfEvent { id: String, duration: Option, - contains: Vec, + #[allow(clippy::vec_box)] + contains: Vec>, #[serde(skip_serializing)] parent: Option<&'static mut PerfEvent>, } @@ -322,10 +323,14 @@ impl PerfEvent { .map(|pe| pe.process_inner(opd)) .collect(); contains.sort_unstable(); - let duration = self.duration.as_ref().expect("corrupted perf event"); + let duration = self + .duration + .as_ref() + .copied() + .unwrap_or_else(|| Duration::new(0, 0)); let percent = (duration.as_secs_f64() / opd.as_secs_f64()) * 100.0; PerfProcessed { - duration: *duration, + duration, id: self.id.clone(), percent, contains, @@ -333,7 +338,11 @@ impl PerfEvent { } fn process(&self) -> PerfProcessed { - let duration = self.duration.as_ref().expect("corrupted perf event"); + let duration = self + .duration + .as_ref() + .copied() + .unwrap_or_else(|| Duration::new(0, 0)); let mut contains: Vec<_> = self .contains .iter() @@ -341,7 +350,7 @@ impl PerfEvent { .collect(); contains.sort_unstable(); PerfProcessed { - duration: *duration, + duration, id: self.id.clone(), percent: 100.0, contains, @@ -423,7 +432,8 @@ pub struct AuditScope { pub level: u32, uuid: Uuid, events: Vec, - perf: Vec, + #[allow(clippy::vec_box)] + perf: Vec>, // active perf event #[serde(skip_serializing)] active_perf: Option<&'static mut PerfEvent>, @@ -516,14 +526,20 @@ impl AuditScope { // Does an active event currently exist? if self.active_perf.is_none() { // No, we are a new event. - self.perf.push(PerfEvent { + self.perf.push(Box::new(PerfEvent { id: id.to_string(), duration: None, contains: vec![], parent: None, - }); - // Get a put ptr, we are now the active. - let xref = self.perf.last_mut().expect("perf alloc failure?") as *mut PerfEvent; + })); + // Get a our ptr, we are now the active. + let idx = self.perf.len() - 1; + let xref = self + .perf + // Get the box + .get_unchecked_mut(idx) + // Now the mut ptr to the inner of hte box + .as_mut() as *mut PerfEvent; let mref = &mut (*xref); self.active_perf = Some(mref); // return the mut ptr. @@ -532,15 +548,18 @@ impl AuditScope { // Yes, there is an active event. // get the currennt active ptr let xref = if let Some(ref mut iparent) = self.active_perf { - iparent.contains.push(PerfEvent { + iparent.contains.push(Box::new(PerfEvent { id: id.to_string(), duration: None, contains: vec![], parent: None, - }); - iparent.contains.last_mut().expect("perf alloc failure?") as *mut PerfEvent + })); + + let idx = iparent.contains.len() - 1; + iparent.contains.get_unchecked_mut(idx).as_mut() as *mut PerfEvent } else { - panic!("Invalid parent state"); + #[allow(clippy::unreachable)] + unreachable!("Invalid parent state"); }; // Alloc in the vec, set parnt to active, then get a mut pointer // to ourself, then set ourself as the active. diff --git a/kanidmd/src/lib/be/idl_arc_sqlite.rs b/kanidmd/src/lib/be/idl_arc_sqlite.rs index 22ec20664..72abaab4a 100644 --- a/kanidmd/src/lib/be/idl_arc_sqlite.rs +++ b/kanidmd/src/lib/be/idl_arc_sqlite.rs @@ -518,9 +518,13 @@ impl<'a> IdlArcSqliteWriteTransaction<'a> { idl_cache.iter_mut_mark_clean().try_for_each(|(k, v)| { match v { Some(idl) => db.write_idl(audit, k.a.as_str(), &k.i, k.k.as_str(), idl), + #[allow(clippy::unreachable)] None => { // Due to how we remove items, we always write an empty idl // to the cache, so this should never be none. + // + // If it is none, this means we have memory corruption so we MUST + // panic. unreachable!(); } } @@ -561,14 +565,13 @@ impl<'a> IdlArcSqliteWriteTransaction<'a> { })?; // Undo the caches in the reverse order. - db.commit(audit).and_then(|()| { + db.commit(audit).map(|()| { op_ts_max.commit(); name_cache.commit(); idl_cache.commit(); entry_cache.commit(); allids.commit(); maxid.commit(); - Ok(()) }) }) } @@ -791,16 +794,14 @@ impl<'a> IdlArcSqliteWriteTransaction<'a> { } pub unsafe fn purge_idxs(&mut self, audit: &mut AuditScope) -> Result<(), OperationError> { - self.db.purge_idxs(audit).and_then(|()| { + self.db.purge_idxs(audit).map(|()| { self.idl_cache.clear(); - Ok(()) }) } pub unsafe fn purge_id2entry(&mut self, audit: &mut AuditScope) -> Result<(), OperationError> { - self.db.purge_id2entry(audit).and_then(|()| { + self.db.purge_id2entry(audit).map(|()| { self.entry_cache.clear(); - Ok(()) }) } diff --git a/kanidmd/src/lib/be/idl_sqlite.rs b/kanidmd/src/lib/be/idl_sqlite.rs index 498e364ec..ed4ed4210 100644 --- a/kanidmd/src/lib/be/idl_sqlite.rs +++ b/kanidmd/src/lib/be/idl_sqlite.rs @@ -449,6 +449,7 @@ impl Drop for IdlSqliteReadTransaction { // Abort - so far this has proven reliable to use drop here. fn drop(self: &mut Self) { if !self.committed { + #[allow(clippy::expect_used)] self.conn .execute("ROLLBACK TRANSACTION", NO_PARAMS) // We can't do this without expect. @@ -468,6 +469,7 @@ impl IdlSqliteReadTransaction { // this a Result<> // // There is no way to flag this is an RO operation. + #[allow(clippy::expect_used)] conn.execute("BEGIN TRANSACTION", NO_PARAMS) .expect("Unable to begin transaction!"); IdlSqliteReadTransaction { @@ -487,6 +489,7 @@ impl Drop for IdlSqliteWriteTransaction { // Abort fn drop(self: &mut Self) { if !self.committed { + #[allow(clippy::expect_used)] self.conn .execute("ROLLBACK TRANSACTION", NO_PARAMS) .expect("Unable to rollback transaction! Can not proceed!!!"); @@ -497,6 +500,7 @@ impl Drop for IdlSqliteWriteTransaction { impl IdlSqliteWriteTransaction { pub fn new(conn: r2d2::PooledConnection) -> Self { // Start the transaction + #[allow(clippy::expect_used)] conn.execute("BEGIN TRANSACTION", NO_PARAMS) .expect("Unable to begin transaction!"); IdlSqliteWriteTransaction { @@ -1253,6 +1257,7 @@ impl IdlSqlite { } pub fn read(&self) -> IdlSqliteReadTransaction { + #[allow(clippy::expect_used)] let conn = self .pool .get() @@ -1261,6 +1266,7 @@ impl IdlSqlite { } pub fn write(&self) -> IdlSqliteWriteTransaction { + #[allow(clippy::expect_used)] let conn = self .pool .get() diff --git a/kanidmd/src/lib/be/mod.rs b/kanidmd/src/lib/be/mod.rs index b6efeceda..33d9cb973 100644 --- a/kanidmd/src/lib/be/mod.rs +++ b/kanidmd/src/lib/be/mod.rs @@ -1,4 +1,3 @@ -use std::convert::TryFrom; use std::fs; use crate::value::IndexType; @@ -87,8 +86,8 @@ impl IdRawEntry { ) -> Result, OperationError> { let db_e = serde_cbor::from_slice(self.data.as_slice()) .map_err(|_| OperationError::SerdeCborError)?; - let id = u64::try_from(self.id).map_err(|_| OperationError::InvalidEntryID)?; - Entry::from_dbentry(au, db_e, id).map_err(|_| OperationError::CorruptedEntry(id)) + // let id = u64::try_from(self.id).map_err(|_| OperationError::InvalidEntryID)?; + Entry::from_dbentry(au, db_e, self.id).map_err(|_| OperationError::CorruptedEntry(self.id)) } } @@ -721,9 +720,7 @@ impl<'a> BackendWriteTransaction<'a> { let idlayer = self.get_idlayer(); // Now, assign id's to all the new entries. - let mut id_max = idlayer.get_id2entry_max_id().and_then(|id_max| { - u64::try_from(id_max).map_err(|_| OperationError::InvalidEntryID) - })?; + let mut id_max = idlayer.get_id2entry_max_id()?; let c_entries: Vec<_> = entries .into_iter() .map(|e| { @@ -891,9 +888,11 @@ impl<'a> BackendWriteTransaction<'a> { // check from the Entry::idx functions as they only yield partial // changes. Because the uuid is changing, we have to treat pre // as a deleting entry, regardless of what state post is in. - let uuid = mask_pre - .map(|e| e.get_uuid()) - .expect("Not possible to fail"); + let uuid = mask_pre.map(|e| e.get_uuid()).ok_or_else(|| { + ladmin_error!(audit, "Invalid entry state - possible memory corruption"); + OperationError::InvalidState + })?; + let (n2u_add, n2u_rem) = Entry::idx_name2uuid_diff(mask_pre, None); // There will never be content to add. assert!(n2u_add.is_none()); @@ -1221,9 +1220,8 @@ impl<'a> BackendWriteTransaction<'a> { // Unwrap the Cell we have finished with it. let idlayer = idlayer.into_inner(); - idlayer.commit(audit).and_then(|()| { + idlayer.commit(audit).map(|()| { idxmeta_wr.commit(); - Ok(()) }) } @@ -1235,6 +1233,7 @@ impl<'a> BackendWriteTransaction<'a> { } pub fn get_db_s_uuid(&self) -> Uuid { + #[allow(clippy::expect_used)] match self .get_idlayer() .get_db_s_uuid() @@ -1252,6 +1251,7 @@ impl<'a> BackendWriteTransaction<'a> { } pub fn get_db_d_uuid(&self) -> Uuid { + #[allow(clippy::expect_used)] match self .get_idlayer() .get_db_d_uuid() @@ -1334,8 +1334,13 @@ impl Backend { // Should this actually call the idlayer directly? pub fn reset_db_s_uuid(&self, audit: &mut AuditScope) -> Uuid { let wr = self.write(); - let sid = wr.reset_db_s_uuid().unwrap(); - wr.commit(audit).unwrap(); + #[allow(clippy::expect_used)] + let sid = wr + .reset_db_s_uuid() + .expect("unable to reset db server uuid"); + #[allow(clippy::expect_used)] + wr.commit(audit) + .expect("Unable to commit to backend, can not proceed"); sid } @@ -1732,12 +1737,12 @@ mod tests { run_test!(|audit: &mut AuditScope, be: &mut BackendWriteTransaction| { // Add some test data? let mut e1: Entry = Entry::new(); - e1.add_ava("name", Value::new_iname_s("william")); + e1.add_ava("name", Value::new_iname("william")); e1.add_ava("uuid", Value::from("db237e8a-0079-4b8c-8a56-593b22aa44d1")); let e1 = unsafe { e1.into_sealed_new() }; let mut e2: Entry = Entry::new(); - e2.add_ava("name", Value::new_iname_s("claire")); + e2.add_ava("name", Value::new_iname("claire")); e2.add_ava("uuid", Value::from("bd651620-00dd-426b-aaa0-4494f7b7906f")); let e2 = unsafe { e2.into_sealed_new() }; @@ -1846,8 +1851,8 @@ mod tests { assert!(be.name2uuid(audit, "william") == Ok(Some(william_uuid))); assert!(be.name2uuid(audit, "db237e8a-0079-4b8c-8a56-593b22aa44d1") == Ok(None)); // check uuid2spn - assert!(be.uuid2spn(audit, &claire_uuid) == Ok(Some(Value::new_iname_s("claire")))); - assert!(be.uuid2spn(audit, &william_uuid) == Ok(Some(Value::new_iname_s("william")))); + assert!(be.uuid2spn(audit, &claire_uuid) == Ok(Some(Value::new_iname("claire")))); + assert!(be.uuid2spn(audit, &william_uuid) == Ok(Some(Value::new_iname("william")))); // check uuid2rdn assert!(be.uuid2rdn(audit, &claire_uuid) == Ok(Some("name=claire".to_string()))); assert!(be.uuid2rdn(audit, &william_uuid) == Ok(Some("name=william".to_string()))); diff --git a/kanidmd/src/lib/constants/uuids.rs b/kanidmd/src/lib/constants/uuids.rs index 3d629fc5e..bcf056106 100644 --- a/kanidmd/src/lib/constants/uuids.rs +++ b/kanidmd/src/lib/constants/uuids.rs @@ -1,111 +1,120 @@ +#![allow(clippy::unwrap_used)] + use uuid::Uuid; // Built in group and account ranges. pub const STR_UUID_ADMIN: &str = "00000000-0000-0000-0000-000000000000"; -pub const _UUID_IDM_ADMINS: &str = "00000000-0000-0000-0000-000000000001"; -pub const _UUID_IDM_PEOPLE_READ_PRIV: &str = "00000000-0000-0000-0000-000000000002"; -pub const _UUID_IDM_PEOPLE_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000003"; -pub const _UUID_IDM_GROUP_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000004"; -pub const _UUID_IDM_ACCOUNT_READ_PRIV: &str = "00000000-0000-0000-0000-000000000005"; -pub const _UUID_IDM_ACCOUNT_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000006"; -pub const _UUID_IDM_RADIUS_SERVERS: &str = "00000000-0000-0000-0000-000000000007"; -pub const _UUID_IDM_HP_ACCOUNT_READ_PRIV: &str = "00000000-0000-0000-0000-000000000008"; -pub const _UUID_IDM_HP_ACCOUNT_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000009"; -pub const _UUID_IDM_SCHEMA_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000010"; -pub const _UUID_IDM_ACP_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000011"; -pub const _UUID_IDM_HP_GROUP_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000012"; -pub const _UUID_IDM_PEOPLE_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000013"; -pub const _UUID_IDM_ACCOUNT_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000014"; -pub const _UUID_IDM_GROUP_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000015"; -pub const _UUID_IDM_HP_ACCOUNT_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000016"; -pub const _UUID_IDM_HP_GROUP_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000017"; -pub const _UUID_IDM_ADMIN_V1: &str = "00000000-0000-0000-0000-000000000018"; -pub const _UUID_SYSTEM_ADMINS: &str = "00000000-0000-0000-0000-000000000019"; -pub const UUID_DOMAIN_ADMINS: &str = "00000000-0000-0000-0000-000000000020"; -pub const _UUID_IDM_ACCOUNT_UNIX_EXTEND_PRIV: &str = "00000000-0000-0000-0000-000000000021"; -pub const _UUID_IDM_GROUP_UNIX_EXTEND_PRIV: &str = "00000000-0000-0000-0000-000000000022"; -pub const _UUID_IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV: &str = +pub const _STR_UUID_IDM_ADMINS: &str = "00000000-0000-0000-0000-000000000001"; +pub const _STR_UUID_IDM_PEOPLE_READ_PRIV: &str = "00000000-0000-0000-0000-000000000002"; +pub const _STR_UUID_IDM_PEOPLE_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000003"; +pub const _STR_UUID_IDM_GROUP_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000004"; +pub const _STR_UUID_IDM_ACCOUNT_READ_PRIV: &str = "00000000-0000-0000-0000-000000000005"; +pub const _STR_UUID_IDM_ACCOUNT_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000006"; +pub const _STR_UUID_IDM_RADIUS_SERVERS: &str = "00000000-0000-0000-0000-000000000007"; +pub const _STR_UUID_IDM_HP_ACCOUNT_READ_PRIV: &str = "00000000-0000-0000-0000-000000000008"; +pub const _STR_UUID_IDM_HP_ACCOUNT_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000009"; +pub const _STR_UUID_IDM_SCHEMA_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000010"; +pub const _STR_UUID_IDM_ACP_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000011"; +pub const _STR_UUID_IDM_HP_GROUP_WRITE_PRIV: &str = "00000000-0000-0000-0000-000000000012"; +pub const _STR_UUID_IDM_PEOPLE_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000013"; +pub const _STR_UUID_IDM_ACCOUNT_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000014"; +pub const _STR_UUID_IDM_GROUP_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000015"; +pub const _STR_UUID_IDM_HP_ACCOUNT_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000016"; +pub const _STR_UUID_IDM_HP_GROUP_MANAGE_PRIV: &str = "00000000-0000-0000-0000-000000000017"; +pub const _STR_UUID_IDM_ADMIN_V1: &str = "00000000-0000-0000-0000-000000000018"; +pub const _STR_UUID_SYSTEM_ADMINS: &str = "00000000-0000-0000-0000-000000000019"; +pub const STR_UUID_DOMAIN_ADMINS: &str = "00000000-0000-0000-0000-000000000020"; +pub const _STR_UUID_IDM_ACCOUNT_UNIX_EXTEND_PRIV: &str = "00000000-0000-0000-0000-000000000021"; +pub const _STR_UUID_IDM_GROUP_UNIX_EXTEND_PRIV: &str = "00000000-0000-0000-0000-000000000022"; +pub const _STR_UUID_IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV: &str = "00000000-0000-0000-0000-000000000023"; -pub const _UUID_IDM_PEOPLE_EXTEND_PRIV: &str = "00000000-0000-0000-0000-000000000024"; +pub const _STR_UUID_IDM_PEOPLE_EXTEND_PRIV: &str = "00000000-0000-0000-0000-000000000024"; // -pub const _UUID_IDM_HIGH_PRIVILEGE: &str = "00000000-0000-0000-0000-000000001000"; +pub const _STR_UUID_IDM_HIGH_PRIVILEGE: &str = "00000000-0000-0000-0000-000000001000"; // Builtin schema -pub const UUID_SCHEMA_ATTR_CLASS: &str = "00000000-0000-0000-0000-ffff00000000"; -pub const UUID_SCHEMA_ATTR_UUID: &str = "00000000-0000-0000-0000-ffff00000001"; -pub const UUID_SCHEMA_ATTR_NAME: &str = "00000000-0000-0000-0000-ffff00000002"; -pub const UUID_SCHEMA_ATTR_SPN: &str = "00000000-0000-0000-0000-ffff00000003"; -pub const UUID_SCHEMA_ATTR_DESCRIPTION: &str = "00000000-0000-0000-0000-ffff00000004"; -pub const UUID_SCHEMA_ATTR_MULTIVALUE: &str = "00000000-0000-0000-0000-ffff00000005"; -pub const UUID_SCHEMA_ATTR_UNIQUE: &str = "00000000-0000-0000-0000-ffff00000047"; -pub const UUID_SCHEMA_ATTR_INDEX: &str = "00000000-0000-0000-0000-ffff00000006"; -pub const UUID_SCHEMA_ATTR_SYNTAX: &str = "00000000-0000-0000-0000-ffff00000007"; -pub const UUID_SCHEMA_ATTR_SYSTEMMAY: &str = "00000000-0000-0000-0000-ffff00000008"; -pub const UUID_SCHEMA_ATTR_MAY: &str = "00000000-0000-0000-0000-ffff00000009"; -pub const UUID_SCHEMA_ATTR_SYSTEMMUST: &str = "00000000-0000-0000-0000-ffff00000010"; -pub const UUID_SCHEMA_ATTR_MUST: &str = "00000000-0000-0000-0000-ffff00000011"; -pub const UUID_SCHEMA_ATTR_MEMBEROF: &str = "00000000-0000-0000-0000-ffff00000012"; -pub const UUID_SCHEMA_ATTR_MEMBER: &str = "00000000-0000-0000-0000-ffff00000013"; -pub const UUID_SCHEMA_ATTR_DIRECTMEMBEROF: &str = "00000000-0000-0000-0000-ffff00000014"; -pub const UUID_SCHEMA_ATTR_VERSION: &str = "00000000-0000-0000-0000-ffff00000015"; -pub const UUID_SCHEMA_ATTR_DOMAIN: &str = "00000000-0000-0000-0000-ffff00000016"; -pub const UUID_SCHEMA_ATTR_ACP_ENABLE: &str = "00000000-0000-0000-0000-ffff00000017"; -pub const UUID_SCHEMA_ATTR_ACP_RECEIVER: &str = "00000000-0000-0000-0000-ffff00000018"; -pub const UUID_SCHEMA_ATTR_ACP_TARGETSCOPE: &str = "00000000-0000-0000-0000-ffff00000019"; -pub const UUID_SCHEMA_ATTR_ACP_SEARCH_ATTR: &str = "00000000-0000-0000-0000-ffff00000020"; -pub const UUID_SCHEMA_ATTR_ACP_CREATE_CLASS: &str = "00000000-0000-0000-0000-ffff00000021"; -pub const UUID_SCHEMA_ATTR_ACP_CREATE_ATTR: &str = "00000000-0000-0000-0000-ffff00000022"; -pub const UUID_SCHEMA_ATTR_ACP_MODIFY_REMOVEDATTR: &str = "00000000-0000-0000-0000-ffff00000023"; -pub const UUID_SCHEMA_ATTR_ACP_MODIFY_PRESENTATTR: &str = "00000000-0000-0000-0000-ffff00000024"; -pub const UUID_SCHEMA_ATTR_ACP_MODIFY_CLASS: &str = "00000000-0000-0000-0000-ffff00000025"; -pub const UUID_SCHEMA_CLASS_ATTRIBUTETYPE: &str = "00000000-0000-0000-0000-ffff00000026"; -pub const UUID_SCHEMA_CLASS_CLASSTYPE: &str = "00000000-0000-0000-0000-ffff00000027"; -pub const UUID_SCHEMA_CLASS_OBJECT: &str = "00000000-0000-0000-0000-ffff00000028"; -pub const UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT: &str = "00000000-0000-0000-0000-ffff00000029"; -pub const UUID_SCHEMA_CLASS_MEMBEROF: &str = "00000000-0000-0000-0000-ffff00000030"; -pub const UUID_SCHEMA_CLASS_RECYCLED: &str = "00000000-0000-0000-0000-ffff00000031"; -pub const UUID_SCHEMA_CLASS_TOMBSTONE: &str = "00000000-0000-0000-0000-ffff00000032"; -pub const UUID_SCHEMA_CLASS_SYSTEM_INFO: &str = "00000000-0000-0000-0000-ffff00000033"; -pub const UUID_SCHEMA_CLASS_ACCESS_CONTROL_PROFILE: &str = "00000000-0000-0000-0000-ffff00000034"; -pub const UUID_SCHEMA_CLASS_ACCESS_CONTROL_SEARCH: &str = "00000000-0000-0000-0000-ffff00000035"; -pub const UUID_SCHEMA_CLASS_ACCESS_CONTROL_DELETE: &str = "00000000-0000-0000-0000-ffff00000036"; -pub const UUID_SCHEMA_CLASS_ACCESS_CONTROL_MODIFY: &str = "00000000-0000-0000-0000-ffff00000037"; -pub const UUID_SCHEMA_CLASS_ACCESS_CONTROL_CREATE: &str = "00000000-0000-0000-0000-ffff00000038"; -pub const UUID_SCHEMA_CLASS_SYSTEM: &str = "00000000-0000-0000-0000-ffff00000039"; -pub const UUID_SCHEMA_ATTR_DISPLAYNAME: &str = "00000000-0000-0000-0000-ffff00000040"; -pub const UUID_SCHEMA_ATTR_MAIL: &str = "00000000-0000-0000-0000-ffff00000041"; -pub const UUID_SCHEMA_ATTR_SSH_PUBLICKEY: &str = "00000000-0000-0000-0000-ffff00000042"; -pub const UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL: &str = "00000000-0000-0000-0000-ffff00000043"; -pub const UUID_SCHEMA_CLASS_PERSON: &str = "00000000-0000-0000-0000-ffff00000044"; -pub const UUID_SCHEMA_CLASS_GROUP: &str = "00000000-0000-0000-0000-ffff00000045"; -pub const UUID_SCHEMA_CLASS_ACCOUNT: &str = "00000000-0000-0000-0000-ffff00000046"; +pub const STR_UUID_SCHEMA_ATTR_CLASS: &str = "00000000-0000-0000-0000-ffff00000000"; +pub const STR_UUID_SCHEMA_ATTR_UUID: &str = "00000000-0000-0000-0000-ffff00000001"; +pub const STR_UUID_SCHEMA_ATTR_NAME: &str = "00000000-0000-0000-0000-ffff00000002"; +pub const STR_UUID_SCHEMA_ATTR_SPN: &str = "00000000-0000-0000-0000-ffff00000003"; +pub const STR_UUID_SCHEMA_ATTR_DESCRIPTION: &str = "00000000-0000-0000-0000-ffff00000004"; +pub const STR_UUID_SCHEMA_ATTR_MULTIVALUE: &str = "00000000-0000-0000-0000-ffff00000005"; +pub const STR_UUID_SCHEMA_ATTR_UNIQUE: &str = "00000000-0000-0000-0000-ffff00000047"; +pub const STR_UUID_SCHEMA_ATTR_INDEX: &str = "00000000-0000-0000-0000-ffff00000006"; +pub const STR_UUID_SCHEMA_ATTR_SYNTAX: &str = "00000000-0000-0000-0000-ffff00000007"; +pub const STR_UUID_SCHEMA_ATTR_SYSTEMMAY: &str = "00000000-0000-0000-0000-ffff00000008"; +pub const STR_UUID_SCHEMA_ATTR_MAY: &str = "00000000-0000-0000-0000-ffff00000009"; +pub const STR_UUID_SCHEMA_ATTR_SYSTEMMUST: &str = "00000000-0000-0000-0000-ffff00000010"; +pub const STR_UUID_SCHEMA_ATTR_MUST: &str = "00000000-0000-0000-0000-ffff00000011"; +pub const STR_UUID_SCHEMA_ATTR_MEMBEROF: &str = "00000000-0000-0000-0000-ffff00000012"; +pub const STR_UUID_SCHEMA_ATTR_MEMBER: &str = "00000000-0000-0000-0000-ffff00000013"; +pub const STR_UUID_SCHEMA_ATTR_DIRECTMEMBEROF: &str = "00000000-0000-0000-0000-ffff00000014"; +pub const STR_UUID_SCHEMA_ATTR_VERSION: &str = "00000000-0000-0000-0000-ffff00000015"; +pub const STR_UUID_SCHEMA_ATTR_DOMAIN: &str = "00000000-0000-0000-0000-ffff00000016"; +pub const STR_UUID_SCHEMA_ATTR_ACP_ENABLE: &str = "00000000-0000-0000-0000-ffff00000017"; +pub const STR_UUID_SCHEMA_ATTR_ACP_RECEIVER: &str = "00000000-0000-0000-0000-ffff00000018"; +pub const STR_UUID_SCHEMA_ATTR_ACP_TARGETSCOPE: &str = "00000000-0000-0000-0000-ffff00000019"; +pub const STR_UUID_SCHEMA_ATTR_ACP_SEARCH_ATTR: &str = "00000000-0000-0000-0000-ffff00000020"; +pub const STR_UUID_SCHEMA_ATTR_ACP_CREATE_CLASS: &str = "00000000-0000-0000-0000-ffff00000021"; +pub const STR_UUID_SCHEMA_ATTR_ACP_CREATE_ATTR: &str = "00000000-0000-0000-0000-ffff00000022"; +pub const STR_UUID_SCHEMA_ATTR_ACP_MODIFY_REMOVEDATTR: &str = + "00000000-0000-0000-0000-ffff00000023"; +pub const STR_UUID_SCHEMA_ATTR_ACP_MODIFY_PRESENTATTR: &str = + "00000000-0000-0000-0000-ffff00000024"; +pub const STR_UUID_SCHEMA_ATTR_ACP_MODIFY_CLASS: &str = "00000000-0000-0000-0000-ffff00000025"; +pub const STR_UUID_SCHEMA_CLASS_ATTRIBUTETYPE: &str = "00000000-0000-0000-0000-ffff00000026"; +pub const STR_UUID_SCHEMA_CLASS_CLASSTYPE: &str = "00000000-0000-0000-0000-ffff00000027"; +pub const STR_UUID_SCHEMA_CLASS_OBJECT: &str = "00000000-0000-0000-0000-ffff00000028"; +pub const STR_UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT: &str = "00000000-0000-0000-0000-ffff00000029"; +pub const STR_UUID_SCHEMA_CLASS_MEMBEROF: &str = "00000000-0000-0000-0000-ffff00000030"; +pub const STR_UUID_SCHEMA_CLASS_RECYCLED: &str = "00000000-0000-0000-0000-ffff00000031"; +pub const STR_UUID_SCHEMA_CLASS_TOMBSTONE: &str = "00000000-0000-0000-0000-ffff00000032"; +pub const STR_UUID_SCHEMA_CLASS_SYSTEM_INFO: &str = "00000000-0000-0000-0000-ffff00000033"; +pub const STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_PROFILE: &str = + "00000000-0000-0000-0000-ffff00000034"; +pub const STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_SEARCH: &str = + "00000000-0000-0000-0000-ffff00000035"; +pub const STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_DELETE: &str = + "00000000-0000-0000-0000-ffff00000036"; +pub const STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_MODIFY: &str = + "00000000-0000-0000-0000-ffff00000037"; +pub const STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_CREATE: &str = + "00000000-0000-0000-0000-ffff00000038"; +pub const STR_UUID_SCHEMA_CLASS_SYSTEM: &str = "00000000-0000-0000-0000-ffff00000039"; +pub const STR_UUID_SCHEMA_ATTR_DISPLAYNAME: &str = "00000000-0000-0000-0000-ffff00000040"; +pub const STR_UUID_SCHEMA_ATTR_MAIL: &str = "00000000-0000-0000-0000-ffff00000041"; +pub const STR_UUID_SCHEMA_ATTR_SSH_PUBLICKEY: &str = "00000000-0000-0000-0000-ffff00000042"; +pub const STR_UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL: &str = "00000000-0000-0000-0000-ffff00000043"; +pub const STR_UUID_SCHEMA_CLASS_PERSON: &str = "00000000-0000-0000-0000-ffff00000044"; +pub const STR_UUID_SCHEMA_CLASS_GROUP: &str = "00000000-0000-0000-0000-ffff00000045"; +pub const STR_UUID_SCHEMA_CLASS_ACCOUNT: &str = "00000000-0000-0000-0000-ffff00000046"; // GAP - 47 -pub const UUID_SCHEMA_ATTR_ATTRIBUTENAME: &str = "00000000-0000-0000-0000-ffff00000048"; -pub const UUID_SCHEMA_ATTR_CLASSNAME: &str = "00000000-0000-0000-0000-ffff00000049"; -pub const UUID_SCHEMA_ATTR_LEGALNAME: &str = "00000000-0000-0000-0000-ffff00000050"; -pub const UUID_SCHEMA_ATTR_RADIUS_SECRET: &str = "00000000-0000-0000-0000-ffff00000051"; -pub const UUID_SCHEMA_CLASS_DOMAIN_INFO: &str = "00000000-0000-0000-0000-ffff00000052"; -pub const UUID_SCHEMA_ATTR_DOMAIN_NAME: &str = "00000000-0000-0000-0000-ffff00000053"; -pub const UUID_SCHEMA_ATTR_DOMAIN_UUID: &str = "00000000-0000-0000-0000-ffff00000054"; -pub const UUID_SCHEMA_ATTR_DOMAIN_SSID: &str = "00000000-0000-0000-0000-ffff00000055"; +pub const STR_UUID_SCHEMA_ATTR_ATTRIBUTENAME: &str = "00000000-0000-0000-0000-ffff00000048"; +pub const STR_UUID_SCHEMA_ATTR_CLASSNAME: &str = "00000000-0000-0000-0000-ffff00000049"; +pub const STR_UUID_SCHEMA_ATTR_LEGALNAME: &str = "00000000-0000-0000-0000-ffff00000050"; +pub const STR_UUID_SCHEMA_ATTR_RADIUS_SECRET: &str = "00000000-0000-0000-0000-ffff00000051"; +pub const STR_UUID_SCHEMA_CLASS_DOMAIN_INFO: &str = "00000000-0000-0000-0000-ffff00000052"; +pub const STR_UUID_SCHEMA_ATTR_DOMAIN_NAME: &str = "00000000-0000-0000-0000-ffff00000053"; +pub const STR_UUID_SCHEMA_ATTR_DOMAIN_UUID: &str = "00000000-0000-0000-0000-ffff00000054"; +pub const STR_UUID_SCHEMA_ATTR_DOMAIN_SSID: &str = "00000000-0000-0000-0000-ffff00000055"; -pub const UUID_SCHEMA_ATTR_GIDNUMBER: &str = "00000000-0000-0000-0000-ffff00000056"; -pub const UUID_SCHEMA_CLASS_POSIXACCOUNT: &str = "00000000-0000-0000-0000-ffff00000057"; -pub const UUID_SCHEMA_CLASS_POSIXGROUP: &str = "00000000-0000-0000-0000-ffff00000058"; -pub const UUID_SCHEMA_ATTR_BADLIST_PASSWORD: &str = "00000000-0000-0000-0000-ffff00000059"; -pub const UUID_SCHEMA_CLASS_SYSTEM_CONFIG: &str = "00000000-0000-0000-0000-ffff00000060"; -pub const UUID_SCHEMA_ATTR_LOGINSHELL: &str = "00000000-0000-0000-0000-ffff00000061"; -pub const UUID_SCHEMA_ATTR_UNIX_PASSWORD: &str = "00000000-0000-0000-0000-ffff00000062"; -pub const UUID_SCHEMA_ATTR_LAST_MOD_CID: &str = "00000000-0000-0000-0000-ffff00000063"; -pub const UUID_SCHEMA_ATTR_PHANTOM: &str = "00000000-0000-0000-0000-ffff00000064"; -pub const UUID_SCHEMA_ATTR_CLAIM: &str = "00000000-0000-0000-0000-ffff00000065"; -pub const UUID_SCHEMA_ATTR_PASSWORD_IMPORT: &str = "00000000-0000-0000-0000-ffff00000066"; -pub const UUID_SCHEMA_ATTR_NSUNIQUEID: &str = "00000000-0000-0000-0000-ffff00000067"; +pub const STR_UUID_SCHEMA_ATTR_GIDNUMBER: &str = "00000000-0000-0000-0000-ffff00000056"; +pub const STR_UUID_SCHEMA_CLASS_POSIXACCOUNT: &str = "00000000-0000-0000-0000-ffff00000057"; +pub const STR_UUID_SCHEMA_CLASS_POSIXGROUP: &str = "00000000-0000-0000-0000-ffff00000058"; +pub const STR_UUID_SCHEMA_ATTR_BADLIST_PASSWORD: &str = "00000000-0000-0000-0000-ffff00000059"; +pub const STR_UUID_SCHEMA_CLASS_SYSTEM_CONFIG: &str = "00000000-0000-0000-0000-ffff00000060"; +pub const STR_UUID_SCHEMA_ATTR_LOGINSHELL: &str = "00000000-0000-0000-0000-ffff00000061"; +pub const STR_UUID_SCHEMA_ATTR_UNIX_PASSWORD: &str = "00000000-0000-0000-0000-ffff00000062"; +pub const STR_UUID_SCHEMA_ATTR_LAST_MOD_CID: &str = "00000000-0000-0000-0000-ffff00000063"; +pub const STR_UUID_SCHEMA_ATTR_PHANTOM: &str = "00000000-0000-0000-0000-ffff00000064"; +pub const STR_UUID_SCHEMA_ATTR_CLAIM: &str = "00000000-0000-0000-0000-ffff00000065"; +pub const STR_UUID_SCHEMA_ATTR_PASSWORD_IMPORT: &str = "00000000-0000-0000-0000-ffff00000066"; +pub const STR_UUID_SCHEMA_ATTR_NSUNIQUEID: &str = "00000000-0000-0000-0000-ffff00000067"; -pub const UUID_SCHEMA_ATTR_DN: &str = "00000000-0000-0000-0000-ffff00000068"; -pub const UUID_SCHEMA_ATTR_NICE: &str = "00000000-0000-0000-0000-ffff00000069"; -pub const UUID_SCHEMA_ATTR_ENTRYUUID: &str = "00000000-0000-0000-0000-ffff00000070"; -pub const UUID_SCHEMA_ATTR_OBJECTCLASS: &str = "00000000-0000-0000-0000-ffff00000071"; +pub const STR_UUID_SCHEMA_ATTR_DN: &str = "00000000-0000-0000-0000-ffff00000068"; +pub const STR_UUID_SCHEMA_ATTR_NICE: &str = "00000000-0000-0000-0000-ffff00000069"; +pub const STR_UUID_SCHEMA_ATTR_ENTRYUUID: &str = "00000000-0000-0000-0000-ffff00000070"; +pub const STR_UUID_SCHEMA_ATTR_OBJECTCLASS: &str = "00000000-0000-0000-0000-ffff00000071"; // System and domain infos // I'd like to strongly criticise william of the past for fucking up these allocations. @@ -115,37 +124,42 @@ pub const STR_UUID_DOMAIN_INFO: &str = "00000000-0000-0000-0000-ffffff000025"; // Access controls // skip 00 / 01 - see system info -pub const _UUID_IDM_ADMINS_ACP_RECYCLE_SEARCH_V1: &str = "00000000-0000-0000-0000-ffffff000002"; -pub const _UUID_IDM_ADMINS_ACP_REVIVE_V1: &str = "00000000-0000-0000-0000-ffffff000003"; -pub const _UUID_IDM_SELF_ACP_READ_V1: &str = "00000000-0000-0000-0000-ffffff000004"; -pub const _UUID_IDM_ALL_ACP_READ_V1: &str = "00000000-0000-0000-0000-ffffff000006"; -pub const _UUID_IDM_ACP_PEOPLE_READ_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000007"; -pub const _UUID_IDM_ACP_PEOPLE_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000008"; -pub const _UUID_IDM_ACP_GROUP_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000009"; -pub const _UUID_IDM_ACP_ACCOUNT_READ_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000010"; -pub const _UUID_IDM_ACP_ACCOUNT_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000011"; -pub const _UUID_IDM_ACP_ACCOUNT_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000012"; -pub const _UUID_IDM_ACP_PEOPLE_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000013"; -pub const _UUID_IDM_ACP_RADIUS_SERVERS_V1: &str = "00000000-0000-0000-0000-ffffff000014"; -pub const _UUID_IDM_ACP_HP_ACCOUNT_READ_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000015"; -pub const _UUID_IDM_ACP_HP_ACCOUNT_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000016"; -pub const _UUID_IDM_ACP_HP_GROUP_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000017"; -pub const _UUID_IDM_ACP_SCHEMA_WRITE_ATTRS_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000018"; -pub const _UUID_IDM_ACP_ACP_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000019"; -pub const _UUID_IDM_ACP_SCHEMA_WRITE_CLASSES_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000020"; -pub const _UUID_IDM_SELF_ACP_WRITE_V1: &str = "00000000-0000-0000-0000-ffffff000021"; -pub const _UUID_IDM_ACP_GROUP_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000022"; -pub const _UUID_IDM_ACP_HP_ACCOUNT_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000023"; -pub const _UUID_IDM_ACP_HP_GROUP_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000024"; +pub const _STR_UUID_IDM_ADMINS_ACP_RECYCLE_SEARCH_V1: &str = "00000000-0000-0000-0000-ffffff000002"; +pub const _STR_UUID_IDM_ADMINS_ACP_REVIVE_V1: &str = "00000000-0000-0000-0000-ffffff000003"; +pub const _STR_UUID_IDM_SELF_ACP_READ_V1: &str = "00000000-0000-0000-0000-ffffff000004"; +pub const _STR_UUID_IDM_ALL_ACP_READ_V1: &str = "00000000-0000-0000-0000-ffffff000006"; +pub const _STR_UUID_IDM_ACP_PEOPLE_READ_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000007"; +pub const _STR_UUID_IDM_ACP_PEOPLE_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000008"; +pub const _STR_UUID_IDM_ACP_GROUP_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000009"; +pub const _STR_UUID_IDM_ACP_ACCOUNT_READ_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000010"; +pub const _STR_UUID_IDM_ACP_ACCOUNT_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000011"; +pub const _STR_UUID_IDM_ACP_ACCOUNT_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000012"; +pub const _STR_UUID_IDM_ACP_PEOPLE_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000013"; +pub const _STR_UUID_IDM_ACP_RADIUS_SERVERS_V1: &str = "00000000-0000-0000-0000-ffffff000014"; +pub const _STR_UUID_IDM_ACP_HP_ACCOUNT_READ_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000015"; +pub const _STR_UUID_IDM_ACP_HP_ACCOUNT_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000016"; +pub const _STR_UUID_IDM_ACP_HP_GROUP_WRITE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000017"; +pub const _STR_UUID_IDM_ACP_SCHEMA_WRITE_ATTRS_PRIV_V1: &str = + "00000000-0000-0000-0000-ffffff000018"; +pub const _STR_UUID_IDM_ACP_ACP_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000019"; +pub const _STR_UUID_IDM_ACP_SCHEMA_WRITE_CLASSES_PRIV_V1: &str = + "00000000-0000-0000-0000-ffffff000020"; +pub const _STR_UUID_IDM_SELF_ACP_WRITE_V1: &str = "00000000-0000-0000-0000-ffffff000021"; +pub const _STR_UUID_IDM_ACP_GROUP_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000022"; +pub const _STR_UUID_IDM_ACP_HP_ACCOUNT_MANAGE_PRIV_V1: &str = + "00000000-0000-0000-0000-ffffff000023"; +pub const _STR_UUID_IDM_ACP_HP_GROUP_MANAGE_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000024"; // Skip 25 - see domain info. -pub const UUID_IDM_ACP_DOMAIN_ADMIN_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000026"; +pub const STR_UUID_IDM_ACP_DOMAIN_ADMIN_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000026"; pub const STR_UUID_SYSTEM_CONFIG: &str = "00000000-0000-0000-0000-ffffff000027"; -pub const UUID_IDM_ACP_SYSTEM_CONFIG_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000028"; -pub const _UUID_IDM_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000029"; -pub const _UUID_IDM_ACP_GROUP_UNIX_EXTEND_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000030"; -pub const _UUID_IDM_ACP_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1: &str = +pub const STR_UUID_IDM_ACP_SYSTEM_CONFIG_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000028"; +pub const _STR_UUID_IDM_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1: &str = + "00000000-0000-0000-0000-ffffff000029"; +pub const _STR_UUID_IDM_ACP_GROUP_UNIX_EXTEND_PRIV_V1: &str = + "00000000-0000-0000-0000-ffffff000030"; +pub const _STR_UUID_IDM_ACP_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000031"; -pub const _UUID_IDM_ACP_PEOPLE_EXTEND_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000032"; +pub const _STR_UUID_IDM_ACP_PEOPLE_EXTEND_PRIV_V1: &str = "00000000-0000-0000-0000-ffffff000032"; // End of system ranges pub const STR_UUID_DOES_NOT_EXIST: &str = "00000000-0000-0000-0000-fffffffffffe"; @@ -158,4 +172,101 @@ lazy_static! { pub static ref UUID_SYSTEM_CONFIG: Uuid = Uuid::parse_str(STR_UUID_SYSTEM_CONFIG).unwrap(); pub static ref UUID_SYSTEM_INFO: Uuid = Uuid::parse_str(STR_UUID_SYSTEM_INFO).unwrap(); pub static ref UUID_DOMAIN_INFO: Uuid = Uuid::parse_str(STR_UUID_DOMAIN_INFO).unwrap(); + pub static ref UUID_SCHEMA_ATTR_CLASS: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_CLASS).unwrap(); + pub static ref UUID_SCHEMA_ATTR_UUID: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_UUID).unwrap(); + pub static ref UUID_SCHEMA_ATTR_LAST_MOD_CID: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_LAST_MOD_CID).unwrap(); + pub static ref UUID_SCHEMA_ATTR_NAME: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_NAME).unwrap(); + pub static ref UUID_SCHEMA_ATTR_SPN: Uuid = Uuid::parse_str(STR_UUID_SCHEMA_ATTR_SPN).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ATTRIBUTENAME: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ATTRIBUTENAME).unwrap(); + pub static ref UUID_SCHEMA_ATTR_CLASSNAME: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_CLASSNAME).unwrap(); + pub static ref UUID_SCHEMA_ATTR_DESCRIPTION: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_DESCRIPTION).unwrap(); + pub static ref UUID_SCHEMA_ATTR_MULTIVALUE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_MULTIVALUE).unwrap(); + pub static ref UUID_SCHEMA_ATTR_PHANTOM: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_PHANTOM).unwrap(); + pub static ref UUID_SCHEMA_ATTR_UNIQUE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_UNIQUE).unwrap(); + pub static ref UUID_SCHEMA_ATTR_INDEX: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_INDEX).unwrap(); + pub static ref UUID_SCHEMA_ATTR_SYNTAX: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_SYNTAX).unwrap(); + pub static ref UUID_SCHEMA_ATTR_SYSTEMMAY: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_SYSTEMMAY).unwrap(); + pub static ref UUID_SCHEMA_ATTR_MAY: Uuid = Uuid::parse_str(STR_UUID_SCHEMA_ATTR_MAY).unwrap(); + pub static ref UUID_SCHEMA_ATTR_SYSTEMMUST: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_SYSTEMMUST).unwrap(); + pub static ref UUID_SCHEMA_ATTR_MUST: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_MUST).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_ENABLE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_ENABLE).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_RECEIVER: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_RECEIVER).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_TARGETSCOPE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_TARGETSCOPE).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_SEARCH_ATTR: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_SEARCH_ATTR).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_CREATE_CLASS: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_CREATE_CLASS).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_CREATE_ATTR: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_CREATE_ATTR).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_MODIFY_REMOVEDATTR: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_MODIFY_REMOVEDATTR).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_MODIFY_PRESENTATTR: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_MODIFY_PRESENTATTR).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ACP_MODIFY_CLASS: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ACP_MODIFY_CLASS).unwrap(); + pub static ref UUID_SCHEMA_ATTR_MEMBEROF: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_MEMBEROF).unwrap(); + pub static ref UUID_SCHEMA_ATTR_DIRECTMEMBEROF: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_DIRECTMEMBEROF).unwrap(); + pub static ref UUID_SCHEMA_ATTR_MEMBER: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_MEMBER).unwrap(); + pub static ref UUID_SCHEMA_ATTR_VERSION: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_VERSION).unwrap(); + pub static ref UUID_SCHEMA_ATTR_DOMAIN: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_DOMAIN).unwrap(); + pub static ref UUID_SCHEMA_ATTR_CLAIM: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_CLAIM).unwrap(); + pub static ref UUID_SCHEMA_ATTR_PASSWORD_IMPORT: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_PASSWORD_IMPORT).unwrap(); + pub static ref UUID_SCHEMA_ATTR_DN: Uuid = Uuid::parse_str(STR_UUID_SCHEMA_ATTR_DN).unwrap(); + pub static ref UUID_SCHEMA_ATTR_ENTRYUUID: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_ENTRYUUID).unwrap(); + pub static ref UUID_SCHEMA_ATTR_OBJECTCLASS: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_ATTR_OBJECTCLASS).unwrap(); + pub static ref UUID_SCHEMA_CLASS_ATTRIBUTETYPE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_ATTRIBUTETYPE).unwrap(); + pub static ref UUID_SCHEMA_CLASS_CLASSTYPE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_CLASSTYPE).unwrap(); + pub static ref UUID_SCHEMA_CLASS_OBJECT: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_OBJECT).unwrap(); + pub static ref UUID_SCHEMA_CLASS_MEMBEROF: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_MEMBEROF).unwrap(); + pub static ref UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT).unwrap(); + pub static ref UUID_SCHEMA_CLASS_RECYCLED: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_RECYCLED).unwrap(); + pub static ref UUID_SCHEMA_CLASS_TOMBSTONE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_TOMBSTONE).unwrap(); + pub static ref UUID_SCHEMA_CLASS_SYSTEM_INFO: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_SYSTEM_INFO).unwrap(); + pub static ref UUID_SCHEMA_CLASS_ACCESS_CONTROL_PROFILE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_PROFILE).unwrap(); + pub static ref UUID_SCHEMA_CLASS_ACCESS_CONTROL_SEARCH: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_SEARCH).unwrap(); + pub static ref UUID_SCHEMA_CLASS_ACCESS_CONTROL_DELETE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_DELETE).unwrap(); + pub static ref UUID_SCHEMA_CLASS_ACCESS_CONTROL_MODIFY: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_MODIFY).unwrap(); + pub static ref UUID_SCHEMA_CLASS_ACCESS_CONTROL_CREATE: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_ACCESS_CONTROL_CREATE).unwrap(); + pub static ref UUID_SCHEMA_CLASS_SYSTEM: Uuid = + Uuid::parse_str(STR_UUID_SCHEMA_CLASS_SYSTEM).unwrap(); } diff --git a/kanidmd/src/lib/core/ctx.rs b/kanidmd/src/lib/core/ctx.rs index 7b0cbd3b3..fb5860c66 100644 --- a/kanidmd/src/lib/core/ctx.rs +++ b/kanidmd/src/lib/core/ctx.rs @@ -26,6 +26,7 @@ impl ServerCtx { self.system.clone() } + #[allow(clippy::expect_used)] pub fn stop(self) { // stop the actix system self.system.stop(); diff --git a/kanidmd/src/lib/core/ldaps.rs b/kanidmd/src/lib/core/ldaps.rs index eca2805d3..ed833f190 100644 --- a/kanidmd/src/lib/core/ldaps.rs +++ b/kanidmd/src/lib/core/ldaps.rs @@ -198,7 +198,12 @@ pub(crate) async fn create_ldap_server( eprintln!("Could not parse ldap server address {} -> {:?}", address, e); })?; - let listener = Box::new(TcpListener::bind(&addr).await.unwrap()); + let listener = Box::new(TcpListener::bind(&addr).await.map_err(|e| { + eprintln!( + "Could not bind to ldap server address {} -> {:?}", + address, e + ); + })?); match opt_tls_params { Some(tls_params) => { @@ -208,8 +213,10 @@ pub(crate) async fn create_ldap_server( let lacceptor = Box::leak(acceptor) as &'static _; ctx.add_message_stream(Box::leak(listener).incoming().map(move |st| { - let st = st.unwrap(); - let addr = st.peer_addr().unwrap(); + #[allow(clippy::expect_used)] + let st = st.expect("Failed to access TCP stream"); + #[allow(clippy::expect_used)] + let addr = st.peer_addr().expect("Failed to access peer adddress"); TlsConnect(lacceptor, st, addr) })); LdapServer { qe_r } @@ -219,8 +226,10 @@ pub(crate) async fn create_ldap_server( info!("Starting LDAP interface ldap://{} ...", address); LdapServer::create(move |ctx| { ctx.add_message_stream(Box::leak(listener).incoming().map(|st| { - let st = st.unwrap(); - let addr = st.peer_addr().unwrap(); + #[allow(clippy::expect_used)] + let st = st.expect("Failed to access TCP stream"); + #[allow(clippy::expect_used)] + let addr = st.peer_addr().expect("Failed to access peer adddress"); TcpConnect(st, addr) })); LdapServer { qe_r } diff --git a/kanidmd/src/lib/core/mod.rs b/kanidmd/src/lib/core/mod.rs index 1fafe7616..d07268a68 100644 --- a/kanidmd/src/lib/core/mod.rs +++ b/kanidmd/src/lib/core/mod.rs @@ -1,11 +1,11 @@ mod ctx; mod ldaps; // use actix_files as fs; -use libc::umask; use actix::prelude::*; use actix_session::{CookieSession, Session}; use actix_web::web::{self, Data, HttpResponse, Json, Path}; use actix_web::{cookie, error, middleware, App, HttpServer}; +use libc::umask; use crossbeam::channel::unbounded; use std::sync::Arc; @@ -462,7 +462,7 @@ async fn schema_attributetype_get_id( let filter = filter_all!(f_and!([ f_eq("class", PartialValue::new_class("attributetype")), - f_eq("attributename", PartialValue::new_iutf8s(path.as_str())) + f_eq("attributename", PartialValue::new_iutf8(path.as_str())) ])); let (eventid, hvalue) = new_eventid!(); @@ -497,7 +497,7 @@ async fn schema_classtype_get_id( let filter = filter_all!(f_and!([ f_eq("class", PartialValue::new_class("classtype")), - f_eq("classname", PartialValue::new_iutf8s(path.as_str())) + f_eq("classname", PartialValue::new_iutf8(path.as_str())) ])); let (eventid, hvalue) = new_eventid!(); @@ -1024,7 +1024,7 @@ async fn group_post_id_unix( let uat = get_current_user(&session); let id = path.into_inner(); let (eventid, hvalue) = new_eventid!(); - let m_obj = IdmGroupUnixExtendMessage::new(uat, id, obj.into_inner(), eventid); + let m_obj = IdmGroupUnixExtendMessage::new(uat, id, &obj, eventid); match state.qe_w.send(m_obj).await { Ok(Ok(())) => HttpResponse::Ok() .header("X-KANIDM-OPID", hvalue) @@ -1305,7 +1305,7 @@ fn setup_qs_idms( Ok((query_server, idms)) } -pub fn backup_server_core(config: Configuration, dst_path: &str) { +pub fn backup_server_core(config: &Configuration, dst_path: &str) { let mut audit = AuditScope::new("backend_backup", uuid::Uuid::new_v4(), config.log_level); let schema = match Schema::new(&mut audit) { Ok(s) => s, @@ -1337,7 +1337,7 @@ pub fn backup_server_core(config: Configuration, dst_path: &str) { // Let the txn abort, even on success. } -pub fn restore_server_core(config: Configuration, dst_path: &str) { +pub fn restore_server_core(config: &Configuration, dst_path: &str) { let mut audit = AuditScope::new("backend_restore", uuid::Uuid::new_v4(), config.log_level); // First, we provide the in-memory schema so that core attrs are indexed correctly. @@ -1401,7 +1401,7 @@ pub fn restore_server_core(config: Configuration, dst_path: &str) { info!("✅ Restore Success!"); } -pub fn reindex_server_core(config: Configuration) { +pub fn reindex_server_core(config: &Configuration) { let mut audit = AuditScope::new("server_reindex", uuid::Uuid::new_v4(), config.log_level); eprintln!("Start Index Phase 1 ..."); // First, we provide the in-memory schema so that core attrs are indexed correctly. @@ -1471,7 +1471,7 @@ pub fn reindex_server_core(config: Configuration) { }; } -pub fn domain_rename_core(config: Configuration, new_domain_name: String) { +pub fn domain_rename_core(config: &Configuration, new_domain_name: &str) { let mut audit = AuditScope::new("domain_rename", uuid::Uuid::new_v4(), config.log_level); let schema = match Schema::new(&mut audit) { @@ -1502,7 +1502,7 @@ pub fn domain_rename_core(config: Configuration, new_domain_name: String) { let qs_write = qs.write(duration_from_epoch_now()); let r = qs_write - .domain_rename(&mut audit, new_domain_name.as_str()) + .domain_rename(&mut audit, new_domain_name) .and_then(|_| qs_write.commit(&mut audit)); match r { @@ -1531,7 +1531,7 @@ pub fn reset_sid_core(config: Configuration) { } */ -pub fn verify_server_core(config: Configuration) { +pub fn verify_server_core(config: &Configuration) { let mut audit = AuditScope::new("server_verify", uuid::Uuid::new_v4(), config.log_level); // setup the qs - without initialise! let schema_mem = match Schema::new(&mut audit) { @@ -1569,7 +1569,7 @@ pub fn verify_server_core(config: Configuration) { // Now add IDM server verifications? } -pub fn recover_account_core(config: Configuration, name: String, password: String) { +pub fn recover_account_core(config: &Configuration, name: &str, password: &str) { let mut audit = AuditScope::new("recover_account", uuid::Uuid::new_v4(), config.log_level); let schema = match Schema::new(&mut audit) { @@ -1600,14 +1600,18 @@ pub fn recover_account_core(config: Configuration, name: String, password: Strin // Run the password change. let mut idms_prox_write = idms.proxy_write(duration_from_epoch_now()); - match idms_prox_write.recover_account(&mut audit, name, password) { - Ok(_) => { - idms_prox_write - .commit(&mut audit) - .expect("A critical error during commit occured."); - audit.write_log(); - info!("Password reset!"); - } + match idms_prox_write.recover_account(&mut audit, &name, &password) { + Ok(_) => match idms_prox_write.commit(&mut audit) { + Ok(()) => { + audit.write_log(); + info!("Password reset!"); + } + Err(e) => { + error!("A critical error during commit occured {:?}", e); + audit.write_log(); + std::process::exit(1); + } + }, Err(e) => { error!("Error during password reset -> {:?}", e); audit.write_log(); @@ -1633,7 +1637,7 @@ pub async fn create_server_core(config: Configuration) -> Result // The log server is started on it's own thread, and is contacted // asynchronously. let (log_tx, log_rx) = unbounded(); - let log_thread = thread::spawn(move || async_log::run(log_rx)); + let log_thread = thread::spawn(move || async_log::run(&log_rx)); // Similar, create a stats thread which aggregates statistics from the // server as they come in. @@ -1681,11 +1685,7 @@ pub async fn create_server_core(config: Configuration) -> Result match &config.integration_test_config { Some(itc) => { let mut idms_prox_write = idms.proxy_write(duration_from_epoch_now()); - match idms_prox_write.recover_account( - &mut audit, - "admin".to_string(), - itc.admin_password.clone(), - ) { + match idms_prox_write.recover_account(&mut audit, "admin", &itc.admin_password) { Ok(_) => {} Err(e) => { audit.write_log(); @@ -1975,9 +1975,16 @@ pub async fn create_server_core(config: Configuration) -> Result server.bind(config.address) } }; - server.expect("Failed to initialise server!").run(); - info!("ready to rock! 🤘"); + match server { + Ok(s) => s.run(), + Err(e) => { + error!("Failed to initialise server! {:?}", e); + return Err(()); + } + }; + + info!("ready to rock! 🧱"); Ok(ServerCtx::new(System::current(), log_tx, log_thread)) } diff --git a/kanidmd/src/lib/credential/mod.rs b/kanidmd/src/lib/credential/mod.rs index d5b7632c7..cc1accbd8 100644 --- a/kanidmd/src/lib/credential/mod.rs +++ b/kanidmd/src/lib/credential/mod.rs @@ -1,4 +1,5 @@ use crate::be::dbvalue::{DbCredV1, DbPasswordV1}; +use kanidm_proto::v1::OperationError; use openssl::hash::MessageDigest; use openssl::pkcs5::pbkdf2_hmac; use rand::prelude::*; @@ -93,7 +94,7 @@ impl TryFrom<&str> for Password { } impl Password { - fn new_pbkdf2(cleartext: &str) -> KDF { + fn new_pbkdf2(cleartext: &str) -> Result { let mut rng = rand::thread_rng(); let salt: Vec = (0..PBKDF2_SALT_LEN).map(|_| rng.gen()).collect(); // This is 512 bits of output @@ -106,18 +107,18 @@ impl Password { MessageDigest::sha256(), key.as_mut_slice(), ) - .expect("PBKDF2 failure"); - // Turn key to a vec. - KDF::PBKDF2(PBKDF2_COST, salt, key) + .map(|()| { + // Turn key to a vec. + KDF::PBKDF2(PBKDF2_COST, salt, key) + }) + .map_err(|_| OperationError::CryptographyError) } - pub fn new(cleartext: &str) -> Self { - Password { - material: Self::new_pbkdf2(cleartext), - } + pub fn new(cleartext: &str) -> Result { + Self::new_pbkdf2(cleartext).map(|material| Password { material }) } - pub fn verify(&self, cleartext: &str) -> bool { + pub fn verify(&self, cleartext: &str) -> Result { match &self.material { KDF::PBKDF2(cost, salt, key) => { // We have to get the number of bits to derive from our stored hash @@ -132,9 +133,11 @@ impl Password { MessageDigest::sha256(), chal_key.as_mut_slice(), ) - .expect("PBKDF2 failure"); - // Actually compare the outputs. - &chal_key == key + .map_err(|_| OperationError::CryptographyError) + .map(|()| { + // Actually compare the outputs. + &chal_key == key + }) } } } @@ -208,29 +211,29 @@ impl TryFrom for Credential { } impl Credential { - pub fn new_password_only(cleartext: &str) -> Self { - Credential { - password: Some(Password::new(cleartext)), + pub fn new_password_only(cleartext: &str) -> Result { + Password::new(cleartext).map(|pw| Credential { + password: Some(pw), totp: None, claims: Vec::new(), uuid: Uuid::new_v4(), - } + }) } - pub fn set_password(&self, cleartext: &str) -> Self { - Credential { - password: Some(Password::new(cleartext)), + pub fn set_password(&self, cleartext: &str) -> Result { + Password::new(cleartext).map(|pw| Credential { + password: Some(pw), totp: self.totp.clone(), claims: self.claims.clone(), uuid: self.uuid, - } + }) } #[cfg(test)] pub fn verify_password(&self, cleartext: &str) -> bool { match &self.password { - Some(pw) => pw.verify(cleartext), - None => panic!(), + Some(pw) => pw.verify(cleartext).unwrap_or(false), + None => false, } } @@ -299,7 +302,7 @@ mod tests { #[test] fn test_credential_simple() { - let c = Credential::new_password_only("password"); + let c = Credential::new_password_only("password").unwrap(); assert!(c.verify_password("password")); assert!(!c.verify_password("password1")); assert!(!c.verify_password("Password1")); @@ -317,6 +320,6 @@ mod tests { let im_pw = "pbkdf2_sha256$36000$xIEozuZVAoYm$uW1b35DUKyhvQAf1mBqMvoBDcqSD06juzyO/nmyV0+w="; let password = "eicieY7ahchaoCh0eeTa"; let r = Password::try_from(im_pw).expect("Failed to parse"); - assert!(r.verify(password)); + assert!(r.verify(password).unwrap_or(false)); } } diff --git a/kanidmd/src/lib/entry.rs b/kanidmd/src/lib/entry.rs index 27f12ff54..a6f62c32a 100644 --- a/kanidmd/src/lib/entry.rs +++ b/kanidmd/src/lib/entry.rs @@ -323,14 +323,14 @@ impl Entry { let attr = k.to_lowercase(); let vv: Set = match attr.as_str() { "attributename" | "classname" | "domain" => { - vs.into_iter().map(|v| Value::new_iutf8(v)).collect() + vs.into_iter().map(|v| Value::new_iutf8(&v)).collect() } "name" | "domain_name" => { - vs.into_iter().map(|v| Value::new_iname(v)).collect() + vs.into_iter().map(|v| Value::new_iname(&v)).collect() } "userid" | "uidnumber" => { warn!("WARNING: Use of unstabilised attributes userid/uidnumber"); - vs.into_iter().map(|v| Value::new_iutf8(v)).collect() + vs.into_iter().map(|v| Value::new_iutf8(&v)).collect() } "class" | "acp_create_class" | "acp_modify_class" => { vs.into_iter().map(|v| Value::new_class(v.as_str())).collect() @@ -1299,7 +1299,7 @@ impl Entry { pub fn reduce_attributes( self, - allowed_attrs: BTreeSet<&str>, + allowed_attrs: &BTreeSet<&str>, ) -> Entry { // Remove all attrs from our tree that are NOT in the allowed set. @@ -1880,7 +1880,7 @@ impl From<&SchemaAttribute> for Entry { // Convert an Attribute to an entry ... make it good! let uuid_v = btreeset![Value::new_uuidr(&s.uuid)]; - let name_v = btreeset![Value::new_iutf8(s.name.clone())]; + let name_v = btreeset![Value::new_iutf8(s.name.as_str())]; let desc_v = btreeset![Value::new_utf8(s.description.clone())]; let multivalue_v = btreeset![Value::from(s.multivalue)]; @@ -1922,7 +1922,7 @@ impl From<&SchemaClass> for Entry { fn from(s: &SchemaClass) -> Self { let uuid_v = btreeset![Value::new_uuidr(&s.uuid)]; - let name_v = btreeset![Value::new_iutf8(s.name.clone())]; + let name_v = btreeset![Value::new_iutf8(s.name.as_str())]; let desc_v = btreeset![Value::new_utf8(s.description.clone())]; let mut attrs: Map> = Map::with_capacity(16); @@ -2070,7 +2070,7 @@ mod tests { let present_single_mods = unsafe { ModifyList::new_valid_list(vec![Modify::Present( String::from("attr"), - Value::new_iutf8s("value"), + Value::new_iutf8("value"), )]) }; @@ -2078,20 +2078,20 @@ mod tests { // Assert the changes are there assert!(e.attribute_equality("userid", &PartialValue::new_utf8s("william"))); - assert!(e.attribute_equality("attr", &PartialValue::new_iutf8s("value"))); + assert!(e.attribute_equality("attr", &PartialValue::new_iutf8("value"))); // Assert present for multivalue let present_multivalue_mods = unsafe { ModifyList::new_valid_list(vec![ - Modify::Present(String::from("class"), Value::new_iutf8s("test")), - Modify::Present(String::from("class"), Value::new_iutf8s("multi_test")), + Modify::Present(String::from("class"), Value::new_iutf8("test")), + Modify::Present(String::from("class"), Value::new_iutf8("multi_test")), ]) }; e.apply_modlist(&present_multivalue_mods); - assert!(e.attribute_equality("class", &PartialValue::new_iutf8s("test"))); - assert!(e.attribute_equality("class", &PartialValue::new_iutf8s("multi_test"))); + assert!(e.attribute_equality("class", &PartialValue::new_iutf8("test"))); + assert!(e.attribute_equality("class", &PartialValue::new_iutf8("multi_test"))); // Assert purge on single/multi/empty value let purge_single_mods = @@ -2116,12 +2116,12 @@ mod tests { let remove_mods = unsafe { ModifyList::new_valid_list(vec![Modify::Removed( String::from("attr"), - PartialValue::new_iutf8s("value"), + PartialValue::new_iutf8("value"), )]) }; e.apply_modlist(&present_single_mods); - assert!(e.attribute_equality("attr", &PartialValue::new_iutf8s("value"))); + assert!(e.attribute_equality("attr", &PartialValue::new_iutf8("value"))); e.apply_modlist(&remove_mods); assert!(e.attrs.get("attr").unwrap().is_empty()); @@ -2282,7 +2282,7 @@ mod tests { let mut e: Entry = Entry::new(); e.add_ava("class", Value::new_class("person")); e.add_ava("gidnumber", Value::new_uint32(1300)); - e.add_ava("name", Value::new_iname_s("testperson")); + e.add_ava("name", Value::new_iname("testperson")); e.add_ava("spn", Value::new_spn_str("testperson", "example.com")); e.add_ava( "uuid", @@ -2332,7 +2332,7 @@ mod tests { let mut e2: Entry = Entry::new(); e2.add_ava("class", Value::new_class("person")); - e2.add_ava("name", Value::new_iname_s("testperson")); + e2.add_ava("name", Value::new_iname("testperson")); e2.add_ava("spn", Value::new_spn_str("testperson", "example.com")); let e2 = unsafe { e2.into_sealed_committed() }; diff --git a/kanidmd/src/lib/event.rs b/kanidmd/src/lib/event.rs index b9191b7cc..d172090e6 100644 --- a/kanidmd/src/lib/event.rs +++ b/kanidmd/src/lib/event.rs @@ -36,7 +36,7 @@ impl SearchResult { pub fn new( audit: &mut AuditScope, qs: &QueryServerReadTransaction, - entries: Vec>, + entries: &[Entry], ) -> Result { let entries: Result<_, _> = entries .iter() @@ -461,7 +461,7 @@ impl SearchEvent { audit: &mut AuditScope, qs: &QueryServerReadTransaction, euuid: &Uuid, - filter: Filter, + filter: &Filter, attrs: Option>, ) -> Result { Ok(SearchEvent { @@ -618,7 +618,7 @@ impl DeleteEvent { pub fn from_parts( audit: &mut AuditScope, uat: Option, - filter: Filter, + filter: &Filter, qs: &QueryServerWriteTransaction, ) -> Result { Ok(DeleteEvent { @@ -716,7 +716,7 @@ impl ModifyEvent { audit: &mut AuditScope, uat: Option, target_uuid: Uuid, - proto_ml: ProtoModifyList, + proto_ml: &ProtoModifyList, filter: Filter, qs: &QueryServerWriteTransaction, ) -> Result { @@ -747,7 +747,7 @@ impl ModifyEvent { audit: &mut AuditScope, uat: Option, target_uuid: Uuid, - ml: ModifyList, + ml: &ModifyList, filter: Filter, qs: &QueryServerWriteTransaction, ) -> Result { @@ -775,11 +775,11 @@ impl ModifyEvent { audit: &mut AuditScope, uat: Option, target_uuid: Uuid, - attr: String, + attr: &str, filter: Filter, qs: &QueryServerWriteTransaction, ) -> Result { - let ml = ModifyList::new_purge(attr.as_str()); + let ml = ModifyList::new_purge(attr); let f_uuid = filter_all!(f_eq("uuid", PartialValue::new_uuid(target_uuid))); // Add any supplemental conditions we have. let f = Filter::join_parts_and(f_uuid, filter); @@ -1012,7 +1012,7 @@ impl WhoamiResult { pub fn new( audit: &mut AuditScope, qs: &QueryServerReadTransaction, - e: Entry, + e: &Entry, uat: UserAuthToken, ) -> Result { Ok(WhoamiResult { diff --git a/kanidmd/src/lib/filter.rs b/kanidmd/src/lib/filter.rs index 1c0b6819b..93da40b22 100644 --- a/kanidmd/src/lib/filter.rs +++ b/kanidmd/src/lib/filter.rs @@ -493,8 +493,8 @@ impl FilterComp { fn new_ignore_hidden(fc: FilterComp) -> Self { FilterComp::And(vec![ FilterComp::AndNot(Box::new(FilterComp::Or(vec![ - FilterComp::Eq("class".to_string(), PartialValue::new_iutf8s("tombstone")), - FilterComp::Eq("class".to_string(), PartialValue::new_iutf8s("recycled")), + FilterComp::Eq("class".to_string(), PartialValue::new_iutf8("tombstone")), + FilterComp::Eq("class".to_string(), PartialValue::new_iutf8("recycled")), ]))), fc, ]) @@ -502,7 +502,7 @@ impl FilterComp { fn new_recycled(fc: FilterComp) -> Self { FilterComp::And(vec![ - FilterComp::Eq("class".to_string(), PartialValue::new_iutf8s("recycled")), + FilterComp::Eq("class".to_string(), PartialValue::new_iutf8("recycled")), fc, ]) } @@ -1071,6 +1071,7 @@ impl FilterResolved { // If the f_list_or only has one element, pop it and return. if f_list_new.len() == 1 { + #[allow(clippy::expect_used)] f_list_new.pop().expect("corrupt?") } else { // finally, optimise this list by sorting. @@ -1100,6 +1101,7 @@ impl FilterResolved { // If the f_list_or only has one element, pop it and return. if f_list_new.len() == 1 { + #[allow(clippy::expect_used)] f_list_new.pop().expect("corrupt?") } else { // sort, but reverse so that sub-optimal elements are earlier @@ -1138,8 +1140,8 @@ mod tests { // AFTER let _complex_filt: Filter = filter!(f_and!([ f_or!([ - f_eq("userid", PartialValue::new_iutf8s("test_a")), - f_eq("userid", PartialValue::new_iutf8s("test_b")), + f_eq("userid", PartialValue::new_iutf8("test_a")), + f_eq("userid", PartialValue::new_iutf8("test_b")), ]), f_sub("class", PartialValue::new_class("user")), ])); @@ -1310,12 +1312,12 @@ mod tests { // antisymmetry: if a < b then !(a > b), as well as a > b implying !(a < b); and // These are unindexed so we have to check them this way. - let f_t3b = unsafe { filter_resolved!(f_eq("userid", PartialValue::new_iutf8s(""))) }; + let f_t3b = unsafe { filter_resolved!(f_eq("userid", PartialValue::new_iutf8(""))) }; assert_eq!(f_t1a.partial_cmp(&f_t3b), Some(Ordering::Less)); assert_eq!(f_t3b.partial_cmp(&f_t1a), Some(Ordering::Greater)); // transitivity: a < b and b < c implies a < c. The same must hold for both == and >. - let f_t4b = unsafe { filter_resolved!(f_sub("userid", PartialValue::new_iutf8s(""))) }; + let f_t4b = unsafe { filter_resolved!(f_sub("userid", PartialValue::new_iutf8(""))) }; assert_eq!(f_t1a.partial_cmp(&f_t4b), Some(Ordering::Less)); assert_eq!(f_t3b.partial_cmp(&f_t4b), Some(Ordering::Less)); @@ -1384,32 +1386,32 @@ mod tests { let f_t1a = unsafe { filter_resolved!(f_or!([ - f_eq("userid", PartialValue::new_iutf8s("william")), - f_eq("uidnumber", PartialValue::new_iutf8s("1000")), + f_eq("userid", PartialValue::new_iutf8("william")), + f_eq("uidnumber", PartialValue::new_iutf8("1000")), ])) }; assert!(e.entry_match_no_index(&f_t1a)); let f_t2a = unsafe { filter_resolved!(f_or!([ - f_eq("userid", PartialValue::new_iutf8s("william")), - f_eq("uidnumber", PartialValue::new_iutf8s("1001")), + f_eq("userid", PartialValue::new_iutf8("william")), + f_eq("uidnumber", PartialValue::new_iutf8("1001")), ])) }; assert!(e.entry_match_no_index(&f_t2a)); let f_t3a = unsafe { filter_resolved!(f_or!([ - f_eq("userid", PartialValue::new_iutf8s("alice")), - f_eq("uidnumber", PartialValue::new_iutf8s("1000")), + f_eq("userid", PartialValue::new_iutf8("alice")), + f_eq("uidnumber", PartialValue::new_iutf8("1000")), ])) }; assert!(e.entry_match_no_index(&f_t3a)); let f_t4a = unsafe { filter_resolved!(f_or!([ - f_eq("userid", PartialValue::new_iutf8s("alice")), - f_eq("uidnumber", PartialValue::new_iutf8s("1001")), + f_eq("userid", PartialValue::new_iutf8("alice")), + f_eq("uidnumber", PartialValue::new_iutf8("1001")), ])) }; assert!(!e.entry_match_no_index(&f_t4a)); @@ -1432,32 +1434,32 @@ mod tests { let f_t1a = unsafe { filter_resolved!(f_and!([ - f_eq("userid", PartialValue::new_iutf8s("william")), - f_eq("uidnumber", PartialValue::new_iutf8s("1000")), + f_eq("userid", PartialValue::new_iutf8("william")), + f_eq("uidnumber", PartialValue::new_iutf8("1000")), ])) }; assert!(e.entry_match_no_index(&f_t1a)); let f_t2a = unsafe { filter_resolved!(f_and!([ - f_eq("userid", PartialValue::new_iutf8s("william")), - f_eq("uidnumber", PartialValue::new_iutf8s("1001")), + f_eq("userid", PartialValue::new_iutf8("william")), + f_eq("uidnumber", PartialValue::new_iutf8("1001")), ])) }; assert!(!e.entry_match_no_index(&f_t2a)); let f_t3a = unsafe { filter_resolved!(f_and!([ - f_eq("userid", PartialValue::new_iutf8s("alice")), - f_eq("uidnumber", PartialValue::new_iutf8s("1000")), + f_eq("userid", PartialValue::new_iutf8("alice")), + f_eq("uidnumber", PartialValue::new_iutf8("1000")), ])) }; assert!(!e.entry_match_no_index(&f_t3a)); let f_t4a = unsafe { filter_resolved!(f_and!([ - f_eq("userid", PartialValue::new_iutf8s("alice")), - f_eq("uidnumber", PartialValue::new_iutf8s("1001")), + f_eq("userid", PartialValue::new_iutf8("alice")), + f_eq("uidnumber", PartialValue::new_iutf8("1001")), ])) }; assert!(!e.entry_match_no_index(&f_t4a)); @@ -1478,16 +1480,12 @@ mod tests { .into_sealed_new() }; - let f_t1a = unsafe { - filter_resolved!(f_andnot(f_eq("userid", PartialValue::new_iutf8s("alice")))) - }; + let f_t1a = + unsafe { filter_resolved!(f_andnot(f_eq("userid", PartialValue::new_iutf8("alice")))) }; assert!(e1.entry_match_no_index(&f_t1a)); let f_t2a = unsafe { - filter_resolved!(f_andnot(f_eq( - "userid", - PartialValue::new_iutf8s("william") - ))) + filter_resolved!(f_andnot(f_eq("userid", PartialValue::new_iutf8("william")))) }; assert!(!e1.entry_match_no_index(&f_t2a)); } @@ -1550,8 +1548,8 @@ mod tests { filter_resolved!(f_and!([ f_eq("class", PartialValue::new_class("person")), f_or!([ - f_eq("uidnumber", PartialValue::new_iutf8s("1001")), - f_eq("uidnumber", PartialValue::new_iutf8s("1000")) + f_eq("uidnumber", PartialValue::new_iutf8("1001")), + f_eq("uidnumber", PartialValue::new_iutf8("1000")) ]) ])) }; @@ -1571,8 +1569,8 @@ mod tests { // to determine what attrs we are requesting regardless of the partialvalue. let f_t1a = unsafe { filter_valid!(f_and!([ - f_eq("userid", PartialValue::new_iutf8s("alice")), - f_eq("class", PartialValue::new_iutf8s("1001")), + f_eq("userid", PartialValue::new_iutf8("alice")), + f_eq("class", PartialValue::new_iutf8("1001")), ])) }; @@ -1580,9 +1578,9 @@ mod tests { let f_t2a = unsafe { filter_valid!(f_and!([ - f_eq("userid", PartialValue::new_iutf8s("alice")), - f_eq("class", PartialValue::new_iutf8s("1001")), - f_eq("userid", PartialValue::new_iutf8s("claire")), + f_eq("userid", PartialValue::new_iutf8("alice")), + f_eq("class", PartialValue::new_iutf8("1001")), + f_eq("userid", PartialValue::new_iutf8("claire")), ])) }; diff --git a/kanidmd/src/lib/idm/account.rs b/kanidmd/src/lib/idm/account.rs index b2d13a811..8245fa482 100644 --- a/kanidmd/src/lib/idm/account.rs +++ b/kanidmd/src/lib/idm/account.rs @@ -98,33 +98,33 @@ pub(crate) struct Account { impl Account { pub(crate) fn try_from_entry_ro( au: &mut AuditScope, - value: Entry, + value: &Entry, qs: &mut QueryServerReadTransaction, ) -> Result { lperf_trace_segment!(au, "idm::account::try_from_entry_ro", || { - let groups = Group::try_from_account_entry_ro(au, &value, qs)?; + let groups = Group::try_from_account_entry_ro(au, value, qs)?; try_from_entry!(value, groups) }) } pub(crate) fn try_from_entry_rw( au: &mut AuditScope, - value: Entry, + value: &Entry, qs: &mut QueryServerWriteTransaction, ) -> Result { - let groups = Group::try_from_account_entry_rw(au, &value, qs)?; + let groups = Group::try_from_account_entry_rw(au, value, qs)?; try_from_entry!(value, groups) } #[cfg(test)] pub(crate) fn try_from_entry_no_groups( - value: Entry, + value: &Entry, ) -> Result { try_from_entry!(value, vec![]) } // Could this actually take a claims list and application instead? - pub(crate) fn to_userauthtoken(&self, claims: Vec) -> Option { + pub(crate) fn to_userauthtoken(&self, claims: &[Claim]) -> Option { // This could consume self? // The cred handler provided is what authenticated this user, so we can use it to // process what the proper claims should be. @@ -161,13 +161,13 @@ impl Account { match &self.primary { // Change the cred Some(primary) => { - let ncred = primary.set_password(cleartext); + let ncred = primary.set_password(cleartext)?; let vcred = Value::new_credential("primary", ncred); Ok(ModifyList::new_purge_and_set("primary_credential", vcred)) } // Make a new credential instead None => { - let ncred = Credential::new_password_only(cleartext); + let ncred = Credential::new_password_only(cleartext)?; let vcred = Value::new_credential("primary", ncred); Ok(ModifyList::new_purge_and_set("primary_credential", vcred)) } diff --git a/kanidmd/src/lib/idm/authsession.rs b/kanidmd/src/lib/idm/authsession.rs index d25e05298..345d8e2ba 100644 --- a/kanidmd/src/lib/idm/authsession.rs +++ b/kanidmd/src/lib/idm/authsession.rs @@ -136,7 +136,7 @@ impl CredHandler { _ => { match cred { AuthCredential::Password(cleartext) => { - if pw.verify(cleartext.as_str()) { + if pw.verify(cleartext.as_str()).unwrap_or(false) { lsecurity!(au, "Handler::Password -> Result::Success"); CredState::Success(Vec::new()) } else { @@ -170,7 +170,7 @@ impl CredHandler { match cred { AuthCredential::Password(cleartext) => { // if pw -> check - if pw_totp.pw.verify(cleartext.as_str()) { + if pw_totp.pw.verify(cleartext.as_str()).unwrap_or(false) { pw_totp.pw_state = CredVerifyState::Success; match pw_totp.totp_state { CredVerifyState::Init => { @@ -366,7 +366,7 @@ impl AuthSession { self.finished = true; let uat = self .account - .to_userauthtoken(claims) + .to_userauthtoken(&claims) .ok_or(OperationError::InvalidState)?; Ok(AuthState::Success(uat)) } @@ -492,7 +492,7 @@ mod tests { // create the ent let mut account = entry_str_to_account!(JSON_ADMIN_V1); // manually load in a cred - let cred = Credential::new_password_only("test_password"); + let cred = Credential::new_password_only("test_password").unwrap(); account.primary = Some(cred); // now check @@ -549,7 +549,9 @@ mod tests { let pw_good = "test_password"; let pw_bad = "bad_password"; - let cred = Credential::new_password_only(pw_good).update_totp(totp); + let cred = Credential::new_password_only(pw_good) + .unwrap() + .update_totp(totp); // add totp also account.primary = Some(cred); diff --git a/kanidmd/src/lib/idm/group.rs b/kanidmd/src/lib/idm/group.rs index b8f734f9f..d81fe9b13 100644 --- a/kanidmd/src/lib/idm/group.rs +++ b/kanidmd/src/lib/idm/group.rs @@ -47,8 +47,7 @@ macro_rules! try_from_account_e { e })?; // Now convert the group entries to groups. - let groups: Result, _> = - ges.into_iter().map(Group::try_from_entry).collect(); + let groups: Result, _> = ges.iter().map(Group::try_from_entry).collect(); groups.map_err(|e| { // log e @@ -90,7 +89,7 @@ impl Group { } pub fn try_from_entry( - value: Entry, + value: &Entry, ) -> Result { if !value.attribute_value_pres("class", &PVCLASS_GROUP) { return Err(OperationError::InvalidAccountState( diff --git a/kanidmd/src/lib/idm/radius.rs b/kanidmd/src/lib/idm/radius.rs index c5b0db6de..a63069fbe 100644 --- a/kanidmd/src/lib/idm/radius.rs +++ b/kanidmd/src/lib/idm/radius.rs @@ -24,7 +24,7 @@ pub(crate) struct RadiusAccount { impl RadiusAccount { pub(crate) fn try_from_entry_reduced( au: &mut AuditScope, - value: Entry, + value: &Entry, qs: &mut QueryServerReadTransaction, ) -> Result { if !value.attribute_value_pres("class", &PVCLASS_ACCOUNT) { diff --git a/kanidmd/src/lib/idm/server.rs b/kanidmd/src/lib/idm/server.rs index 2815c4eec..b0623fb29 100644 --- a/kanidmd/src/lib/idm/server.rs +++ b/kanidmd/src/lib/idm/server.rs @@ -172,7 +172,7 @@ impl<'a> IdmServerWriteTransaction<'a> { // typing and functionality so we can assess what auth types can // continue, and helps to keep non-needed entry specific data // out of the LRU. - let account = Account::try_from_entry_ro(au, entry, &mut self.qs_read)?; + let account = Account::try_from_entry_ro(au, &entry, &mut self.qs_read)?; let auth_session = AuthSession::new(au, account, init.appid.clone()); // Get the set of mechanisms that can proceed. This is tied @@ -240,7 +240,7 @@ impl<'a> IdmServerWriteTransaction<'a> { .qs_read .internal_search_uuid(au, &uae.target) .and_then(|account_entry| { - UnixUserAccount::try_from_entry_ro(au, account_entry, &mut self.qs_read) + UnixUserAccount::try_from_entry_ro(au, &account_entry, &mut self.qs_read) }) .map_err(|e| { ladmin_error!(au, "Failed to start auth unix -> {:?}", e); @@ -254,7 +254,7 @@ impl<'a> IdmServerWriteTransaction<'a> { pub fn auth_ldap( &mut self, au: &mut AuditScope, - lae: LdapAuthEvent, + lae: &LdapAuthEvent, _ct: Duration, ) -> Result, OperationError> { // TODO #59: Implement soft lock checking for unix creds here! @@ -271,14 +271,15 @@ impl<'a> IdmServerWriteTransaction<'a> { // if anonymous if lae.target == *UUID_ANONYMOUS { // TODO: #59 We should have checked if anonymous was locked by now! - let account = Account::try_from_entry_ro(au, account_entry, &mut self.qs_read)?; + let account = Account::try_from_entry_ro(au, &account_entry, &mut self.qs_read)?; Ok(Some(LdapBoundToken { spn: account.spn, uuid: *UUID_ANONYMOUS, effective_uuid: *UUID_ANONYMOUS, })) } else { - let account = UnixUserAccount::try_from_entry_ro(au, account_entry, &mut self.qs_read)?; + let account = + UnixUserAccount::try_from_entry_ro(au, &account_entry, &mut self.qs_read)?; if account .verify_unix_credential(au, lae.cleartext.as_str())? .is_some() @@ -312,7 +313,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> { .qs_read .impersonate_search_ext_uuid(au, &rate.target, &rate.event) .and_then(|account_entry| { - RadiusAccount::try_from_entry_reduced(au, account_entry, &mut self.qs_read) + RadiusAccount::try_from_entry_reduced(au, &account_entry, &mut self.qs_read) }) .map_err(|e| { ladmin_error!(au, "Failed to start radius auth token {:?}", e); @@ -331,7 +332,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> { .qs_read .impersonate_search_ext_uuid(au, &uute.target, &uute.event) .and_then(|account_entry| { - UnixUserAccount::try_from_entry_reduced(au, account_entry, &mut self.qs_read) + UnixUserAccount::try_from_entry_reduced(au, &account_entry, &mut self.qs_read) }) .map_err(|e| { ladmin_error!(au, "Failed to start unix user token -> {:?}", e); @@ -349,7 +350,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> { let group = self .qs_read .impersonate_search_ext_uuid(au, &uute.target, &uute.event) - .and_then(UnixGroup::try_from_entry_reduced) + .and_then(|e| UnixGroup::try_from_entry_reduced(&e)) .map_err(|e| { ladmin_error!(au, "Failed to start unix group token {:?}", e); e @@ -413,7 +414,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { // check a password badlist to eliminate more content // we check the password as "lower case" to help eliminate possibilities - let lc_password = PartialValue::new_iutf8s(cleartext); + let lc_password = PartialValue::new_iutf8(cleartext); let badlist_entry = self .qs_write .internal_search_uuid(au, &UUID_SYSTEM_CONFIG) @@ -439,7 +440,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { .qs_write .internal_search_uuid(au, target) .and_then(|account_entry| { - Account::try_from_entry_rw(au, account_entry, &mut self.qs_write) + Account::try_from_entry_rw(au, &account_entry, &mut self.qs_write) }) .map_err(|e| { ladmin_error!(au, "Failed to search account {:?}", e); @@ -495,10 +496,10 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { .impersonate_modify( au, // Filter as executed - filter!(f_eq("uuid", PartialValue::new_uuidr(&pce.target))), + &filter!(f_eq("uuid", PartialValue::new_uuidr(&pce.target))), // Filter as intended (acp) - filter_all!(f_eq("uuid", PartialValue::new_uuidr(&pce.target))), - modlist, + &filter_all!(f_eq("uuid", PartialValue::new_uuidr(&pce.target))), + &modlist, &pce.event, ) .map_err(|e| { @@ -520,7 +521,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { .internal_search_uuid(au, &pce.target) .and_then(|account_entry| { // Assert the account is unix and valid. - UnixUserAccount::try_from_entry_rw(au, account_entry, &mut self.qs_write) + UnixUserAccount::try_from_entry_rw(au, &account_entry, &mut self.qs_write) }) .map_err(|e| { ladmin_error!(au, "Failed to start set unix account password {:?}", e); @@ -560,10 +561,10 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { .impersonate_modify( au, // Filter as executed - filter!(f_eq("uuid", PartialValue::new_uuidr(&pce.target))), + &filter!(f_eq("uuid", PartialValue::new_uuidr(&pce.target))), // Filter as intended (acp) - filter_all!(f_eq("uuid", PartialValue::new_uuidr(&pce.target))), - modlist, + &filter_all!(f_eq("uuid", PartialValue::new_uuidr(&pce.target))), + &modlist, &pce.event, ) .map_err(|e| { @@ -576,16 +577,16 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { pub fn recover_account( &mut self, au: &mut AuditScope, - name: String, - cleartext: String, + name: &str, + cleartext: &str, ) -> Result<(), OperationError> { // name to uuid - let target = self.qs_write.name_to_uuid(au, name.as_str()).map_err(|e| { + let target = self.qs_write.name_to_uuid(au, name).map_err(|e| { ladmin_error!(au, "name to uuid failed {:?}", e); e })?; // internal pce. - let pce = PasswordChangeEvent::new_internal(&target, cleartext.as_str(), None); + let pce = PasswordChangeEvent::new_internal(&target, cleartext, None); // now set_account_password. self.set_account_password(au, &pce) } @@ -620,10 +621,10 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { .impersonate_modify( au, // Filter as executed - filter!(f_eq("uuid", PartialValue::new_uuidr(&gpe.target))), + &filter!(f_eq("uuid", PartialValue::new_uuidr(&gpe.target))), // Filter as intended (acp) - filter_all!(f_eq("uuid", PartialValue::new_uuidr(&gpe.target))), - modlist, + &filter_all!(f_eq("uuid", PartialValue::new_uuidr(&gpe.target))), + &modlist, // Provide the event to impersonate &gpe.event, ) @@ -659,10 +660,10 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { .impersonate_modify( au, // Filter as executed - filter!(f_eq("uuid", PartialValue::new_uuidr(&rrse.target))), + &filter!(f_eq("uuid", PartialValue::new_uuidr(&rrse.target))), // Filter as intended (acp) - filter_all!(f_eq("uuid", PartialValue::new_uuidr(&rrse.target))), - modlist, + &filter_all!(f_eq("uuid", PartialValue::new_uuidr(&rrse.target))), + &modlist, // Provide the event to impersonate &rrse.event, ) @@ -727,7 +728,11 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { let session = self .mfareg_sessions .remove(&sessionid) - .expect("Session within transaction vanished!"); + .ok_or(OperationError::InvalidState) + .map_err(|e| { + ladmin_error!(au, "Session within transaction vanished!"); + e + })?; // reg the token let modlist = session.account.gen_totp_mod(token).map_err(|e| { ladmin_error!(au, "Failed to gen totp mod {:?}", e); @@ -738,10 +743,10 @@ impl<'a> IdmServerProxyWriteTransaction<'a> { .impersonate_modify( au, // Filter as executed - filter!(f_eq("uuid", PartialValue::new_uuidr(&session.account.uuid))), + &filter!(f_eq("uuid", PartialValue::new_uuidr(&session.account.uuid))), // Filter as intended (acp) - filter_all!(f_eq("uuid", PartialValue::new_uuidr(&session.account.uuid))), - modlist, + &filter_all!(f_eq("uuid", PartialValue::new_uuidr(&session.account.uuid))), + &modlist, &vte.event, ) .map_err(|e| { @@ -913,7 +918,7 @@ mod tests { qs: &QueryServer, pw: &str, ) -> Result<(), OperationError> { - let cred = Credential::new_password_only(pw); + let cred = Credential::new_password_only(pw)?; let v_cred = Value::new_credential("primary", cred); let qs_write = qs.write(duration_from_epoch_now()); diff --git a/kanidmd/src/lib/idm/unix.rs b/kanidmd/src/lib/idm/unix.rs index ebdc267f3..8b3aec7fd 100644 --- a/kanidmd/src/lib/idm/unix.rs +++ b/kanidmd/src/lib/idm/unix.rs @@ -105,28 +105,28 @@ macro_rules! try_from_entry { impl UnixUserAccount { pub(crate) fn try_from_entry_rw( au: &mut AuditScope, - value: Entry, + value: &Entry, qs: &mut QueryServerWriteTransaction, ) -> Result { - let groups = UnixGroup::try_from_account_entry_rw(au, &value, qs)?; + let groups = UnixGroup::try_from_account_entry_rw(au, value, qs)?; try_from_entry!(value, groups) } pub(crate) fn try_from_entry_ro( au: &mut AuditScope, - value: Entry, + value: &Entry, qs: &mut QueryServerReadTransaction, ) -> Result { - let groups = UnixGroup::try_from_account_entry_ro(au, &value, qs)?; + let groups = UnixGroup::try_from_account_entry_ro(au, value, qs)?; try_from_entry!(value, groups) } pub(crate) fn try_from_entry_reduced( au: &mut AuditScope, - value: Entry, + value: &Entry, qs: &mut QueryServerReadTransaction, ) -> Result { - let groups = UnixGroup::try_from_account_entry_red_ro(au, &value, qs)?; + let groups = UnixGroup::try_from_account_entry_red_ro(au, value, qs)?; try_from_entry!(value, groups) } @@ -154,7 +154,7 @@ impl UnixUserAccount { &self, cleartext: &str, ) -> Result, OperationError> { - let ncred = Credential::new_password_only(cleartext); + let ncred = Credential::new_password_only(cleartext)?; let vcred = Value::new_credential("unix", ncred); Ok(ModifyList::new_purge_and_set("unix_password", vcred)) } @@ -169,7 +169,7 @@ impl UnixUserAccount { match &self.cred { Some(cred) => match &cred.password { Some(pw) => { - if pw.verify(cleartext) { + if pw.verify(cleartext)? { lsecurity!(au, "Successful unix cred handling"); Some(self.to_unixusertoken()).transpose() } else { @@ -304,7 +304,7 @@ macro_rules! try_from_account_group_e { ])); let ges: Vec<_> = $qs.internal_search($au, f)?; let groups: Result, _> = iter::once(Ok(upg)) - .chain(ges.into_iter().map(UnixGroup::try_from_entry)) + .chain(ges.iter().map(UnixGroup::try_from_entry)) .collect(); groups } @@ -342,13 +342,13 @@ impl UnixGroup { } pub fn try_from_entry_reduced( - value: Entry, + value: &Entry, ) -> Result { try_from_group_e!(value) } pub fn try_from_entry( - value: Entry, + value: &Entry, ) -> Result { try_from_group_e!(value) } diff --git a/kanidmd/src/lib/ldap.rs b/kanidmd/src/lib/ldap.rs index 38a92ddd4..e00c17bb4 100644 --- a/kanidmd/src/lib/ldap.rs +++ b/kanidmd/src/lib/ldap.rs @@ -251,7 +251,7 @@ impl LdapServer { au, &idm_read.qs_read, &uat.effective_uuid, - filter, + &filter, attrs, ) })?; @@ -343,10 +343,13 @@ impl LdapServer { let ct = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) - .expect("Clock failure!"); + .map_err(|e| { + ladmin_error!(au, "Clock Error -> {:?}", e); + OperationError::InvalidState + })?; let lae = LdapAuthEvent::from_parts(au, target_uuid, pw.to_string())?; - idm_write.auth_ldap(au, lae, ct).and_then(|r| { + idm_write.auth_ldap(au, &lae, ct).and_then(|r| { idm_write.commit(au).map(|_| { if r.is_some() { lsecurity!(au, "✅ LDAP Bind success {}", dn); diff --git a/kanidmd/src/lib/lib.rs b/kanidmd/src/lib/lib.rs index df0ee21e3..5041a76b0 100644 --- a/kanidmd/src/lib/lib.rs +++ b/kanidmd/src/lib/lib.rs @@ -2,7 +2,7 @@ #![warn(unused_extern_crates)] #![deny(clippy::unwrap_used)] #![deny(clippy::expect_used)] -#![deny(clippy::panic)] +// #![deny(clippy::panic)] #![deny(clippy::unreachable)] #![deny(clippy::await_holding_lock)] #![deny(clippy::needless_pass_by_value)] diff --git a/kanidmd/src/lib/macros.rs b/kanidmd/src/lib/macros.rs index fe15ebbed..5e195a67c 100644 --- a/kanidmd/src/lib/macros.rs +++ b/kanidmd/src/lib/macros.rs @@ -108,7 +108,7 @@ macro_rules! entry_str_to_account { let e = unsafe { e.into_sealed_committed() }; - Account::try_from_entry_no_groups(e).expect("Account conversion failure") + Account::try_from_entry_no_groups(&e).expect("Account conversion failure") }}; } diff --git a/kanidmd/src/lib/plugins/attrunique.rs b/kanidmd/src/lib/plugins/attrunique.rs index 946b9c469..fa23674fa 100644 --- a/kanidmd/src/lib/plugins/attrunique.rs +++ b/kanidmd/src/lib/plugins/attrunique.rs @@ -297,7 +297,7 @@ mod tests { ),])), ModifyList::new_list(vec![ Modify::Purged("name".to_string()), - Modify::Present("name".to_string(), Value::new_iname_s("testgroup_a")) + Modify::Present("name".to_string(), Value::new_iname("testgroup_a")) ]), None, |_, _| {} @@ -340,7 +340,7 @@ mod tests { ])), ModifyList::new_list(vec![ Modify::Purged("name".to_string()), - Modify::Present("name".to_string(), Value::new_iname_s("testgroup")) + Modify::Present("name".to_string(), Value::new_iname("testgroup")) ]), None, |_, _| {} diff --git a/kanidmd/src/lib/plugins/domain.rs b/kanidmd/src/lib/plugins/domain.rs index 7b84afbf0..32a044634 100644 --- a/kanidmd/src/lib/plugins/domain.rs +++ b/kanidmd/src/lib/plugins/domain.rs @@ -43,7 +43,7 @@ impl Plugin for Domain { ltrace!(au, "plugin_domain: Applying uuid transform"); // We only apply this if one isn't provided. if !e.attribute_pres("domain_name") { - let n = Value::new_iname_s("example.com"); + let n = Value::new_iname("example.com"); e.set_ava("domain_name", btreeset![n]); ltrace!(au, "plugin_domain: Applying domain_name transform"); } diff --git a/kanidmd/src/lib/plugins/memberof.rs b/kanidmd/src/lib/plugins/memberof.rs index 30d9758fd..f3d3bd830 100644 --- a/kanidmd/src/lib/plugins/memberof.rs +++ b/kanidmd/src/lib/plugins/memberof.rs @@ -123,7 +123,7 @@ fn apply_memberof( .collect() )); - let mut work_set = qs.internal_search_writeable(au, filt)?; + let mut work_set = qs.internal_search_writeable(au, &filt)?; // Load the vecdeque with this batch. while let Some((pre, mut tgte)) = work_set.pop() { diff --git a/kanidmd/src/lib/plugins/password_import.rs b/kanidmd/src/lib/plugins/password_import.rs index 5515b2db2..5f181388f 100644 --- a/kanidmd/src/lib/plugins/password_import.rs +++ b/kanidmd/src/lib/plugins/password_import.rs @@ -38,8 +38,7 @@ impl Plugin for PasswordImport { debug_assert!(!vs.is_empty()); let im_pw = vs.first() - .unwrap() - .to_str() + .and_then(|v| v.to_str()) .ok_or_else(|| OperationError::Plugin(PluginError::PasswordImport("password_import has incorrect value type".to_string())))?; // convert the import_password to a cred @@ -87,7 +86,7 @@ impl Plugin for PasswordImport { let vs: Vec<_> = vs.into_iter().collect(); debug_assert!(!vs.is_empty()); - let im_pw = vs.first().unwrap().to_str().ok_or_else(|| { + let im_pw = vs.first().and_then(|v| v.to_str()).ok_or_else(|| { OperationError::Plugin(PluginError::PasswordImport( "password_import has incorrect value type".to_string(), )) @@ -181,7 +180,7 @@ mod tests { run_modify_test!( Ok(()), preload, - filter!(f_eq("name", PartialValue::new_iutf8s("testperson"))), + filter!(f_eq("name", PartialValue::new_iutf8("testperson"))), ModifyList::new_list(vec![Modify::Present( "password_import".to_string(), Value::from(IMPORT_HASH) @@ -206,7 +205,7 @@ mod tests { }"#, ); - let c = Credential::new_password_only("password"); + let c = Credential::new_password_only("password").unwrap(); ea.add_ava("primary_credential", Value::new_credential("primary", c)); let preload = vec![ea]; @@ -214,7 +213,7 @@ mod tests { run_modify_test!( Ok(()), preload, - filter!(f_eq("name", PartialValue::new_iutf8s("testperson"))), + filter!(f_eq("name", PartialValue::new_iutf8("testperson"))), ModifyList::new_list(vec![Modify::Present( "password_import".to_string(), Value::from(IMPORT_HASH) @@ -240,7 +239,9 @@ mod tests { ); let totp = TOTP::generate_secure("test_totp".to_string(), TOTP_DEFAULT_STEP); - let c = Credential::new_password_only("password").update_totp(totp); + let c = Credential::new_password_only("password") + .unwrap() + .update_totp(totp); ea.add_ava("primary_credential", Value::new_credential("primary", c)); let preload = vec![ea]; @@ -248,7 +249,7 @@ mod tests { run_modify_test!( Ok(()), preload, - filter!(f_eq("name", PartialValue::new_iutf8s("testperson"))), + filter!(f_eq("name", PartialValue::new_iutf8("testperson"))), ModifyList::new_list(vec![Modify::Present( "password_import".to_string(), Value::from(IMPORT_HASH) diff --git a/kanidmd/src/lib/plugins/protected.rs b/kanidmd/src/lib/plugins/protected.rs index 00140b6f3..ce2b56d9e 100644 --- a/kanidmd/src/lib/plugins/protected.rs +++ b/kanidmd/src/lib/plugins/protected.rs @@ -323,8 +323,8 @@ mod tests { preload, filter!(f_eq("classname", PartialValue::new_class("testclass"))), modlist!([ - m_pres("may", &Value::new_iutf8s("name")), - m_pres("must", &Value::new_iutf8s("name")), + m_pres("may", &Value::new_iutf8("name")), + m_pres("must", &Value::new_iutf8("name")), ]), Some(JSON_ADMIN_V1), |_, _| {} diff --git a/kanidmd/src/lib/plugins/refint.rs b/kanidmd/src/lib/plugins/refint.rs index 0abac9abe..21cbea4a9 100644 --- a/kanidmd/src/lib/plugins/refint.rs +++ b/kanidmd/src/lib/plugins/refint.rs @@ -190,7 +190,7 @@ impl Plugin for ReferentialIntegrity { .map(|e| PartialValue::new_refer(*e.get_uuid())) .collect(); - let work_set = qs.internal_search_writeable(au, filt)?; + let work_set = qs.internal_search_writeable(au, &filt)?; let (pre_candidates, candidates) = work_set .into_iter() diff --git a/kanidmd/src/lib/plugins/spn.rs b/kanidmd/src/lib/plugins/spn.rs index faf503bf3..9bb6169ff 100644 --- a/kanidmd/src/lib/plugins/spn.rs +++ b/kanidmd/src/lib/plugins/spn.rs @@ -79,6 +79,7 @@ impl Plugin for Spn { if e.attribute_value_pres("class", &CLASS_GROUP) || e.attribute_value_pres("class", &CLASS_ACCOUNT) { + // We do this in the loop so that we don't get it unless required. if domain_name.is_none() { domain_name = Some(Self::get_domain_name(au, qs)?); } @@ -86,7 +87,15 @@ impl Plugin for Spn { // It should be impossible to hit this expect as the is_none case should cause it to be replaced above. let some_domain_name = domain_name .as_ref() - .expect("Domain name option memory corruption has occured."); + .ok_or(OperationError::InvalidEntryState) + .map_err(|e| { + ladmin_error!( + au, + "Domain name option memory corruption may have occured. {:?}", + e + ); + e + })?; let spn = e .generate_spn(some_domain_name.as_str()) @@ -127,7 +136,15 @@ impl Plugin for Spn { // It should be impossible to hit this expect as the is_none case should cause it to be replaced above. let some_domain_name = domain_name .as_ref() - .expect("Domain name option memory corruption has occured."); + .ok_or(OperationError::InvalidEntryState) + .map_err(|e| { + ladmin_error!( + au, + "Domain name option memory corruption may have occured. {:?}", + e + ); + e + })?; let spn = e .generate_spn(some_domain_name.as_str()) @@ -189,11 +206,11 @@ impl Plugin for Spn { // within the transaction, just incase! qs.internal_modify( au, - filter!(f_or!([ + &filter!(f_or!([ f_eq("class", PartialValue::new_class("group")), f_eq("class", PartialValue::new_class("account")) ])), - modlist!([m_purge("spn")]), + &modlist!([m_purge("spn")]), ) } diff --git a/kanidmd/src/lib/repl/cid.rs b/kanidmd/src/lib/repl/cid.rs index faa5aa34d..52bfca5d7 100644 --- a/kanidmd/src/lib/repl/cid.rs +++ b/kanidmd/src/lib/repl/cid.rs @@ -34,12 +34,15 @@ impl Cid { } } + #[allow(clippy::expect_used)] pub fn sub_secs(&self, secs: u64) -> Result { self.ts .checked_sub(Duration::from_secs(secs)) .map(|r| Cid { - d_uuid: Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(), - s_uuid: Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(), + d_uuid: Uuid::parse_str("00000000-0000-0000-0000-000000000000") + .expect("Invalid compiled d_uuid"), + s_uuid: Uuid::parse_str("00000000-0000-0000-0000-000000000000") + .expect("Invalid compiled s_uuid"), ts: r, }) .ok_or(OperationError::InvalidReplCID) diff --git a/kanidmd/src/lib/schema.rs b/kanidmd/src/lib/schema.rs index 25bd28c68..f038694cd 100644 --- a/kanidmd/src/lib/schema.rs +++ b/kanidmd/src/lib/schema.rs @@ -152,7 +152,7 @@ impl SchemaAttribute { // The get_ava_opt_index handles the optional case for us :) let index = value .get_ava_opt_index("index") - .and_then(|vv: Vec<&IndexType>| Ok(vv.into_iter().cloned().collect())) + .map(|vv: Vec<&IndexType>| vv.into_iter().cloned().collect()) .map_err(|_| { ladmin_error!(audit, "invalid index"); OperationError::InvalidSchemaState("Invalid index".to_string()) @@ -641,8 +641,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("class"), SchemaAttribute { name: String::from("class"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_CLASS) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_CLASS, description: String::from("The set of classes defining an object"), multivalue: true, unique: false, @@ -655,8 +654,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("uuid"), SchemaAttribute { name: String::from("uuid"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_UUID) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_UUID, description: String::from("The universal unique id of the object"), multivalue: false, // Uniqueness is handled by base.rs, not attrunique here due to @@ -671,8 +669,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("last_modified_cid"), SchemaAttribute { name: String::from("last_modified_cid"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_LAST_MOD_CID) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_LAST_MOD_CID, description: String::from("The cid of the last change to this object"), multivalue: false, // Uniqueness is handled by base.rs, not attrunique here due to @@ -687,8 +684,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("name"), SchemaAttribute { name: String::from("name"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_NAME) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_NAME, description: String::from("The shortform name of an object"), multivalue: false, unique: true, @@ -701,8 +697,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("spn"), SchemaAttribute { name: String::from("spn"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_SPN) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_SPN, description: String::from( "The service principle name of an object, unique across all domain trusts", ), @@ -717,8 +712,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("attributename"), SchemaAttribute { name: String::from("attributename"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ATTRIBUTENAME) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ATTRIBUTENAME, description: String::from("The name of a schema attribute"), multivalue: false, unique: true, @@ -731,8 +725,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("classname"), SchemaAttribute { name: String::from("classname"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_CLASSNAME) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_CLASSNAME, description: String::from("The name of a schema class"), multivalue: false, unique: true, @@ -745,8 +738,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("description"), SchemaAttribute { name: String::from("description"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_DESCRIPTION) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_DESCRIPTION, description: String::from("A description of an attribute, object or class"), multivalue: true, unique: false, @@ -757,7 +749,7 @@ impl<'a> SchemaWriteTransaction<'a> { ); self.attributes.insert(String::from("multivalue"), SchemaAttribute { name: String::from("multivalue"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_MULTIVALUE).expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_MULTIVALUE, description: String::from("If true, this attribute is able to store multiple values rather than just a single value."), multivalue: false, unique: false, @@ -767,7 +759,7 @@ impl<'a> SchemaWriteTransaction<'a> { }); self.attributes.insert(String::from("phantom"), SchemaAttribute { name: String::from("phantom"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_PHANTOM).expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_PHANTOM, description: String::from("If true, this attribute must NOT be present in any may/must sets of a class as. This represents generated attributes."), multivalue: false, unique: false, @@ -777,7 +769,7 @@ impl<'a> SchemaWriteTransaction<'a> { }); self.attributes.insert(String::from("unique"), SchemaAttribute { name: String::from("unique"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_UNIQUE).expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_UNIQUE, description: String::from("If true, this attribute must store a unique value through out the database."), multivalue: false, unique: false, @@ -789,8 +781,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("index"), SchemaAttribute { name: String::from("index"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_INDEX) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_INDEX, description: String::from( "Describe the indexes to apply to instances of this attribute.", ), @@ -805,8 +796,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("syntax"), SchemaAttribute { name: String::from("syntax"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_SYNTAX) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_SYNTAX, description: String::from( "Describe the syntax of this attribute. This affects indexing and sorting.", ), @@ -821,8 +811,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("systemmay"), SchemaAttribute { name: String::from("systemmay"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_SYSTEMMAY) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_SYSTEMMAY, description: String::from( "A list of system provided optional attributes this class can store.", ), @@ -837,8 +826,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("may"), SchemaAttribute { name: String::from("may"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_MAY) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_MAY, description: String::from( "A user modifiable list of optional attributes this class can store.", ), @@ -853,8 +841,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("systemmust"), SchemaAttribute { name: String::from("systemmust"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_SYSTEMMUST) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_SYSTEMMUST, description: String::from( "A list of system provided required attributes this class must store.", ), @@ -869,8 +856,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("must"), SchemaAttribute { name: String::from("must"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_MUST) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_MUST, description: String::from( "A user modifiable list of required attributes this class must store.", ), @@ -887,8 +873,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_enable"), SchemaAttribute { name: String::from("acp_enable"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_ENABLE) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_ENABLE, description: String::from("A flag to determine if this ACP is active for application. True is enabled, and enforce. False is checked but not enforced."), multivalue: false, unique: false, @@ -902,8 +887,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_receiver"), SchemaAttribute { name: String::from("acp_receiver"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_RECEIVER) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_RECEIVER, description: String::from( "Who the ACP applies to, constraining or allowing operations.", ), @@ -918,8 +902,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_targetscope"), SchemaAttribute { name: String::from("acp_targetscope"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_TARGETSCOPE) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_TARGETSCOPE, description: String::from( "The effective targets of the ACP, IE what will be acted upon.", ), @@ -934,8 +917,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_search_attr"), SchemaAttribute { name: String::from("acp_search_attr"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_SEARCH_ATTR) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_SEARCH_ATTR, description: String::from("The attributes that may be viewed or searched by the reciever on targetscope."), multivalue: true, unique: false, @@ -948,8 +930,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_create_class"), SchemaAttribute { name: String::from("acp_create_class"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_CREATE_CLASS) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_CREATE_CLASS, description: String::from( "The set of classes that can be created on a new entry.", ), @@ -964,8 +945,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_create_attr"), SchemaAttribute { name: String::from("acp_create_attr"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_CREATE_ATTR) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_CREATE_ATTR, description: String::from( "The set of attribute types that can be created on an entry.", ), @@ -981,8 +961,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_modify_removedattr"), SchemaAttribute { name: String::from("acp_modify_removedattr"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_MODIFY_REMOVEDATTR) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_MODIFY_REMOVEDATTR, description: String::from("The set of attribute types that could be removed or purged in a modification."), multivalue: true, unique: false, @@ -995,8 +974,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_modify_presentattr"), SchemaAttribute { name: String::from("acp_modify_presentattr"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_MODIFY_PRESENTATTR) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_MODIFY_PRESENTATTR, description: String::from("The set of attribute types that could be added or asserted in a modification."), multivalue: true, unique: false, @@ -1009,8 +987,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("acp_modify_class"), SchemaAttribute { name: String::from("acp_modify_class"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ACP_MODIFY_CLASS) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ACP_MODIFY_CLASS, description: String::from("The set of class values that could be asserted or added to an entry. Only applies to modify::present operations on class."), multivalue: true, unique: false, @@ -1024,8 +1001,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("memberof"), SchemaAttribute { name: String::from("memberof"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_MEMBEROF) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_MEMBEROF, description: String::from("reverse group membership of the object"), multivalue: true, unique: false, @@ -1038,8 +1014,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("directmemberof"), SchemaAttribute { name: String::from("directmemberof"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_DIRECTMEMBEROF) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_DIRECTMEMBEROF, description: String::from("reverse direct group membership of the object"), multivalue: true, unique: false, @@ -1052,8 +1027,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("member"), SchemaAttribute { name: String::from("member"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_MEMBER) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_MEMBER, description: String::from("List of members of the group"), multivalue: true, unique: false, @@ -1067,8 +1041,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("version"), SchemaAttribute { name: String::from("version"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_VERSION) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_VERSION, description: String::from( "The systems internal migration version for provided objects", ), @@ -1084,8 +1057,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("domain"), SchemaAttribute { name: String::from("domain"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_DOMAIN) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_DOMAIN, description: String::from("A DNS Domain name entry."), multivalue: true, unique: false, @@ -1098,8 +1070,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("claim"), SchemaAttribute { name: String::from("claim"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_CLAIM) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_CLAIM, description: String::from("The spn of a claim this entry holds"), multivalue: true, unique: false, @@ -1112,8 +1083,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("password_import"), SchemaAttribute { name: String::from("password_import"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_PASSWORD_IMPORT) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_PASSWORD_IMPORT, description: String::from("An imported password hash from an external system."), multivalue: true, unique: false, @@ -1128,7 +1098,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("dn"), SchemaAttribute { name: String::from("dn"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_DN).expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_DN, description: String::from("An LDAP Compatible DN"), multivalue: false, unique: false, @@ -1141,8 +1111,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("entryuuid"), SchemaAttribute { name: String::from("entryuuid"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_ENTRYUUID) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_ENTRYUUID, description: String::from("An LDAP Compatible entryUUID"), multivalue: false, unique: false, @@ -1155,8 +1124,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("objectclass"), SchemaAttribute { name: String::from("objectclass"), - uuid: Uuid::parse_str(UUID_SCHEMA_ATTR_OBJECTCLASS) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_ATTR_OBJECTCLASS, description: String::from("An LDAP Compatible objectClass"), multivalue: true, unique: false, @@ -1171,8 +1139,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("attributetype"), SchemaClass { name: String::from("attributetype"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_ATTRIBUTETYPE) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_ATTRIBUTETYPE, description: String::from("Definition of a schema attribute"), systemmay: vec![String::from("phantom"), String::from("index")], may: vec![], @@ -1191,8 +1158,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("classtype"), SchemaClass { name: String::from("classtype"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_CLASSTYPE) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_CLASSTYPE, description: String::from("Definition of a schema classtype"), systemmay: vec![ String::from("systemmay"), @@ -1213,8 +1179,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("object"), SchemaClass { name: String::from("object"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_OBJECT) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_OBJECT, description: String::from( "A system created class that all objects must contain", ), @@ -1232,8 +1197,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("memberof"), SchemaClass { name: String::from("memberof"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_MEMBEROF) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_MEMBEROF, description: String::from("Class that is dynamically added to recepients of memberof or directmemberof"), systemmay: vec![ "memberof".to_string(), @@ -1248,8 +1212,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("extensibleobject"), SchemaClass { name: String::from("extensibleobject"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_EXTENSIBLEOBJECT, description: String::from( "A class type that has green hair and turns off all rules ...", ), @@ -1264,7 +1227,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("recycled"), SchemaClass { name: String::from("recycled"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_RECYCLED).expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_RECYCLED, description: String::from("An object that has been deleted, but still recoverable via the revive operation. Recycled objects are not modifiable, only revivable."), systemmay: vec![], may: vec![], @@ -1276,7 +1239,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("tombstone"), SchemaClass { name: String::from("tombstone"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_TOMBSTONE).expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_TOMBSTONE, description: String::from("An object that is purged from the recycle bin. This is a system internal state. Tombstones have no attributes beside UUID."), systemmay: vec![], may: vec![], @@ -1292,8 +1255,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("system_info"), SchemaClass { name: String::from("system_info"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_SYSTEM_INFO) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_SYSTEM_INFO, description: String::from("System metadata object class"), systemmay: vec![], may: vec![], @@ -1311,8 +1273,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("access_control_profile"), SchemaClass { name: String::from("access_control_profile"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_ACCESS_CONTROL_PROFILE) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_ACCESS_CONTROL_PROFILE, description: String::from("System Access Control Profile Class"), systemmay: vec!["acp_enable".to_string(), "description".to_string()], may: vec![], @@ -1328,8 +1289,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("access_control_search"), SchemaClass { name: String::from("access_control_search"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_ACCESS_CONTROL_SEARCH) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_ACCESS_CONTROL_SEARCH, description: String::from("System Access Control Search Class"), systemmay: vec![], may: vec![], @@ -1341,8 +1301,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("access_control_delete"), SchemaClass { name: String::from("access_control_delete"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_ACCESS_CONTROL_DELETE) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_ACCESS_CONTROL_DELETE, description: String::from("System Access Control DELETE Class"), systemmay: vec![], may: vec![], @@ -1354,8 +1313,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("access_control_modify"), SchemaClass { name: String::from("access_control_modify"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_ACCESS_CONTROL_MODIFY) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_ACCESS_CONTROL_MODIFY, description: String::from("System Access Control Modify Class"), systemmay: vec![ "acp_modify_removedattr".to_string(), @@ -1371,8 +1329,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("access_control_create"), SchemaClass { name: String::from("access_control_create"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_ACCESS_CONTROL_CREATE) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_ACCESS_CONTROL_CREATE, description: String::from("System Access Control Create Class"), systemmay: vec![ "acp_create_class".to_string(), @@ -1387,8 +1344,7 @@ impl<'a> SchemaWriteTransaction<'a> { String::from("system"), SchemaClass { name: String::from("system"), - uuid: Uuid::parse_str(UUID_SCHEMA_CLASS_SYSTEM) - .expect("unable to parse const uuid"), + uuid: *UUID_SCHEMA_CLASS_SYSTEM, description: String::from("A class denoting that a type is system generated and protected. It has special internal behaviour."), systemmay: vec![], may: vec![], @@ -1774,12 +1730,12 @@ mod tests { }; let r1 = - single_value_string.validate_ava("single_value", &btreeset![Value::new_iutf8s("test")]); + single_value_string.validate_ava("single_value", &btreeset![Value::new_iutf8("test")]); assert_eq!(r1, Ok(())); let r2 = single_value_string.validate_ava( "single_value", - &btreeset![Value::new_iutf8s("test1"), Value::new_iutf8s("test2")], + &btreeset![Value::new_iutf8("test1"), Value::new_iutf8("test2")], ); assert_eq!( r2, @@ -1824,8 +1780,8 @@ mod tests { "mv_bool", &btreeset![ Value::new_bool(true), - Value::new_iutf8s("test1"), - Value::new_iutf8s("test2") + Value::new_iutf8("test1"), + Value::new_iutf8("test2") ], ); assert_eq!( @@ -2180,7 +2136,7 @@ mod tests { ); // test syntax of bool - let f_bool = filter_all!(f_eq("multivalue", PartialValue::new_iutf8s("zzzz"))); + let f_bool = filter_all!(f_eq("multivalue", PartialValue::new_iutf8("zzzz"))); assert_eq!( f_bool.validate(&schema), Err(SchemaError::InvalidAttributeSyntax( @@ -2196,10 +2152,7 @@ mod tests { // Test the recursive structures validate let f_or_empty = filter_all!(f_or!([])); assert_eq!(f_or_empty.validate(&schema), Err(SchemaError::EmptyFilter)); - let f_or = filter_all!(f_or!([f_eq( - "multivalue", - PartialValue::new_iutf8s("zzzz") - )])); + let f_or = filter_all!(f_or!([f_eq("multivalue", PartialValue::new_iutf8("zzzz"))])); assert_eq!( f_or.validate(&schema), Err(SchemaError::InvalidAttributeSyntax( @@ -2208,7 +2161,7 @@ mod tests { ); let f_or_mult = filter_all!(f_and!([ f_eq("class", PartialValue::new_class("attributetype")), - f_eq("multivalue", PartialValue::new_iutf8s("zzzzzzz")), + f_eq("multivalue", PartialValue::new_iutf8("zzzzzzz")), ])); assert_eq!( f_or_mult.validate(&schema), diff --git a/kanidmd/src/lib/server.rs b/kanidmd/src/lib/server.rs index f083b3298..72a3ff271 100644 --- a/kanidmd/src/lib/server.rs +++ b/kanidmd/src/lib/server.rs @@ -226,12 +226,10 @@ pub trait QueryServerTransaction { } fn uuid_to_rdn(&self, audit: &mut AuditScope, uuid: &Uuid) -> Result { + // If we have a some, pass it on, else unwrap into a default. self.get_be_txn() .uuid2rdn(audit, uuid) - .and_then(|v| match v { - Some(u) => Ok(u), - None => Ok(format!("uuid={}", uuid.to_hyphenated_ref())), - }) + .map(|v| v.unwrap_or_else(|| format!("uuid={}", uuid.to_hyphenated_ref()))) } // From internal, generate an exists event and dispatch @@ -398,8 +396,8 @@ pub trait QueryServerTransaction { Some(schema_a) => { match schema_a.syntax { SyntaxType::UTF8STRING => Ok(Value::new_utf8(value.to_string())), - SyntaxType::UTF8STRING_INSENSITIVE => Ok(Value::new_iutf8s(value)), - SyntaxType::UTF8STRING_INAME => Ok(Value::new_iname_s(value)), + SyntaxType::UTF8STRING_INSENSITIVE => Ok(Value::new_iutf8(value)), + SyntaxType::UTF8STRING_INAME => Ok(Value::new_iname(value)), SyntaxType::BOOLEAN => Value::new_bools(value) .ok_or_else(|| OperationError::InvalidAttribute("Invalid boolean syntax".to_string())), SyntaxType::SYNTAX_ID => Value::new_syntaxs(value) @@ -470,7 +468,7 @@ pub trait QueryServerTransaction { Some(schema_a) => { match schema_a.syntax { SyntaxType::UTF8STRING => Ok(PartialValue::new_utf8(value.to_string())), - SyntaxType::UTF8STRING_INSENSITIVE => Ok(PartialValue::new_iutf8s(value)), + SyntaxType::UTF8STRING_INSENSITIVE => Ok(PartialValue::new_iutf8(value)), SyntaxType::UTF8STRING_INAME => Ok(PartialValue::new_iname(value)), SyntaxType::BOOLEAN => PartialValue::new_bools(value).ok_or_else(|| { OperationError::InvalidAttribute("Invalid boolean syntax".to_string()) @@ -736,6 +734,7 @@ impl QueryServer { let schema_write = self.schema.write(); let be_txn = self.be.write(); + #[allow(clippy::expect_used)] let ts_max = be_txn.get_db_ts_max(&ts).expect("Unable to get db_ts_max"); let cid = Cid::new_lamport(self.s_uuid, self.d_uuid, ts, &ts_max); @@ -1238,10 +1237,10 @@ impl<'a> QueryServerWriteTransaction<'a> { // Get this entries uuid. let u: Uuid = *e.get_uuid(); - e.get_ava_as_refuuid("directmemberof").and_then(|riter| { + if let Some(riter) = e.get_ava_as_refuuid("directmemberof") { riter.for_each(|g_uuid| { dm_mods - .entry(g_uuid.clone()) + .entry(*g_uuid) .and_modify(|mlist| { let m = Modify::Present("member".to_string(), Value::new_refer_r(&u)); @@ -1253,8 +1252,7 @@ impl<'a> QueryServerWriteTransaction<'a> { ModifyList::new_list(vec![m]) }); }); - Some(()) - }); + }; }); // Now impersonate the modify @@ -1273,7 +1271,7 @@ impl<'a> QueryServerWriteTransaction<'a> { // I think the filter/filter_all shouldn't matter here because the only // valid direct memberships should be still valid/live references. let f = filter_all!(f_eq("uuid", PartialValue::new_uuid(g))); - self.internal_modify(au, f, mods) + self.internal_modify(au, &f, &mods) }) .collect(); r @@ -1462,7 +1460,7 @@ impl<'a> QueryServerWriteTransaction<'a> { pub(crate) fn internal_search_writeable( &self, audit: &mut AuditScope, - filter: Filter, + filter: &Filter, ) -> Result, OperationError> { lperf_segment!(audit, "server::internal_search_writeable", || { let f_valid = filter @@ -1485,6 +1483,7 @@ impl<'a> QueryServerWriteTransaction<'a> { /// such as memberof, but at the expense that YOU must guarantee you /// uphold all other plugin and state rules that are important. You /// probably want modify instead. + #[allow(clippy::needless_pass_by_value)] pub(crate) fn internal_batch_modify( &self, au: &mut AuditScope, @@ -1668,7 +1667,7 @@ impl<'a> QueryServerWriteTransaction<'a> { pub fn internal_delete( &self, audit: &mut AuditScope, - filter: Filter, + filter: &Filter, ) -> Result<(), OperationError> { let f_valid = filter .validate(self.get_schema()) @@ -1680,8 +1679,8 @@ impl<'a> QueryServerWriteTransaction<'a> { pub fn internal_modify( &self, audit: &mut AuditScope, - filter: Filter, - modlist: ModifyList, + filter: &Filter, + modlist: &ModifyList, ) -> Result<(), OperationError> { lperf_segment!(audit, "server::internal_modify", || { let f_valid = filter @@ -1710,9 +1709,9 @@ impl<'a> QueryServerWriteTransaction<'a> { pub fn impersonate_modify( &self, audit: &mut AuditScope, - filter: Filter, - filter_intent: Filter, - modlist: ModifyList, + filter: &Filter, + filter_intent: &Filter, + modlist: &ModifyList, event: &Event, ) -> Result<(), OperationError> { let f_valid = filter.validate(self.get_schema()).map_err(|e| { @@ -1805,7 +1804,7 @@ impl<'a> QueryServerWriteTransaction<'a> { Ok(modlist) => { // Apply to &results[0] ltrace!(audit, "Generated modlist -> {:?}", modlist); - self.internal_modify(audit, filt, modlist) + self.internal_modify(audit, &filt, &modlist) } Err(e) => Err(OperationError::SchemaViolation(e)), } @@ -2279,11 +2278,10 @@ impl<'a> QueryServerWriteTransaction<'a> { audit: &mut AuditScope, new_domain_name: &str, ) -> Result<(), OperationError> { - let modl = - ModifyList::new_purge_and_set("domain_name", Value::new_iname_s(new_domain_name)); + let modl = ModifyList::new_purge_and_set("domain_name", Value::new_iname(new_domain_name)); let udi = PartialValue::new_uuidr(&UUID_DOMAIN_INFO); let filt = filter_all!(f_eq("uuid", udi)); - self.internal_modify(audit, filt, modl) + self.internal_modify(audit, &filt, &modl) } pub fn reindex(&self, audit: &mut AuditScope) -> Result<(), OperationError> { @@ -2502,8 +2500,8 @@ mod tests { // this. let r_inv_1 = server_txn.internal_modify( audit, - filter!(f_eq("tnanuanou", PartialValue::new_iname("Flarbalgarble"))), - ModifyList::new_list(vec![Modify::Present( + &filter!(f_eq("tnanuanou", PartialValue::new_iname("Flarbalgarble"))), + &ModifyList::new_list(vec![Modify::Present( "description".to_string(), Value::from("anusaosu"), )]), @@ -2605,7 +2603,7 @@ mod tests { filter!(f_eq("name", PartialValue::new_iname("testperson1"))), ModifyList::new_list(vec![Modify::Present( "name".to_string(), - Value::new_iname_s("testpersonx"), + Value::new_iname("testpersonx"), )]), ) }; @@ -2617,7 +2615,7 @@ mod tests { filter!(f_eq("name", PartialValue::new_iname("testperson1"))), ModifyList::new_list(vec![ Modify::Present("class".to_string(), Value::new_class("system_info")), - // Modify::Present("domain".to_string(), Value::new_iutf8s("domain.name")), + // Modify::Present("domain".to_string(), Value::new_iutf8("domain.name")), Modify::Present("version".to_string(), Value::new_uint32(1)), ]), ) @@ -2630,7 +2628,7 @@ mod tests { filter!(f_eq("name", PartialValue::new_iname("testperson1"))), ModifyList::new_list(vec![ Modify::Purged("name".to_string()), - Modify::Present("name".to_string(), Value::new_iname_s("testpersonx")), + Modify::Present("name".to_string(), Value::new_iname("testpersonx")), ]), ) }; @@ -3458,7 +3456,7 @@ mod tests { let de_attr = unsafe { DeleteEvent::new_internal_invalid(filter!(f_eq( "attributename", - PartialValue::new_iutf8s("testattr") + PartialValue::new_iutf8("testattr") ))) }; assert!(server_txn.delete(audit, &de_attr).is_ok()); @@ -3510,7 +3508,7 @@ mod tests { assert!(cr.is_ok()); // Build the credential. - let cred = Credential::new_password_only("test_password"); + let cred = Credential::new_password_only("test_password").unwrap(); let v_cred = Value::new_credential("primary", cred); assert!(v_cred.validate()); @@ -3553,7 +3551,7 @@ mod tests { }"#, ); e1.add_ava("uuid", Value::new_uuids(uuid).unwrap()); - e1.add_ava("name", Value::new_iname_s(name)); + e1.add_ava("name", Value::new_iname(name)); e1.add_ava("displayname", Value::new_utf8s(name)); e1 } @@ -3567,7 +3565,7 @@ mod tests { } }"#, ); - e1.add_ava("name", Value::new_iname_s(name)); + e1.add_ava("name", Value::new_iname(name)); e1.add_ava("uuid", Value::new_uuids(uuid).unwrap()); members .iter() @@ -3806,8 +3804,8 @@ mod tests { let me_syn = unsafe { ModifyEvent::new_internal_invalid( filter!(f_or!([ - f_eq("attributename", PartialValue::new_iutf8s("name")), - f_eq("attributename", PartialValue::new_iutf8s("domain_name")), + f_eq("attributename", PartialValue::new_iutf8("name")), + f_eq("attributename", PartialValue::new_iutf8("domain_name")), ])), ModifyList::new_purge_and_set( "syntax", @@ -3826,11 +3824,8 @@ mod tests { ModifyList::new_list(vec![ Modify::Purged("name".to_string()), Modify::Purged("domain_name".to_string()), - Modify::Present("name".to_string(), Value::new_iutf8s("domain_local")), - Modify::Present( - "domain_name".to_string(), - Value::new_iutf8s("example.com"), - ), + Modify::Present("name".to_string(), Value::new_iutf8("domain_local")), + Modify::Present("domain_name".to_string(), Value::new_iutf8("example.com")), ]), ) }; @@ -3845,8 +3840,8 @@ mod tests { let me_syn = unsafe { ModifyEvent::new_internal_invalid( filter!(f_or!([ - f_eq("attributename", PartialValue::new_iutf8s("name")), - f_eq("attributename", PartialValue::new_iutf8s("domain_name")), + f_eq("attributename", PartialValue::new_iutf8("name")), + f_eq("attributename", PartialValue::new_iutf8("domain_name")), ])), ModifyList::new_purge_and_set( "syntax", diff --git a/kanidmd/src/lib/utils.rs b/kanidmd/src/lib/utils.rs index 7b69b80b6..cc74fc6c0 100644 --- a/kanidmd/src/lib/utils.rs +++ b/kanidmd/src/lib/utils.rs @@ -22,7 +22,10 @@ fn uuid_from_u64_u32(a: u64, b: u32, sid: SID) -> Uuid { v.extend_from_slice(&b.to_be_bytes()); v.extend_from_slice(&sid); - Builder::from_slice(v.as_slice()).unwrap().build() + #[allow(clippy::expect_used)] + Builder::from_slice(v.as_slice()) + .expect("invalid slice for uuid builder") + .build() } pub fn uuid_from_duration(d: Duration, sid: SID) -> Uuid { @@ -46,9 +49,10 @@ pub fn readable_password_from_random() -> String { } pub fn duration_from_epoch_now() -> Duration { + #[allow(clippy::expect_used)] SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() + .expect("invalid duration from epoch now") } /* diff --git a/kanidmd/src/lib/value.rs b/kanidmd/src/lib/value.rs index 66869e9e2..a5819b91b 100644 --- a/kanidmd/src/lib/value.rs +++ b/kanidmd/src/lib/value.rs @@ -15,17 +15,23 @@ use std::cmp::Ordering; use regex::Regex; lazy_static! { - static ref SPN_RE: Regex = - Regex::new("(?P[^@]+)@(?P[^@]+)").expect("Invalid SPN regex found"); - static ref INAME_RE: Regex = - Regex::new("^(_.*|.*(\\s|@|,|=).*|\\d+|root|nobody|nogroup|wheel|sshd|shadow|systemd.*)$").expect("Invalid Iname regex found"); + static ref SPN_RE: Regex = { + #[allow(clippy::expect_used)] + Regex::new("(?P[^@]+)@(?P[^@]+)").expect("Invalid SPN regex found") + }; + static ref INAME_RE: Regex = { + #[allow(clippy::expect_used)] + Regex::new("^(_.*|.*(\\s|@|,|=).*|\\d+|root|nobody|nogroup|wheel|sshd|shadow|systemd.*)$").expect("Invalid Iname regex found") // ^ ^ ^ // | | \- must not be only integers // | \- must not contain whitespace, @, ',', = // \- must not start with _ // Them's be the rules. - static ref NSUNIQUEID_RE: Regex = - Regex::new("^[0-9a-fA-F]{8}-[0-9a-fA-F]{8}-[0-9a-fA-F]{8}-[0-9a-fA-F]{8}$").expect("Invalid Nsunique regex found"); + }; + static ref NSUNIQUEID_RE: Regex = { + #[allow(clippy::expect_used)] + Regex::new("^[0-9a-fA-F]{8}-[0-9a-fA-F]{8}-[0-9a-fA-F]{8}-[0-9a-fA-F]{8}$").expect("Invalid Nsunique regex found") + }; } #[allow(non_camel_case_types)] @@ -279,7 +285,7 @@ impl PartialValue { } } - pub fn new_iutf8s(s: &str) -> Self { + pub fn new_iutf8(s: &str) -> Self { PartialValue::Iutf8(s.to_lowercase()) } @@ -289,7 +295,7 @@ impl PartialValue { #[inline] pub fn new_class(s: &str) -> Self { - PartialValue::new_iutf8s(s) + PartialValue::new_iutf8(s) } /* @@ -532,10 +538,6 @@ impl PartialValue { } } - pub fn to_str_unwrap(&self) -> &str { - self.to_str().expect("An invalid value was returned!!!") - } - pub fn contains(&self, s: &PartialValue) -> bool { match (self, s) { (PartialValue::Utf8(s1), PartialValue::Utf8(s2)) => s1.contains(s2), @@ -563,7 +565,9 @@ impl PartialValue { PartialValue::Bool(b) => b.to_string(), PartialValue::Syntax(syn) => syn.to_string(), PartialValue::Index(it) => it.to_string(), - PartialValue::JsonFilt(s) => { + PartialValue::JsonFilt(s) => + { + #[allow(clippy::expect_used)] serde_json::to_string(s).expect("A json filter value was corrupted during run-time") } PartialValue::Cred(tag) => tag.to_string(), @@ -715,16 +719,9 @@ impl Value { } } - pub fn new_iutf8(s: String) -> Self { + pub fn new_iutf8(s: &str) -> Self { Value { - pv: PartialValue::new_iutf8s(s.as_str()), - data: None, - } - } - - pub fn new_iutf8s(s: &str) -> Self { - Value { - pv: PartialValue::new_iutf8s(s), + pv: PartialValue::new_iutf8(s), data: None, } } @@ -736,14 +733,7 @@ impl Value { } } - pub fn new_iname(s: String) -> Self { - Value { - pv: PartialValue::new_iname(s.as_str()), - data: None, - } - } - - pub fn new_iname_s(s: &str) -> Self { + pub fn new_iname(s: &str) -> Self { Value { pv: PartialValue::new_iname(s), data: None, @@ -788,14 +778,14 @@ impl Value { pub fn new_class(s: &str) -> Self { Value { - pv: PartialValue::new_iutf8s(s), + pv: PartialValue::new_iutf8(s), data: None, } } pub fn new_attr(s: &str) -> Self { Value { - pv: PartialValue::new_iutf8s(s), + pv: PartialValue::new_iutf8(s), data: None, } } @@ -1146,6 +1136,8 @@ impl Value { } } + #[allow(clippy::unreachable)] + #[allow(clippy::expect_used)] pub(crate) fn to_db_valuev1(&self) -> DbValueV1 { // This has to clone due to how the backend works. match &self.pv { @@ -1166,9 +1158,9 @@ impl Value { let c = match &self.data { Some(v) => match v.as_ref() { DataValue::Cred(c) => c, - _ => panic!(), + _ => unreachable!(), }, - None => panic!(), + None => unreachable!(), }; // Save the tag AND the dataValue here! @@ -1181,9 +1173,9 @@ impl Value { let ru = match &self.data { Some(v) => match v.as_ref() { DataValue::RadiusCred(rc) => rc.clone(), - _ => panic!(), + _ => unreachable!(), }, - None => panic!(), + None => unreachable!(), }; DbValueV1::RU(ru) } @@ -1191,9 +1183,9 @@ impl Value { let sk = match &self.data { Some(v) => match v.as_ref() { DataValue::SshKey(sc) => sc.clone(), - _ => panic!(), + _ => unreachable!(), }, - None => panic!(), + None => unreachable!(), }; DbValueV1::SK(DbValueTaggedStringV1 { t: t.clone(), @@ -1220,10 +1212,6 @@ impl Value { } } - pub fn to_str_unwrap(&self) -> &str { - self.to_str().expect("An invalid value was returned!!!") - } - pub fn as_string(&self) -> Option<&String> { match &self.pv { PartialValue::Utf8(s) => Some(s), @@ -1306,7 +1294,9 @@ impl Value { // In resolve value, we bypass this, but we keep it here for complete // impl sake. PartialValue::Refer(u) => u.to_hyphenated_ref().to_string(), - PartialValue::JsonFilt(s) => { + PartialValue::JsonFilt(s) => + { + #[allow(clippy::expect_used)] serde_json::to_string(s).expect("A json filter value was corrupted during run-time") } PartialValue::Cred(tag) => { @@ -1383,6 +1373,7 @@ impl Value { } pub fn generate_idx_eq_keys(&self) -> Vec { + #[allow(clippy::expect_used)] match &self.pv { PartialValue::Utf8(s) | PartialValue::Iutf8(s) @@ -1551,18 +1542,18 @@ mod tests { * - can not have spaces (confuses too many systems :() * - can not have = or , (confuses ldap) */ - let inv1 = Value::new_iname_s("1234"); - let inv2 = Value::new_iname_s("bc23f637-4439-4c07-b95d-eaed0d9e4b8b"); - let inv3 = Value::new_iname_s("hello@test.com"); - let inv4 = Value::new_iname_s("_bad"); - let inv5 = Value::new_iname_s("no spaces I'm sorry :("); - let inv6 = Value::new_iname_s("bad=equals"); - let inv7 = Value::new_iname_s("bad,comma"); + let inv1 = Value::new_iname("1234"); + let inv2 = Value::new_iname("bc23f637-4439-4c07-b95d-eaed0d9e4b8b"); + let inv3 = Value::new_iname("hello@test.com"); + let inv4 = Value::new_iname("_bad"); + let inv5 = Value::new_iname("no spaces I'm sorry :("); + let inv6 = Value::new_iname("bad=equals"); + let inv7 = Value::new_iname("bad,comma"); - let val1 = Value::new_iname_s("William"); - let val2 = Value::new_iname_s("this_is_okay"); - let val3 = Value::new_iname_s("123_456"); - let val4 = Value::new_iname_s("🍿"); + let val1 = Value::new_iname("William"); + let val2 = Value::new_iname("this_is_okay"); + let val3 = Value::new_iname("123_456"); + let val4 = Value::new_iname("🍿"); assert!(!inv1.validate()); assert!(!inv2.validate()); diff --git a/kanidmd/src/server/main.rs b/kanidmd/src/server/main.rs index e104c8023..23e6b4d87 100644 --- a/kanidmd/src/server/main.rs +++ b/kanidmd/src/server/main.rs @@ -1,4 +1,12 @@ #![deny(warnings)] +#![warn(unused_extern_crates)] +#![deny(clippy::unwrap_used)] +#![deny(clippy::expect_used)] +#![deny(clippy::panic)] +#![deny(clippy::unreachable)] +#![deny(clippy::await_holding_lock)] +#![deny(clippy::needless_pass_by_value)] +#![deny(clippy::trivially_copy_pass_by_ref)] use users::{get_current_gid, get_current_uid, get_effective_gid, get_effective_uid}; @@ -136,7 +144,7 @@ fn read_file_metadata(path: &PathBuf) -> Metadata { Err(e) => { eprintln!( "Unable to read metadata for {} - {:?}", - path.to_str().unwrap(), + path.to_str().unwrap_or("invalid file path"), e ); std::process::exit(1); @@ -171,18 +179,18 @@ async fn main() { let cfg_meta = read_file_metadata(&(opt.commonopt().config_path)); if !cfg_meta.permissions().readonly() { 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()); + opt.commonopt().config_path.to_str().unwrap_or("invalid file path")); } if cfg_meta.mode() & 0o007 != 0 { eprintln!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...", - opt.commonopt().config_path.to_str().unwrap() + opt.commonopt().config_path.to_str().unwrap_or("invalid file path") ); } 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 ...", - opt.commonopt().config_path.to_str().unwrap() + opt.commonopt().config_path.to_str().unwrap_or("invalid file path") ); } @@ -241,7 +249,7 @@ async fn main() { if !db_parent_path.exists() { eprintln!( "DB folder {} may not exist, server startup may FAIL!", - db_parent_path.to_str().unwrap() + db_parent_path.to_str().unwrap_or("invalid file path") ); } @@ -250,16 +258,16 @@ async fn main() { if !i_meta.is_dir() { eprintln!( "ERROR: Refusing to run - DB folder {} may not be a directory", - db_par_path_buf.to_str().unwrap() + db_par_path_buf.to_str().unwrap_or("invalid file path") ); std::process::exit(1); } if i_meta.permissions().readonly() { - 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()); + 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")); } 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()); + 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")); } } @@ -287,11 +295,16 @@ async fn main() { let sctx = create_server_core(config).await; match sctx { - Ok(sctx) => { - tokio::signal::ctrl_c().await.unwrap(); - println!("Ctrl-C received, shutting down"); - sctx.stop() - } + Ok(sctx) => match tokio::signal::ctrl_c().await { + Ok(_) => { + eprintln!("Ctrl-C received, shutting down"); + sctx.stop() + } + Err(_) => { + eprintln!("Invalid signal received, shutting down as a precaution ..."); + sctx.stop() + } + }, Err(_) => { eprintln!("Failed to start server core!"); return; @@ -310,7 +323,7 @@ async fn main() { std::process::exit(1); } }; - backup_server_core(config, p); + backup_server_core(&config, p); } Opt::Restore(ropt) => { eprintln!("Running in restore mode ..."); @@ -324,21 +337,27 @@ async fn main() { std::process::exit(1); } }; - restore_server_core(config, p); + restore_server_core(&config, p); } Opt::Verify(_vopt) => { eprintln!("Running in db verification mode ..."); // config.update_db_path(&vopt.db_path); - verify_server_core(config); + verify_server_core(&config); } Opt::RecoverAccount(raopt) => { eprintln!("Running account recovery ..."); - let password = rpassword::prompt_password_stderr("new password: ").unwrap(); + let password = match rpassword::prompt_password_stderr("new password: ") { + Ok(pw) => pw, + Err(e) => { + eprintln!("Failed to get password from prompt {:?}", e); + std::process::exit(1); + } + }; // config.update_db_path(&raopt.commonopts.db_path); - recover_account_core(config, raopt.name, password); + recover_account_core(&config, &raopt.name, &password); } /* Opt::ResetServerId(vopt) => { @@ -352,13 +371,13 @@ async fn main() { eprintln!("Running in reindex mode ..."); // config.update_db_path(&copt.db_path); - reindex_server_core(config); + reindex_server_core(&config); } Opt::DomainChange(dopt) => { eprintln!("Running in domain name change mode ... this may take a long time ..."); // config.update_db_path(&dopt.commonopts.db_path); - domain_rename_core(config, dopt.new_domain_name); + domain_rename_core(&config, &dopt.new_domain_name); } } }