mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
V large cleanup
This commit is contained in:
parent
217e3455a2
commit
85ec82832e
160
Cargo.lock
generated
160
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -75,7 +75,9 @@ fn read_file_metadata<P: AsRef<Path>>(path: &P) -> Result<Metadata, ()> {
|
|||
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
|
||||
);
|
||||
})
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -100,6 +100,7 @@ pub enum OperationError {
|
|||
PasswordTooShort(usize),
|
||||
PasswordEmpty,
|
||||
PasswordBadListed,
|
||||
CryptographyError,
|
||||
}
|
||||
|
||||
impl PartialEq for OperationError {
|
||||
|
|
|
@ -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\"]}}' <your outfile>");
|
||||
match serde_json::to_writer(bwrite, &modlist) {
|
||||
Ok(_) =>
|
||||
info!("next step: kanidm raw modify -D admin '{{\"Eq\": [\"uuid\", \"00000000-0000-0000-0000-ffffff000026\"]}}' <outfile>"),
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ r2d2_sqlite = "0.16"
|
|||
reqwest = { version = "0.10" }
|
||||
|
||||
users = "0.10"
|
||||
async-std = "1.6"
|
||||
|
||||
[features]
|
||||
default = [ "libsqlite3-sys/bundled" ]
|
||||
|
|
|
@ -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<Vec<UnixUserToken>, ()> {
|
||||
let dbtxn = self.db.write();
|
||||
async fn get_cached_usertokens(&self) -> Result<Vec<UnixUserToken>, ()> {
|
||||
let dbtxn = self.db.write().await;
|
||||
dbtxn.get_accounts()
|
||||
}
|
||||
|
||||
fn get_cached_grouptokens(&self) -> Result<Vec<UnixGroupToken>, ()> {
|
||||
let dbtxn = self.db.write();
|
||||
async fn get_cached_grouptokens(&self) -> Result<Vec<UnixGroupToken>, ()> {
|
||||
let dbtxn = self.db.write().await;
|
||||
dbtxn.get_groups()
|
||||
}
|
||||
|
||||
fn get_cached_usertoken(&self, account_id: &Id) -> Result<(bool, Option<UnixUserToken>), ()> {
|
||||
async fn get_cached_usertoken(
|
||||
&self,
|
||||
account_id: &Id,
|
||||
) -> Result<(bool, Option<UnixUserToken>), ()> {
|
||||
// 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<UnixGroupToken>), ()> {
|
||||
async fn get_cached_grouptoken(
|
||||
&self,
|
||||
grp_id: &Id,
|
||||
) -> Result<(bool, Option<UnixGroupToken>), ()> {
|
||||
// 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<bool, ()> {
|
||||
let dbtxn = self.db.write();
|
||||
async fn check_cache_userpassword(&self, a_uuid: &str, cred: &str) -> Result<bool, ()> {
|
||||
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<result<t, _>>
|
||||
.transpose()
|
||||
// now result<option<t>, _>
|
||||
.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<result<t, _>>
|
||||
.transpose()
|
||||
// now result<option<t>, _>
|
||||
.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<Option<UnixUserToken>, ()> {
|
||||
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<Option<UnixGroupToken>, ()> {
|
||||
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<String> {
|
||||
let dbtxn = self.db.write();
|
||||
async fn get_groupmembers(&self, uuid: &str) -> Vec<String> {
|
||||
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<Vec<NssUser>, ()> {
|
||||
self.get_cached_usertokens().map(|l| {
|
||||
pub async fn get_nssaccounts(&self) -> Result<Vec<NssUser>, ()> {
|
||||
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<Vec<NssGroup>, ()> {
|
||||
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<Vec<NssGroup>, ()> {
|
||||
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<Option<NssGroup>, ()> {
|
||||
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<Option<NssGroup>, ()> {
|
||||
|
@ -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<UnixUserToken>,
|
||||
cred: &str,
|
||||
) -> Result<Option<bool>, ()> {
|
||||
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<Option<bool>, ()> {
|
||||
|
@ -710,7 +720,9 @@ impl CacheLayer {
|
|||
cred: &str,
|
||||
) -> Result<Option<bool>, ()> {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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."),
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -264,7 +264,7 @@ impl Handler<SearchMessage> 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<AuthMessage> 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<WhoamiMessage> 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<InternalSearchMessage> 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<InternalSearchRecycledMessage> 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<IdmAccountUnixAuthMessage> 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)
|
||||
|
|
|
@ -178,14 +178,14 @@ impl IdmGroupUnixExtendMessage {
|
|||
pub fn new(
|
||||
uat: Option<UserAuthToken>,
|
||||
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<UserAuthToken>,
|
||||
uuid_or_name: String,
|
||||
proto_ml: ProtoModifyList,
|
||||
uuid_or_name: &str,
|
||||
proto_ml: &ProtoModifyList,
|
||||
filter: Filter<FilterInvalid>,
|
||||
) -> 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<UserAuthToken>,
|
||||
uuid_or_name: String,
|
||||
ml: ModifyList<ModifyInvalid>,
|
||||
uuid_or_name: &str,
|
||||
ml: &ModifyList<ModifyInvalid>,
|
||||
filter: Filter<FilterInvalid>,
|
||||
) -> 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<InternalDeleteMessage> 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<InternalCredentialSetMessage> for QueryServerWriteV1 {
|
|||
"actors::v1_write::handle<InternalCredentialSetMessage>",
|
||||
|| {
|
||||
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<IdmAccountSetPasswordMessage> for QueryServerWriteV1 {
|
|||
"actors::v1_write::handle<IdmAccountSetPasswordMessage>",
|
||||
|| {
|
||||
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<InternalRegenerateRadiusMessage> for QueryServerWriteV1 {
|
|||
"actors::v1_write::handle<InternalRegenerateRadiusMessage>",
|
||||
|| {
|
||||
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<PurgeAttributeMessage> for QueryServerWriteV1 {
|
|||
&mut audit,
|
||||
msg.uat,
|
||||
target_uuid,
|
||||
msg.attr,
|
||||
&msg.attr,
|
||||
msg.filter,
|
||||
&qs_write,
|
||||
) {
|
||||
|
@ -891,7 +887,7 @@ impl Handler<RemoveAttributeValueMessage> for QueryServerWriteV1 {
|
|||
&mut audit,
|
||||
msg.uat,
|
||||
target_uuid,
|
||||
proto_ml,
|
||||
&proto_ml,
|
||||
msg.filter,
|
||||
&qs_write,
|
||||
) {
|
||||
|
@ -942,7 +938,7 @@ impl Handler<AppendAttributeMessage> 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<SetAttributeMessage> 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<InternalSshKeyCreateMessage> 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<IdmAccountPersonExtendMessage> 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<IdmAccountUnixExtendMessage> 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<IdmAccountUnixExtendMessage> 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<IdmGroupUnixExtendMessage> 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<IdmAccountUnixSetCredMessage> for QueryServerWriteV1 {
|
|||
"actors::v1_write::handle<IdmAccountUnixSetCredMessage>",
|
||||
|| {
|
||||
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<PurgeTombstoneEvent> 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<PurgeRecycledEvent> 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");
|
||||
}
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::audit::AuditScope;
|
||||
use crossbeam::channel::Receiver;
|
||||
|
||||
pub fn run(rx: Receiver<Option<AuditScope>>) {
|
||||
pub fn run(rx: &Receiver<Option<AuditScope>>) {
|
||||
info!("Log thread started ...");
|
||||
loop {
|
||||
match rx.recv() {
|
||||
|
|
|
@ -309,7 +309,8 @@ struct AuditLog {
|
|||
pub struct PerfEvent {
|
||||
id: String,
|
||||
duration: Option<Duration>,
|
||||
contains: Vec<PerfEvent>,
|
||||
#[allow(clippy::vec_box)]
|
||||
contains: Vec<Box<PerfEvent>>,
|
||||
#[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<AuditLog>,
|
||||
perf: Vec<PerfEvent>,
|
||||
#[allow(clippy::vec_box)]
|
||||
perf: Vec<Box<PerfEvent>>,
|
||||
// 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.
|
||||
|
|
|
@ -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(())
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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<SqliteConnectionManager>) -> 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()
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use std::convert::TryFrom;
|
||||
use std::fs;
|
||||
|
||||
use crate::value::IndexType;
|
||||
|
@ -87,8 +86,8 @@ impl IdRawEntry {
|
|||
) -> Result<Entry<EntrySealed, EntryCommitted>, 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<EntryInit, EntryNew> = 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<EntryInit, EntryNew> = 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())));
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ impl ServerCtx {
|
|||
self.system.clone()
|
||||
}
|
||||
|
||||
#[allow(clippy::expect_used)]
|
||||
pub fn stop(self) {
|
||||
// stop the actix system
|
||||
self.system.stop();
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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<ServerCtx, ()>
|
|||
// 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<ServerCtx, ()>
|
|||
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<ServerCtx, ()>
|
|||
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))
|
||||
}
|
||||
|
|
|
@ -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<KDF, OperationError> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let salt: Vec<u8> = (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, OperationError> {
|
||||
Self::new_pbkdf2(cleartext).map(|material| Password { material })
|
||||
}
|
||||
|
||||
pub fn verify(&self, cleartext: &str) -> bool {
|
||||
pub fn verify(&self, cleartext: &str) -> Result<bool, OperationError> {
|
||||
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<DbCredV1> 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<Self, OperationError> {
|
||||
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<Self, OperationError> {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -323,14 +323,14 @@ impl Entry<EntryInit, EntryNew> {
|
|||
let attr = k.to_lowercase();
|
||||
let vv: Set<Value> = 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<EntrySealed, EntryCommitted> {
|
|||
|
||||
pub fn reduce_attributes(
|
||||
self,
|
||||
allowed_attrs: BTreeSet<&str>,
|
||||
allowed_attrs: &BTreeSet<&str>,
|
||||
) -> Entry<EntryReduced, EntryCommitted> {
|
||||
// Remove all attrs from our tree that are NOT in the allowed set.
|
||||
|
||||
|
@ -1880,7 +1880,7 @@ impl From<&SchemaAttribute> for Entry<EntryInit, EntryNew> {
|
|||
// 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<EntryInit, EntryNew> {
|
|||
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<String, Set<Value>> = 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<EntryInit, EntryNew> = 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<EntryInit, EntryNew> = 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() };
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ impl SearchResult {
|
|||
pub fn new(
|
||||
audit: &mut AuditScope,
|
||||
qs: &QueryServerReadTransaction,
|
||||
entries: Vec<Entry<EntryReduced, EntryCommitted>>,
|
||||
entries: &[Entry<EntryReduced, EntryCommitted>],
|
||||
) -> Result<Self, OperationError> {
|
||||
let entries: Result<_, _> = entries
|
||||
.iter()
|
||||
|
@ -461,7 +461,7 @@ impl SearchEvent {
|
|||
audit: &mut AuditScope,
|
||||
qs: &QueryServerReadTransaction,
|
||||
euuid: &Uuid,
|
||||
filter: Filter<FilterInvalid>,
|
||||
filter: &Filter<FilterInvalid>,
|
||||
attrs: Option<BTreeSet<String>>,
|
||||
) -> Result<Self, OperationError> {
|
||||
Ok(SearchEvent {
|
||||
|
@ -618,7 +618,7 @@ impl DeleteEvent {
|
|||
pub fn from_parts(
|
||||
audit: &mut AuditScope,
|
||||
uat: Option<UserAuthToken>,
|
||||
filter: Filter<FilterInvalid>,
|
||||
filter: &Filter<FilterInvalid>,
|
||||
qs: &QueryServerWriteTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
Ok(DeleteEvent {
|
||||
|
@ -716,7 +716,7 @@ impl ModifyEvent {
|
|||
audit: &mut AuditScope,
|
||||
uat: Option<UserAuthToken>,
|
||||
target_uuid: Uuid,
|
||||
proto_ml: ProtoModifyList,
|
||||
proto_ml: &ProtoModifyList,
|
||||
filter: Filter<FilterInvalid>,
|
||||
qs: &QueryServerWriteTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
|
@ -747,7 +747,7 @@ impl ModifyEvent {
|
|||
audit: &mut AuditScope,
|
||||
uat: Option<UserAuthToken>,
|
||||
target_uuid: Uuid,
|
||||
ml: ModifyList<ModifyInvalid>,
|
||||
ml: &ModifyList<ModifyInvalid>,
|
||||
filter: Filter<FilterInvalid>,
|
||||
qs: &QueryServerWriteTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
|
@ -775,11 +775,11 @@ impl ModifyEvent {
|
|||
audit: &mut AuditScope,
|
||||
uat: Option<UserAuthToken>,
|
||||
target_uuid: Uuid,
|
||||
attr: String,
|
||||
attr: &str,
|
||||
filter: Filter<FilterInvalid>,
|
||||
qs: &QueryServerWriteTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
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<EntryReduced, EntryCommitted>,
|
||||
e: &Entry<EntryReduced, EntryCommitted>,
|
||||
uat: UserAuthToken,
|
||||
) -> Result<Self, OperationError> {
|
||||
Ok(WhoamiResult {
|
||||
|
|
|
@ -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<FilterInvalid> = 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")),
|
||||
]))
|
||||
};
|
||||
|
||||
|
|
|
@ -98,33 +98,33 @@ pub(crate) struct Account {
|
|||
impl Account {
|
||||
pub(crate) fn try_from_entry_ro(
|
||||
au: &mut AuditScope,
|
||||
value: Entry<EntrySealed, EntryCommitted>,
|
||||
value: &Entry<EntrySealed, EntryCommitted>,
|
||||
qs: &mut QueryServerReadTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
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<EntrySealed, EntryCommitted>,
|
||||
value: &Entry<EntrySealed, EntryCommitted>,
|
||||
qs: &mut QueryServerWriteTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
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<EntrySealed, EntryCommitted>,
|
||||
value: &Entry<EntrySealed, EntryCommitted>,
|
||||
) -> Result<Self, OperationError> {
|
||||
try_from_entry!(value, vec![])
|
||||
}
|
||||
|
||||
// Could this actually take a claims list and application instead?
|
||||
pub(crate) fn to_userauthtoken(&self, claims: Vec<Claim>) -> Option<UserAuthToken> {
|
||||
pub(crate) fn to_userauthtoken(&self, claims: &[Claim]) -> Option<UserAuthToken> {
|
||||
// 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))
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -47,8 +47,7 @@ macro_rules! try_from_account_e {
|
|||
e
|
||||
})?;
|
||||
// Now convert the group entries to groups.
|
||||
let groups: Result<Vec<_>, _> =
|
||||
ges.into_iter().map(Group::try_from_entry).collect();
|
||||
let groups: Result<Vec<_>, _> = 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<EntrySealed, EntryCommitted>,
|
||||
value: &Entry<EntrySealed, EntryCommitted>,
|
||||
) -> Result<Self, OperationError> {
|
||||
if !value.attribute_value_pres("class", &PVCLASS_GROUP) {
|
||||
return Err(OperationError::InvalidAccountState(
|
||||
|
|
|
@ -24,7 +24,7 @@ pub(crate) struct RadiusAccount {
|
|||
impl RadiusAccount {
|
||||
pub(crate) fn try_from_entry_reduced(
|
||||
au: &mut AuditScope,
|
||||
value: Entry<EntryReduced, EntryCommitted>,
|
||||
value: &Entry<EntryReduced, EntryCommitted>,
|
||||
qs: &mut QueryServerReadTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
if !value.attribute_value_pres("class", &PVCLASS_ACCOUNT) {
|
||||
|
|
|
@ -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<Option<LdapBoundToken>, 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());
|
||||
|
||||
|
|
|
@ -105,28 +105,28 @@ macro_rules! try_from_entry {
|
|||
impl UnixUserAccount {
|
||||
pub(crate) fn try_from_entry_rw(
|
||||
au: &mut AuditScope,
|
||||
value: Entry<EntrySealed, EntryCommitted>,
|
||||
value: &Entry<EntrySealed, EntryCommitted>,
|
||||
qs: &mut QueryServerWriteTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
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<EntrySealed, EntryCommitted>,
|
||||
value: &Entry<EntrySealed, EntryCommitted>,
|
||||
qs: &mut QueryServerReadTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
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<EntryReduced, EntryCommitted>,
|
||||
value: &Entry<EntryReduced, EntryCommitted>,
|
||||
qs: &mut QueryServerReadTransaction,
|
||||
) -> Result<Self, OperationError> {
|
||||
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<ModifyList<ModifyInvalid>, 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<Vec<_>, _> = 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<EntryReduced, EntryCommitted>,
|
||||
value: &Entry<EntryReduced, EntryCommitted>,
|
||||
) -> Result<Self, OperationError> {
|
||||
try_from_group_e!(value)
|
||||
}
|
||||
|
||||
pub fn try_from_entry(
|
||||
value: Entry<EntrySealed, EntryCommitted>,
|
||||
value: &Entry<EntrySealed, EntryCommitted>,
|
||||
) -> Result<Self, OperationError> {
|
||||
try_from_group_e!(value)
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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")
|
||||
}};
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|_, _| {}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|_, _| {}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")]),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -34,12 +34,15 @@ impl Cid {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::expect_used)]
|
||||
pub fn sub_secs(&self, secs: u64) -> Result<Self, OperationError> {
|
||||
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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -226,12 +226,10 @@ pub trait QueryServerTransaction {
|
|||
}
|
||||
|
||||
fn uuid_to_rdn(&self, audit: &mut AuditScope, uuid: &Uuid) -> Result<String, OperationError> {
|
||||
// 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<FilterInvalid>,
|
||||
filter: &Filter<FilterInvalid>,
|
||||
) -> Result<Vec<EntryTuple>, 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<FilterInvalid>,
|
||||
filter: &Filter<FilterInvalid>,
|
||||
) -> 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<FilterInvalid>,
|
||||
modlist: ModifyList<ModifyInvalid>,
|
||||
filter: &Filter<FilterInvalid>,
|
||||
modlist: &ModifyList<ModifyInvalid>,
|
||||
) -> 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<FilterInvalid>,
|
||||
filter_intent: Filter<FilterInvalid>,
|
||||
modlist: ModifyList<ModifyInvalid>,
|
||||
filter: &Filter<FilterInvalid>,
|
||||
filter_intent: &Filter<FilterInvalid>,
|
||||
modlist: &ModifyList<ModifyInvalid>,
|
||||
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",
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -15,17 +15,23 @@ use std::cmp::Ordering;
|
|||
use regex::Regex;
|
||||
|
||||
lazy_static! {
|
||||
static ref SPN_RE: Regex =
|
||||
Regex::new("(?P<name>[^@]+)@(?P<realm>[^@]+)").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<name>[^@]+)@(?P<realm>[^@]+)").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<String> {
|
||||
#[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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue