mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
1481 2024 access control rework (#2366)
Rework default access controls to better separate roles and access profiles.
This commit is contained in:
parent
c2d9c5c941
commit
d09c2448ff
332
Cargo.lock
generated
332
Cargo.lock
generated
|
@ -80,9 +80,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
|||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
|
||||
checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
|
@ -100,30 +100,30 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
|
|||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
|
||||
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.0"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.1"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
|
||||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -233,7 +233,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -255,7 +255,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -266,7 +266,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -390,7 +390,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -494,7 +494,7 @@ dependencies = [
|
|||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
"which",
|
||||
]
|
||||
|
||||
|
@ -724,9 +724,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.10"
|
||||
version = "4.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272"
|
||||
checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -734,9 +734,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.4.9"
|
||||
version = "4.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1"
|
||||
checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -762,7 +762,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -894,9 +894,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
|
@ -904,9 +904,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.4"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
|
@ -989,9 +989,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.8"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
|
||||
checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
|
@ -999,9 +999,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||
checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
|
@ -1010,22 +1010,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.15"
|
||||
version = "0.9.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
||||
checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset 0.9.0",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.8"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
|
||||
checksum = "b9bcf5bdbfdd6030fb4a1c497b5d5fc5921aa2f60d359a17e249c0e6df3de153"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
|
@ -1033,9 +1032,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.16"
|
||||
version = "0.8.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
||||
checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
@ -1207,7 +1206,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1229,7 +1228,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
|
|||
dependencies = [
|
||||
"darling_core 0.20.3",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1254,9 +1253,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.9"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"
|
||||
checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
"serde",
|
||||
|
@ -1347,7 +1346,16 @@ version = "4.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
"dirs-sys 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1361,6 +1369,18 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.4"
|
||||
|
@ -1369,7 +1389,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1428,7 +1448,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1448,7 +1468,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1468,7 +1488,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1489,7 +1509,7 @@ dependencies = [
|
|||
"darling 0.20.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1581,9 +1601,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "faster-hex"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "239f7bfb930f820ab16a9cd95afc26f88264cf6905c960b340a615384aa3338a"
|
||||
checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
@ -1618,14 +1638,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.22"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
|
||||
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall 0.3.5",
|
||||
"windows-sys 0.48.0",
|
||||
"redox_syscall 0.4.1",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1770,7 +1790,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1918,9 +1938,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-chunk"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b42ea64420f7994000130328f3c7a2038f639120518870436d31b8bde704493"
|
||||
checksum = "d411ecd9b558b0c20b3252b7e409eec48eabc41d18324954fe526bac6e2db55f"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
@ -1962,9 +1982,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-config-value"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea7505b97f4d8e7933e29735a568ba2f86d8de466669d9f0e8321384f9972f47"
|
||||
checksum = "6419db582ea84dfb58c7e7b0af7fd62c808aa14954af2936a33f89b0f4ed018e"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"bstr",
|
||||
|
@ -1975,9 +1995,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-date"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7df669639582dc7c02737642f76890b03b5544e141caba68a7d6b4eb551e0d"
|
||||
checksum = "468dfbe411f335f01525a1352271727f8e7772075a93fa747260f502086b30be"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"itoa",
|
||||
|
@ -2052,9 +2072,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-hash"
|
||||
version = "0.13.1"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1884c7b41ea0875217c1be9ce91322f90bde433e91d374d0e1276073a51ccc60"
|
||||
checksum = "1f8cf8c2266f63e582b7eb206799b63aa5fa68ee510ad349f637dfe2d0653de0"
|
||||
dependencies = [
|
||||
"faster-hex",
|
||||
"thiserror",
|
||||
|
@ -2062,9 +2082,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-hashtable"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "409268480841ad008e81c17ca5a293393fbf9f2b6c2f85b8ab9de1f0c5176a16"
|
||||
checksum = "feb61880816d7ec4f0b20606b498147d480860ddd9133ba542628df2f548d3ca"
|
||||
dependencies = [
|
||||
"gix-hash",
|
||||
"hashbrown 0.14.3",
|
||||
|
@ -2084,13 +2104,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-macros"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d8acb5ee668d55f0f2d19a320a3f9ef67a6999ad483e11135abcc2464ed18b6"
|
||||
checksum = "02a5bcaf6704d9354a3071cede7e77d366a5980c7352e102e2c2f9b645b1d3ae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2153,9 +2173,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-path"
|
||||
version = "0.10.0"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a1d370115171e3ae03c5c6d4f7d096f2981a40ddccb98dfd704c773530ba73b"
|
||||
checksum = "d86d6fac2fabe07b67b7835f46d07571f68b11aa1aaecae94fe722ea4ef305e1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"gix-trace",
|
||||
|
@ -2166,9 +2186,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-quote"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "475c86a97dd0127ba4465fbb239abac9ea10e68301470c9791a6dd5351cdc905"
|
||||
checksum = "4f84845efa535468bc79c5a87b9d29219f1da0313c8ecf0365a5daa7e72786f2"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"btoi",
|
||||
|
@ -2243,9 +2263,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-sec"
|
||||
version = "0.10.0"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92b9542ac025a8c02ed5d17b3fc031a111a384e859d0be3532ec4d58c40a0f28"
|
||||
checksum = "a36ea2c5907d64a9b4b5d3cc9f430e6c30f0509646b5e38eb275ca57c5bf29e2"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"gix-path",
|
||||
|
@ -2268,9 +2288,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-trace"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96b6d623a1152c3facb79067d6e2ecdae48130030cf27d6eb21109f13bd7b836"
|
||||
checksum = "b686a35799b53a9825575ca3f06481d0a053a409c4d97ffcf5ddd67a8760b497"
|
||||
|
||||
[[package]]
|
||||
name = "gix-traverse"
|
||||
|
@ -2304,18 +2324,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gix-utils"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b85d89dc728613e26e0ed952a19583744e7f5240fcd4aa30d6c824ffd8b52f0f"
|
||||
checksum = "9f82c41937f00e15a1f6cb0b55307f0ca1f77f4407ff2bf440be35aa688c6a3e"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gix-validate"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e05cab2b03a45b866156e052aa38619f4ece4adcb2f79978bfc249bc3b21b8c5"
|
||||
checksum = "75b7d8e4274be69f284bbc7e6bb2ccf7065dbcdeba22d8c549f2451ae426883f"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"thiserror",
|
||||
|
@ -2626,11 +2646,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
|||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.5"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2652,9 +2672,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
|
@ -2934,9 +2954,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
|
@ -3155,7 +3175,7 @@ dependencies = [
|
|||
"rpassword 7.3.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shellexpand",
|
||||
"shellexpand 2.1.2",
|
||||
"sketching",
|
||||
"time",
|
||||
"tokio",
|
||||
|
@ -3331,7 +3351,7 @@ version = "1.1.0-rc.15-dev"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3541,9 +3561,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.150"
|
||||
version = "0.2.151"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
|
@ -3610,9 +3630,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.11"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
||||
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
|
@ -3768,9 +3788,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.9"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
|
||||
checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
|
@ -3945,7 +3965,7 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4089,9 +4109,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
|
@ -4107,9 +4127,9 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
|||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.60"
|
||||
version = "0.10.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800"
|
||||
checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if",
|
||||
|
@ -4128,7 +4148,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4139,9 +4159,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.96"
|
||||
version = "0.9.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f"
|
||||
checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -4252,6 +4272,12 @@ dependencies = [
|
|||
"tokio-stream",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "orca"
|
||||
version = "1.1.0-rc.15-dev"
|
||||
|
@ -4514,7 +4540,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4631,7 +4657,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4829,15 +4855,6 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
|
@ -5019,9 +5036,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.0.0"
|
||||
version = "8.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1e7d90385b59f0a6bf3d3b757f3ca4ece2048265d70db20a2016043d4509a40"
|
||||
checksum = "810294a8a4a0853d4118e3b94bb079905f2107c7fe979d8f0faae98765eb6378"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
|
@ -5030,23 +5047,23 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.0.0"
|
||||
version = "8.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c3d8c6fd84090ae348e63a84336b112b5c3918b3bf0493a581f7bd8ee623c29"
|
||||
checksum = "bfc144a1273124a67b8c1d7cd19f5695d1878b31569c0512f6086f0f4676604e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"shellexpand",
|
||||
"syn 2.0.39",
|
||||
"shellexpand 3.1.0",
|
||||
"syn 2.0.41",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.0.0"
|
||||
version = "8.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "873feff8cb7bf86fdf0a71bb21c95159f4e4a37dd7a4bd1855a940909b583ada"
|
||||
checksum = "816ccd4875431253d6bb54b804bcff4369cbde9bae33defde25fdf6c2ef91d40"
|
||||
dependencies = [
|
||||
"sha2 0.10.8",
|
||||
"walkdir",
|
||||
|
@ -5084,15 +5101,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.25"
|
||||
version = "0.38.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
|
||||
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5103,9 +5120,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
|
@ -5295,7 +5312,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5357,7 +5374,7 @@ dependencies = [
|
|||
"darling 0.20.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5421,7 +5438,16 @@ version = "2.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"dirs 4.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shellexpand"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b"
|
||||
dependencies = [
|
||||
"dirs 5.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5619,9 +5645,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
version = "2.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -5698,27 +5724,27 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.50"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||
checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.50"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||
checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5809,9 +5835,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.34.0"
|
||||
version = "1.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9"
|
||||
checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
|
@ -5843,7 +5869,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5858,9 +5884,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-openssl"
|
||||
version = "0.6.3"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08f9ffb7809f1b20c1b398d92acf4cc719874b3b2b2d9ea2f09b4a80350878a"
|
||||
checksum = "6ffab79df67727f6acf57f1ff743091873c24c579b1e2ce4d8f53e47ded4d63d"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"openssl",
|
||||
|
@ -6028,7 +6054,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -6127,9 +6153,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "tss-esapi"
|
||||
|
@ -6186,9 +6212,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bom"
|
||||
|
@ -6275,7 +6301,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
@ -6381,7 +6407,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -6415,7 +6441,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -6448,7 +6474,7 @@ checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -6925,9 +6951,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.19"
|
||||
version = "0.5.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b"
|
||||
checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -7052,7 +7078,7 @@ checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -7072,7 +7098,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.41",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
1
Makefile
1
Makefile
|
@ -117,6 +117,7 @@ precommit: ## all the usual test things
|
|||
precommit: test codespell test/pykanidm doc/format
|
||||
|
||||
.PHONY: vendor
|
||||
vendor: ## Vendor required crates
|
||||
vendor:
|
||||
cargo vendor > cargo_vendor_config
|
||||
|
||||
|
|
|
@ -15,21 +15,19 @@
|
|||
- [Installing client tools](installing_client_tools.md)
|
||||
|
||||
- [Administration](administrivia.md)
|
||||
- [Accounts and Groups](accounts_and_groups.md)
|
||||
- [Account Policy](account_policy.md)
|
||||
- [Authentication and Credentials](authentication.md)
|
||||
- [POSIX Accounts and Groups](posix_accounts.md)
|
||||
- [Backup and Restore](backup_restore.md)
|
||||
- [Database Maintenance](database_maint.md)
|
||||
- [Domain Rename](domain_rename.md)
|
||||
- [Monitoring the platform](monitoring.md)
|
||||
- [Password Quality and Badlisting](password_quality.md)
|
||||
- [The Recycle Bin](recycle_bin.md)
|
||||
|
||||
- [Replication](repl/readme.md)
|
||||
- [Planning](repl/planning.md)
|
||||
- [Deployment](repl/deployment.md)
|
||||
- [Administration](repl/administration.md)
|
||||
- [Accounts and Groups](accounts/intro.md)
|
||||
- [People Accounts](accounts/people.md)
|
||||
- [Authentication and Credentials](accounts/authentication.md)
|
||||
- [Groups](accounts/groups.md)
|
||||
- [Service Accounts](accounts/service.md)
|
||||
- [Account Policy](accounts/policy.md)
|
||||
- [POSIX Accounts and Groups](accounts/posix.md)
|
||||
|
||||
- [Service Integrations](integrations/readme.md)
|
||||
- [PAM and nsswitch](integrations/pam_and_nsswitch.md)
|
||||
|
@ -46,6 +44,11 @@
|
|||
- [Kubernetes Ingress](examples/k8s_ingress_example.md)
|
||||
- [Traefik](examples/traefik.md)
|
||||
|
||||
- [Replication](repl/readme.md)
|
||||
- [Planning](repl/planning.md)
|
||||
- [Deployment](repl/deployment.md)
|
||||
- [Administration](repl/administration.md)
|
||||
|
||||
- [Synchronisation](sync/concepts.md)
|
||||
- [FreeIPA](sync/freeipa.md)
|
||||
- [LDAP](sync/ldap.md)
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
# Account Policy
|
||||
|
||||
Account Policy defines the security requirements that accounts must meet and influences users
|
||||
sessions.
|
||||
|
||||
Policy is defined on groups so that membership of a group influences the security of its members.
|
||||
This allows you to express that if you can access a system or resource, then the account must also
|
||||
meet the policy requirements.
|
||||
|
||||
## Default Account Policy
|
||||
|
||||
A default Account Policy is applied to `idm_all_accounts`. This provides the defaults that influence
|
||||
all accounts in Kanidm. This policy can be modified the same as any other group's policy.
|
||||
|
||||
## Policy Resolution
|
||||
|
||||
When an account is affected by multiple policies, the strictest component from each policy is
|
||||
applied. This can mean that two policies interact and make their combination stricter than their
|
||||
parts.
|
||||
|
||||
| value | ordering |
|
||||
| ----------------------- | -------------- |
|
||||
| auth-session | smallest value |
|
||||
| password-minimum-length | largest value |
|
||||
| privilege-expiry | smallest value |
|
||||
|
||||
### Example Resolution
|
||||
|
||||
If we had two policies where the first defined:
|
||||
|
||||
```text
|
||||
auth-session: 86400
|
||||
password-minimum-length: 10
|
||||
privilege-expiry: 600
|
||||
```
|
||||
|
||||
And the second
|
||||
|
||||
```text
|
||||
auth-session: 3600
|
||||
password-minimum-length: 15
|
||||
privilege-expiry: 3600
|
||||
```
|
||||
|
||||
As the value of auth-session from the second is smaller we would take that. We would take the
|
||||
smallest value of privilege-expiry from the first. We would take the largest value of
|
||||
password-minimum-length. This leaves:
|
||||
|
||||
```text
|
||||
auth-session: 3600
|
||||
password-minimum-length: 15
|
||||
privilege-expiry: 600
|
||||
```
|
||||
|
||||
## Enabling Account Policy
|
||||
|
||||
Account Policy is enabled on a group with the command:
|
||||
|
||||
```shell
|
||||
kanidm group account-policy enable <group name>
|
||||
kanidm group account-policy enable my_admin_group
|
||||
```
|
||||
|
||||
## Setting Maximum Session Time
|
||||
|
||||
The auth-session value influences the maximum time in seconds that an authenticated session can
|
||||
exist. After this time, the user must reauthenticate.
|
||||
|
||||
This value provides a difficult balance - forcing frequent re-authentications can frustrate and
|
||||
annoy users. However extremely long sessions allow a stolen or disclosed session token/device to
|
||||
read data for an extended period. Due to Kanidm's read/write separation this mitigates the risk of
|
||||
disclosed sessions as they can only _read_ data, not write it.
|
||||
|
||||
To set the maximum authentication session time
|
||||
|
||||
```shell
|
||||
kanidm group account-policy auth-expiry <group name> <seconds>
|
||||
kanidm group account-policy auth-expiry my_admin_group 86400
|
||||
```
|
||||
|
||||
## Setting Minimum Password Length
|
||||
|
||||
The password-minimum-length value defines the character length of passwords that are acceptable.
|
||||
There are no-other tunables for passwords in account policy. Other settings such as complexity,
|
||||
symbols, numbers and so on, have been proven to not matter in any real world attacks.
|
||||
|
||||
To set this value:
|
||||
|
||||
```shell
|
||||
kanidm group account-policy password-minimum-length <group name> <length>
|
||||
kanidm group account-policy password-minimum-length my_admin_group 12
|
||||
```
|
||||
|
||||
## Setting Maximum Privilege Time
|
||||
|
||||
The privilege-expiry time defines how long a session retains its write privileges after a
|
||||
reauthentication. After this time, the session returns to read-only mode.
|
||||
|
||||
To set the maximum privilege time
|
||||
|
||||
```shell
|
||||
kanidm group account-policy privilege-expiry <group name> <seconds>
|
||||
kanidm group account-policy privilege-expiry my_admin_group 900
|
||||
```
|
|
@ -16,14 +16,21 @@ secure method of authentication in Kanidm.
|
|||
|
||||
<!-- deno-fmt-ignore-start -->
|
||||
|
||||
{{#template templates/kani-warning.md
|
||||
{{#template ../templates/kani-warning.md
|
||||
imagepath=images
|
||||
title=Warning!
|
||||
text=Kanidm's definition of Passkeys differs to other systems. This is because we adopted the term very early before it has changed and evolved.
|
||||
text=Kanidm's definition of Passkeys may differ from that of other systems. This is because we adopted the term very early, before it has changed and evolved.
|
||||
}}
|
||||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
|
||||
### Attested Passkeys
|
||||
|
||||
These are the same as Passkeys, except that the device must present a cryptographic certificate or
|
||||
origin during registration. This allows [account policy](policy.md) to be defined to only allow the
|
||||
use of certain models of authenticator. In general only FIDO2 keys or TPM's are capable of meeting
|
||||
attestation requirements.
|
||||
|
||||
### Password + TOTP
|
||||
|
||||
This is a classic Time-based One Time Password combined with a password. Different to other systems
|
||||
|
@ -35,8 +42,13 @@ environments due to the fact it is still possible to perform realtime phishing a
|
|||
|
||||
## Resetting Person Account Credentials
|
||||
|
||||
Members of the `idm_account_manage_priv` group have the rights to manage person and service accounts
|
||||
security and login aspects. This includes resetting account credentials.
|
||||
Members of the groups `idm_people_admins`, `idm_people_on_boarding` and `idm_service_desk` have the
|
||||
rights to initiate a credential reset for a person.
|
||||
|
||||
> NOTE: If the person is a member of `idm_high_privilege` then these resets are not allowed. This is
|
||||
> to prevent `idm_service_desk` and similar roles from privilege escalation by resetting the
|
||||
> credentials of a higher privileged account. If a person who is a member of `idm_high_privilege`
|
||||
> requires a credential reset, this must be initiated by a member of `idm_people_admins`.
|
||||
|
||||
### Onboarding a New Person / Resetting Credentials
|
||||
|
||||
|
@ -82,16 +94,26 @@ kanidm person credential create-reset-token demo_user 86400 --name idm_admin
|
|||
If the user wishes you can direct them to `https://idm.mydomain.name/ui/reset` where they can
|
||||
manually enter their token value.
|
||||
|
||||
Once the credential has been set the token is immediately invalidated and can never be used again.
|
||||
By default the token is valid for 1 hour. You can request a longer token validity time when creating
|
||||
the token. Tokens are only allowed to be valid for a maximum of 24 hours.
|
||||
Once the credential reset has been committed the token is immediately invalidated and can never be
|
||||
used again. By default the token is valid for 1 hour. You can request a longer token validity time
|
||||
when creating the token. Tokens are only allowed to be valid for a maximum of 24 hours.
|
||||
|
||||
### Resetting Credentials Directly
|
||||
|
||||
You can perform a password reset on the demo\_user, for example as the idm\_admin user, who is a
|
||||
You can perform a password reset on the `demo_user`, for example as the `idm_admin` user, who is a
|
||||
default member of this group. The lines below prefixed with `#` are the interactive credential
|
||||
update interface. This allows the user to directly manage the credentials of another account.
|
||||
|
||||
<!-- deno-fmt-ignore-start -->
|
||||
|
||||
{{#template ../templates/kani-warning.md
|
||||
imagepath=images
|
||||
title=Warning!
|
||||
text=Don't use the direct credential reset to lock or invalidate an account. You should expire the account instead.
|
||||
}}
|
||||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
|
||||
```bash
|
||||
kanidm person credential update demo_user --name idm_admin
|
||||
# spn: demo_user@idm.example.com
|
||||
|
@ -115,15 +137,10 @@ kanidm login --name demo_user
|
|||
kanidm self whoami --name demo_user
|
||||
```
|
||||
|
||||
<!-- deno-fmt-ignore-start -->
|
||||
## Credential Deletion
|
||||
|
||||
{{#template templates/kani-warning.md
|
||||
imagepath=images
|
||||
title=Warning!
|
||||
text=Don't use the direct credential reset to lock or invalidate an account. You should expire the account instead.
|
||||
}}
|
||||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
When a person deletes a credential, all sessions that were created by that credential are
|
||||
immediately logged out and invalidated.
|
||||
|
||||
## Reauthentication / Privilege Access Mode
|
||||
|
76
book/src/accounts/groups.md
Normal file
76
book/src/accounts/groups.md
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Groups
|
||||
|
||||
Groups are a collection of other entities that exist within Kanidm.
|
||||
|
||||
## Creating Groups
|
||||
|
||||
Members of `idm_group_admins` can create new groups. `idm_admin` by default has these privileges.
|
||||
|
||||
```bash
|
||||
kanidm group create demo_group --name idm_admin
|
||||
kanidm group add-members demo_group demo_user --name idm_admin
|
||||
kanidm group list-members demo_group --name idm_admin
|
||||
```
|
||||
|
||||
After addition, you will see a reverse link from our `demo_user` showing that it is now a _member
|
||||
of_ the group `demo_group`. Kanidm makes all group membership determinations by inspecting an
|
||||
entry's "memberof" attribute.
|
||||
|
||||
```bash
|
||||
kanidm person get demo_user --name idm_admin
|
||||
```
|
||||
|
||||
## Nested Groups
|
||||
|
||||
Kanidm supports groups being members of groups, allowing nested groups. These nesting relationships
|
||||
are shown through the "memberof" attribute on groups and accounts. This allows nested groups to
|
||||
reflect on accounts.
|
||||
|
||||
An example can be easily shown with:
|
||||
|
||||
```bash
|
||||
kanidm group create group_1 --name idm_admin
|
||||
kanidm group create group_2 --name idm_admin
|
||||
kanidm person create nest_example "Nesting Account Example" --name idm_admin
|
||||
kanidm group add-members group_1 group_2 --name idm_admin
|
||||
kanidm group add-members group_2 nest_example --name idm_admin
|
||||
kanidm person get nest_example --name anonymous
|
||||
```
|
||||
|
||||
This should result in output similar to:
|
||||
|
||||
```
|
||||
memberof: idm_all_persons@localhost
|
||||
memberof: idm_all_accounts@localhost
|
||||
memberof: group_2@localhost
|
||||
memberof: group_1@localhost
|
||||
name: nest_example
|
||||
```
|
||||
|
||||
## Delegated Administration
|
||||
|
||||
Kanidm supports delegated administration though the "entry managed by" field. This allows specifying
|
||||
a group or user account that is the "entry manager" of a group. This allows the entry manager to
|
||||
modify the group without the need to define new access controls.
|
||||
|
||||
The `entry_managed_by` attribute of a group may only be modified by members of
|
||||
`idm_access_control_admins`. During entry creation `idm_group_admins` may set `entry_managed_by`,
|
||||
but may not change it post creation.
|
||||
|
||||
```bash
|
||||
kanidm group create <NAME> [ENTRY_MANAGED_BY]
|
||||
kanidm group create delegated_access_group demo_group --name idm_admin
|
||||
kanidm group get delegated_access_group --name idm_admin
|
||||
```
|
||||
|
||||
Now, as our `demo_user` is a member of `demo_group` they have delegated administration of
|
||||
`delegated_access_group`.
|
||||
|
||||
```bash
|
||||
kanidm login --name demo_user
|
||||
|
||||
note the use of demo_user --\
|
||||
v
|
||||
kanidm group add-members delegated_access_group admin --name demo_user
|
||||
kanidm group get delegated_access_group --name demo_user
|
||||
```
|
122
book/src/accounts/intro.md
Normal file
122
book/src/accounts/intro.md
Normal file
|
@ -0,0 +1,122 @@
|
|||
# Accounts and groups
|
||||
|
||||
Accounts and Groups are the primary reasons for Kanidm to exist. Kanidm is optimised as a repository
|
||||
for these data. As a result, there are many concepts and important details to understand.
|
||||
|
||||
## Service Accounts vs Person Accounts
|
||||
|
||||
Kanidm separates accounts into two types. Person accounts (or persons) are intended for use by
|
||||
humans that will access the system in an interactive way. Service accounts are intended for use by
|
||||
computers or services that need to identify themself to Kanidm. Generally a person or group of
|
||||
persons will be responsible for and will manage service accounts. Because of this distinction these
|
||||
classes of accounts have different properties and methods of authentication and management.
|
||||
|
||||
## Groups
|
||||
|
||||
Groups represent a collection of entities. This generally is a collection of persons or service
|
||||
accounts. Groups are commonly used to assign privileges to the accounts that are members of a group.
|
||||
This allows easier administration over larger systems where privileges can be assigned to groups in
|
||||
a logical manner, and then only membership of the groups need administration, rather than needing to
|
||||
assign privileges to each entity directly and uniquely.
|
||||
|
||||
Groups may also be nested, where a group can contain another group as a member. This allows
|
||||
hierarchies to be created again for easier administration.
|
||||
|
||||
## Default Accounts and Groups
|
||||
|
||||
Kanidm ships with a number of default service accounts and groups. This is to give you the best
|
||||
out-of-box experience possible, as well as supplying best practice examples related to modern
|
||||
Identity Management (IDM) systems.
|
||||
|
||||
There are two "break-glass" system administration accounts.
|
||||
|
||||
`admin` is the default service account which has privileges to configure and administer Kanidm as a
|
||||
whole. This account can manage access controls, schema, integrations and more. However the `admin`
|
||||
can not manage persons by default.
|
||||
|
||||
`idm_admin` is the default service account which has privileges to create persons and to manage
|
||||
these accounts and groups. They can perform credential resets and more.
|
||||
|
||||
Both the `admin` and the `idm_admin` user should _NOT_ be used for daily activities - they exist for
|
||||
initial system configuration, and for disaster recovery scenarios. You should delegate permissions
|
||||
as required to named user accounts instead.
|
||||
|
||||
The majority of the builtin groups are privilege groups that provide rights over Kanidm
|
||||
administrative actions. These include groups for account management, person management (personal and
|
||||
sensitive data), group management, and more.
|
||||
|
||||
`admin` and `idm_admin` both inherit their privileges from these default groups. This allows you to
|
||||
assign persons to these roles instead.
|
||||
|
||||
## Reauthentication and Session Privilege
|
||||
|
||||
Kanidm sessions have a concept of session privilege. Conceptually you can consider this like `sudo`
|
||||
on unix systems or `uac` on windows. This allows a session to briefly access its write permissions
|
||||
by reauthentication with the identical credential they logged in with.
|
||||
|
||||
This allows safe assignment of high privilege roles to persons since their sessions do not have
|
||||
access to their write privileges by default. They must reauthenticate and use their privileges
|
||||
within a short time window.
|
||||
|
||||
However, these sessions always retain their _read_ privileges - meaning that they can still access
|
||||
and view high levels of data at any time without reauthentication.
|
||||
|
||||
In high risk environments you should still consider assigning seperate administration accounts to
|
||||
users if this is considered a risk.
|
||||
|
||||
## Recovering the Initial Admin Accounts
|
||||
|
||||
By default the `admin` and `idm_admin` accounts have no password, and can not be accessed. They need
|
||||
to be "recovered" from the server that is running the kanidmd server.
|
||||
|
||||
You should have already recovered the admin account during your setup process. If not, refer to the
|
||||
[server configuration chapter](server_configuration.md#default-admin-account) on how to recover
|
||||
these accounts.
|
||||
|
||||
These accounts will be used through the remainder of this document for managing the server.
|
||||
|
||||
## Viewing Default Groups
|
||||
|
||||
You should take some time to inspect the default groups which are related to default roles and
|
||||
permissions. Each group has a description to explain its purpose. These can be viewed with:
|
||||
|
||||
```bash
|
||||
kanidm group list --name idm_admin
|
||||
kanidm group get <name>
|
||||
```
|
||||
|
||||
## Why Can't I Change admin With idm\_admin?
|
||||
|
||||
As a security mechanism there is a distinction between "accounts" and "high permission accounts".
|
||||
This is to help prevent elevation attacks, where a member of a service desk could attempt to reset
|
||||
the password of idm\_admin or admin, or even a member of HR or System Admin teams to move laterally.
|
||||
|
||||
Generally, membership of a "privilege" group that ships with Kanidm, such as:
|
||||
|
||||
- idm\_account\_manage\_priv
|
||||
- idm\_people\_read\_priv
|
||||
- idm\_schema\_manage\_priv
|
||||
- many more ...
|
||||
|
||||
...indirectly grants you membership to "idm\_high\_privilege". If you are a member of this group,
|
||||
the standard "account" and "people" rights groups are NOT able to alter, read or manage these
|
||||
accounts. To manage these accounts higher rights are required, such as those held by the admin
|
||||
account.
|
||||
|
||||
Further, groups that are considered "idm\_high\_privilege" can NOT be managed by the standard
|
||||
"idm\_group\_manage\_priv" group.
|
||||
|
||||
Management of high privilege accounts and groups is granted through the the "hp" variants of all
|
||||
privileges. A non-conclusive list:
|
||||
|
||||
- idm\_hp\_account\_read\_priv
|
||||
- idm\_hp\_account\_manage\_priv
|
||||
- idm\_hp\_account\_write\_priv
|
||||
- idm\_hp\_group\_manage\_priv
|
||||
- idm\_hp\_group\_write\_priv
|
||||
|
||||
Membership of any of these groups should be considered to be equivalent to system administration
|
||||
rights in the directory, and by extension, over all network resources that trust Kanidm.
|
||||
|
||||
All groups that are flagged as "idm\_high\_privilege" should be audited and monitored to ensure that
|
||||
they are not altered.
|
118
book/src/accounts/people.md
Normal file
118
book/src/accounts/people.md
Normal file
|
@ -0,0 +1,118 @@
|
|||
# People Accounts
|
||||
|
||||
A person represents a human's account in Kanidm. The majority of your users will be a person who
|
||||
will use this account in their daily activities. These entries may contain personally identifying
|
||||
information that _is_ considered by Kanidm to be sensitive. Because of this, there are default
|
||||
limits to who may access these data.
|
||||
|
||||
## Creating Person Accounts
|
||||
|
||||
Members of the `idm_people_admins` group have the privileges to create new persons in the system. By
|
||||
default `idm_admin` has this permission.
|
||||
|
||||
```bash
|
||||
kanidm login --name idm_admin
|
||||
kanidm person create demo_user "Demonstration User" --name idm_admin
|
||||
kanidm person get demo_user --name idm_admin
|
||||
```
|
||||
|
||||
Kanidm allows person accounts to include personally identifying attributes, such as their legal name
|
||||
and email address.
|
||||
|
||||
Initially, a person does not have these attributes. If desired, a person may be modified to have
|
||||
these attributes.
|
||||
|
||||
```bash
|
||||
# Note, both the --legalname and --mail flags may be omitted
|
||||
kanidm person update demo_user --legalname "initial name" --mail "initial@email.address"
|
||||
```
|
||||
|
||||
You can also use anonymous to view accounts - note that you won't see certain fields due to the
|
||||
limits of the anonymous access control profile.
|
||||
|
||||
```bash
|
||||
kanidm login --name anonymous
|
||||
kanidm person get demo_user --name anonymous
|
||||
```
|
||||
|
||||
> NOTE: only members of `idm_people_pii_read` and `idm_people_admins` may read personal information
|
||||
> by default.
|
||||
|
||||
<!-- deno-fmt-ignore-start -->
|
||||
|
||||
{{#template ../templates/kani-warning.md
|
||||
imagepath=images
|
||||
title=Warning!
|
||||
text=Persons may change their own displayname, name, and legal name at any time. You MUST NOT use these values as primary keys in external systems. You MUST use the `uuid` attribute present on all entries as an external primary key.
|
||||
}}
|
||||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
|
||||
## Account Validity
|
||||
|
||||
Kanidm supports accounts that are only able to authenticate between a pair of dates and times; the
|
||||
"valid from" and "expires" timestamps define these points in time. By default members of
|
||||
`idm_people_admins` may change these values.
|
||||
|
||||
The account validity can be displayed with:
|
||||
|
||||
```bash
|
||||
kanidm person validity show demo_user --name idm_admin
|
||||
user: demo_user
|
||||
valid after: any time
|
||||
expire: never
|
||||
```
|
||||
|
||||
```bash
|
||||
kanidm person validity show demo_user --name idm_admin
|
||||
valid after: 2020-09-25T21:22:04+10:00
|
||||
expire: 2020-09-25T01:22:04+10:00
|
||||
```
|
||||
|
||||
These datetimes are stored in the server as UTC, but presented according to your local system time
|
||||
to aid correct understanding of when the events will occur.
|
||||
|
||||
You may set these time and date values in any timezone you wish (such as your local timezone), and
|
||||
the server will transform these to UTC. These time values are in ISO8601 format, and you should
|
||||
specify this as:
|
||||
|
||||
```shell
|
||||
YYYY-MM-DDThh:mm:ssZ+-hh:mm
|
||||
Year-Month-Day T hour:minutes:seconds Z +- timezone offset
|
||||
```
|
||||
|
||||
Set the earliest time the account can start authenticating:
|
||||
|
||||
```bash
|
||||
kanidm person validity begin-from demo_user '2020-09-25T11:22:04+00:00' --name idm_admin
|
||||
```
|
||||
|
||||
Set the expiry or end date of the account:
|
||||
|
||||
```bash
|
||||
kanidm person validity expire-at demo_user '2020-09-25T11:22:04+00:00' --name idm_admin
|
||||
```
|
||||
|
||||
To unset or remove these values the following can be used, where `any|clear` means you may use
|
||||
either `any` or `clear`.
|
||||
|
||||
```bash
|
||||
kanidm person validity begin-from demo_user any|clear --name idm_admin
|
||||
kanidm person validity expire-at demo_user clear|epoch|now --name idm_admin
|
||||
```
|
||||
|
||||
To "lock" an account, you can set the `expire_at` value to `now` or `epoch`. Even in the situation
|
||||
where the "valid from" is _after_ the `expire_at`, the `expire_at` will be respected.
|
||||
|
||||
These validity settings impact all authentication functions of the account (kanidm, ldap, radius).
|
||||
|
||||
### Allowing people accounts to change their mail attribute
|
||||
|
||||
By default, Kanidm allows an account to change some attributes, but not their mail address.
|
||||
|
||||
Adding the user to the `idm_people_self_write_mail` group, as shown below, allows the user to edit
|
||||
their own mail.
|
||||
|
||||
```bash
|
||||
kanidm group add-members idm_people_self_write_mail_priv demo_user --name idm_admin
|
||||
```
|
223
book/src/accounts/policy.md
Normal file
223
book/src/accounts/policy.md
Normal file
|
@ -0,0 +1,223 @@
|
|||
# Account Policy
|
||||
|
||||
Account Policy defines the security requirements that accounts must meet and influences users
|
||||
sessions.
|
||||
|
||||
Policy is defined on groups so that membership of a group influences the security of its members.
|
||||
This allows you to express that if you can access a system or resource, then the account must also
|
||||
meet the policy requirements.
|
||||
|
||||
All account policy settings may be managed by members of `idm_account_policy_admins`. This is
|
||||
assigned to `idm_admin` by default.
|
||||
|
||||
## Default Account Policy
|
||||
|
||||
A default Account Policy is applied to `idm_all_accounts`. This provides the defaults that influence
|
||||
all accounts in Kanidm. This policy can be modified the same as any other group's policy.
|
||||
|
||||
## Enforced Attributes
|
||||
|
||||
### Auth Expiry
|
||||
|
||||
The maximum length in seconds that an authentication session may exist for.
|
||||
|
||||
### Password Minimum Length
|
||||
|
||||
The minimum length for passwords (if they are allowed).
|
||||
|
||||
### Privilege Expiry
|
||||
|
||||
The maximum length in seconds that privileges will exist after reauthentication for to a read/write
|
||||
session.
|
||||
|
||||
### Webauthn Attestation
|
||||
|
||||
The list of certificate authorities and device aaguids that must be used by members of this policy.
|
||||
This allows limiting devices to specific models.
|
||||
|
||||
To generate this list you should use `fido-mds-tool`.
|
||||
|
||||
## Policy Resolution
|
||||
|
||||
When an account is affected by multiple policies, the strictest component from each policy is
|
||||
applied. This can mean that two policies interact and make their combination stricter than their
|
||||
parts.
|
||||
|
||||
| value | ordering |
|
||||
| ---------------------------- | ---------------------------- |
|
||||
| auth-expiry | smallest value |
|
||||
| password-minimum-length | largest value |
|
||||
| privilege-expiry | smallest value |
|
||||
| webauthn-attestation-ca-list | intersection of equal values |
|
||||
|
||||
### Example Resolution
|
||||
|
||||
If we had two policies where the first defined:
|
||||
|
||||
```text
|
||||
auth-session: 86400
|
||||
password-minimum-length: 10
|
||||
privilege-expiry: 600
|
||||
webauthn-attestation-ca-list: [ "yubikey 5ci", "yubikey 5fips" ]
|
||||
```
|
||||
|
||||
And the second
|
||||
|
||||
```text
|
||||
auth-session: 3600
|
||||
password-minimum-length: 15
|
||||
privilege-expiry: 3600
|
||||
webauthn-attestation-ca-list: [ "yubikey 5fips", "feitian epass" ]
|
||||
```
|
||||
|
||||
As the value of auth-session from the second is smaller we would take that. We would take the
|
||||
smallest value of privilege-expiry from the first. We would take the largest value of
|
||||
password-minimum-length. From the intersection of the webauthn attestation CA lists we would take
|
||||
only the elements that are in both. This leaves:
|
||||
|
||||
```text
|
||||
auth-session: 3600
|
||||
password-minimum-length: 15
|
||||
privilege-expiry: 600
|
||||
webauthn-attestation-ca-list: [ "yubikey 5fips" ]
|
||||
```
|
||||
|
||||
## Enabling Account Policy
|
||||
|
||||
Account Policy is enabled on a group with the command:
|
||||
|
||||
```shell
|
||||
kanidm group account-policy enable <group name>
|
||||
kanidm group account-policy enable my_admin_group
|
||||
```
|
||||
|
||||
### Setting Maximum Session Time
|
||||
|
||||
The auth-session value influences the maximum time in seconds that an authenticated session can
|
||||
exist. After this time, the user must reauthenticate.
|
||||
|
||||
This value provides a difficult balance - forcing frequent re-authentications can frustrate and
|
||||
annoy users. However extremely long sessions allow a stolen or disclosed session token/device to
|
||||
read data for an extended period. Due to Kanidm's read/write separation this mitigates the risk of
|
||||
disclosed sessions as they can only _read_ data, not write it.
|
||||
|
||||
To set the maximum authentication session time
|
||||
|
||||
```shell
|
||||
kanidm group account-policy auth-expiry <group name> <seconds>
|
||||
kanidm group account-policy auth-expiry my_admin_group 86400
|
||||
```
|
||||
|
||||
### Setting Minimum Password Length
|
||||
|
||||
The password-minimum-length value defines the character length of passwords that are acceptable.
|
||||
There are no other tunables for passwords in account policy. Other settings such as complexity,
|
||||
symbols, numbers and so on, have been proven to not matter in any real world attacks.
|
||||
|
||||
To set this value:
|
||||
|
||||
```shell
|
||||
kanidm group account-policy password-minimum-length <group name> <length>
|
||||
kanidm group account-policy password-minimum-length my_admin_group 12
|
||||
```
|
||||
|
||||
### Setting Maximum Privilege Time
|
||||
|
||||
The privilege-expiry time defines how long a session retains its write privileges after a
|
||||
reauthentication. After this time, the session returns to read-only mode.
|
||||
|
||||
To set the maximum privilege time
|
||||
|
||||
```shell
|
||||
kanidm group account-policy privilege-expiry <group name> <seconds>
|
||||
kanidm group account-policy privilege-expiry my_admin_group 900
|
||||
```
|
||||
|
||||
### Setting Webauthn Attestation CA Lists
|
||||
|
||||
The list should be generated with `fido-mds-tool`. This will emit JSON that can be directly used
|
||||
with Kanidm.
|
||||
|
||||
```bash
|
||||
kanidm group account-policy webauthn-attestation-ca-list <group name> <attestation ca list json>
|
||||
kanidm group account-policy webauthn-attestation-ca-list idm_all_persons '{"cas":{"D6E4b4Drh .... }'
|
||||
```
|
||||
|
||||
> NOTE: `fido-mds-tool` is available in the `kanidm:tools` container.
|
||||
|
||||
## Global Settings
|
||||
|
||||
There are a small number of account policy settings that are set globally rather than on a per group
|
||||
basis.
|
||||
|
||||
### Denied Names
|
||||
|
||||
Users of Kanidm can change their name at any time. However, there are some cases where you may wish
|
||||
to deny some name values from being usable. This can be due to conflicting system account names or
|
||||
to exclude insulting or other abusive terms.
|
||||
|
||||
To achieve this you can set names to be in the denied-name list:
|
||||
|
||||
```bash
|
||||
kanidm system denied-names append <name> [<name> ...]
|
||||
```
|
||||
|
||||
You can display the currently denied names with:
|
||||
|
||||
```bash
|
||||
kanidm system denied-names show
|
||||
```
|
||||
|
||||
To allow a name to be used again it can be removed from the list:
|
||||
|
||||
```
|
||||
kanidm system denied-names remove <name> [<name> ...]
|
||||
```
|
||||
|
||||
### Password Quality
|
||||
|
||||
Kanidm enforces that all passwords are checked by the library
|
||||
"[zxcvbn](https://github.com/dropbox/zxcvbn)". This has a large number of checks for password
|
||||
quality. It also provides constructive feedback to users on how to improve their passwords if they
|
||||
are rejected.
|
||||
|
||||
Some things that zxcvbn looks for is use of the account name or email in the password, common
|
||||
passwords, low entropy passwords, dates, reverse words and more.
|
||||
|
||||
This library can not be disabled - all passwords in Kanidm must pass this check.
|
||||
|
||||
### Password Badlisting
|
||||
|
||||
This is the process of configuring a list of passwords to exclude from being able to be used. This
|
||||
is especially useful if a specific business has been notified of compromised accounts, allowing you
|
||||
to maintain a list of customised excluded passwords.
|
||||
|
||||
The other value to this feature is being able to badlist common passwords that zxcvbn does not
|
||||
detect, or from other large scale password compromises.
|
||||
|
||||
By default we ship with a preconfigured badlist that is updated over time as new password breach
|
||||
lists are made available.
|
||||
|
||||
The password badlist by default is append only, meaning it can only grow, but will never remove
|
||||
passwords previously considered breached.
|
||||
|
||||
You can display the current badlist with:
|
||||
|
||||
```bash
|
||||
kanidm system pw-badlist show
|
||||
```
|
||||
|
||||
You can update your own badlist with:
|
||||
|
||||
```bash
|
||||
kanidm system pw-badlist upload "path/to/badlist" [...]
|
||||
```
|
||||
|
||||
Multiple bad lists can be listed and uploaded at once. These are preprocessed to identify and remove
|
||||
passwords that zxcvbn and our password rules would already have eliminated. That helps to make the
|
||||
bad list more efficient to operate over at run time.
|
||||
|
||||
### Password Rotation
|
||||
|
||||
Kanidm will never support this "anti-feature". Password rotation encourages poor password hygiene
|
||||
and is not shown to prevent any attacks - rather it _significantly weakens password security_.
|
|
@ -72,7 +72,7 @@ process applications for HR/People that are capable of supplying this kind of da
|
|||
### Enabling POSIX Attributes on Accounts
|
||||
|
||||
To enable POSIX account features and IDs on an account, you require the permission
|
||||
`idm_account_unix_extend_priv`. This is provided to `idm_admins` in the default database.
|
||||
`idm_unix_admins`. This is provided to `idm_admins` by default.
|
||||
|
||||
You can then use the following command to enable POSIX extensions on a person or service account.
|
||||
|
||||
|
@ -97,8 +97,8 @@ kanidm service-account posix show --name anonymous demo_account
|
|||
|
||||
### Enabling POSIX Attributes on Groups
|
||||
|
||||
To enable POSIX group features and IDs on an account, you require the permission
|
||||
`idm_group_unix_extend_priv`. This is provided to `idm_admins` in the default database.
|
||||
To enable POSIX group features and IDs on an account, you require the permission `idm_unix_admins`.
|
||||
This is provided to `idm_admins` by default.
|
||||
|
||||
You can then use the following command to enable POSIX extensions:
|
||||
|
78
book/src/accounts/service.md
Normal file
78
book/src/accounts/service.md
Normal file
|
@ -0,0 +1,78 @@
|
|||
# Service Accounts
|
||||
|
||||
## Creating Service Accounts
|
||||
|
||||
Members of `idm_service_account_admins` have the privileges to create new service accounts. By
|
||||
default `idm_admin` has this access.
|
||||
|
||||
When creating a service account you must delegate entry management to another group or account. This
|
||||
allows other users or groups to update the service account.
|
||||
|
||||
The `entry_managed_by` attribute of a service account may be created and modified by members of
|
||||
`idm_service_account_admins`.
|
||||
|
||||
> NOTE: If a service account is a member of `idm_high_privilege` its `entry_managed_by` may only be
|
||||
> modified by members of `idm_access_control_admins`
|
||||
|
||||
```bash
|
||||
kanidm service-account create <ACCOUNT_ID> <display-name> <entry-managed-by>
|
||||
kanidm service-account create demo_service "Demonstration Service" demo_group --name idm_admin
|
||||
kanidm service-account get demo_service --name idm_admin
|
||||
```
|
||||
|
||||
By delegating the administration of this service account to `demo_group` this allows our `demo_user`
|
||||
to administer the service account.
|
||||
|
||||
## Using API Tokens with Service Accounts
|
||||
|
||||
Service accounts can have API tokens generated and associated with them. These tokens can be used
|
||||
for identification of the service account, and for granting extended access rights where the service
|
||||
account may previously have not had the access. Additionally service accounts can have expiry times
|
||||
and other auditing information attached.
|
||||
|
||||
To show API tokens for a service account:
|
||||
|
||||
```bash
|
||||
kanidm service-account api-token status --name ENTRY_MANAGER ACCOUNT_ID
|
||||
kanidm service-account api-token status --name demo_user demo_service
|
||||
```
|
||||
|
||||
By default API tokens are issued to be "read only", so they are unable to make changes on behalf of
|
||||
the service account they represent. To generate a new read only API token with optional expiry time:
|
||||
|
||||
```bash
|
||||
kanidm service-account api-token generate --name ENTRY_MANAGER ACCOUNT_ID LABEL [EXPIRY]
|
||||
kanidm service-account api-token generate --name demo_user demo_service "Test Token"
|
||||
kanidm service-account api-token generate --name demo_user demo_service "Test Token" 2020-09-25T11:22:02+10:00
|
||||
```
|
||||
|
||||
If you wish to issue a token that is able to make changes on behalf of the service account, you must
|
||||
add the `--rw` flag during the generate command. It is recommended you only add `--rw` when the API
|
||||
token is performing writes to Kanidm.
|
||||
|
||||
```bash
|
||||
kanidm service-account api-token generate --name ENTRY_MANAGER ACCOUNT_ID LABEL [EXPIRY] --rw
|
||||
kanidm service-account api-token generate --name demo_user demo_service "Test Token" --rw
|
||||
kanidm service-account api-token generate --name demo_user demo_service "Test Token" 2020-09-25T11:22:02+10:00 --rw
|
||||
```
|
||||
|
||||
To destroy (revoke) an API token you will need its token id. This can be shown with the "status"
|
||||
command.
|
||||
|
||||
```bash
|
||||
kanidm service-account api-token status --name ENTRY_MANAGER ACCOUNT_ID
|
||||
kanidm service-account api-token status --name demo_user demo_service
|
||||
kanidm service-account api-token destroy --name ENTRY_MANAGER ACCOUNT_ID TOKEN_ID
|
||||
kanidm service-account api-token destroy --name demo_user demo_service 4de2a4e9-e06a-4c5e-8a1b-33f4e7dd5dc7
|
||||
```
|
||||
|
||||
## API Tokens with LDAP
|
||||
|
||||
API tokens can also be used to gain extended search permissions with LDAP. To do this you can bind
|
||||
with a dn of `dn=token` and provide the API token as the password.
|
||||
|
||||
```bash
|
||||
ldapwhoami -H ldaps://URL -x -D "dn=token" -w "TOKEN"
|
||||
ldapwhoami -H ldaps://idm.example.com -x -D "dn=token" -w "..."
|
||||
# u: demo_service@idm.example.com
|
||||
```
|
|
@ -1,345 +0,0 @@
|
|||
# Accounts and groups
|
||||
|
||||
Accounts and Groups are the primary reasons for Kanidm to exist. Kanidm is optimised as a repository
|
||||
for these data. As a result, there are many concepts and important details to understand.
|
||||
|
||||
## Service Accounts vs Person Accounts
|
||||
|
||||
Kanidm separates accounts into two types. Person accounts (or persons) are intended for use by
|
||||
humans that will access the system in an interactive way. Service accounts are intended for use by
|
||||
computers or services that need to identify themself to Kanidm. Generally a person or group of
|
||||
persons will be responsible for and will manage service accounts. Because of this distinction these
|
||||
classes of accounts have different properties and methods of authentication and management.
|
||||
|
||||
## Groups
|
||||
|
||||
Groups represent a collection of entities. This generally is a collection of persons or service
|
||||
accounts. Groups are commonly used to assign privileges to the accounts that are members of a group.
|
||||
This allows easier administration over larger systems where privileges can be assigned to groups in
|
||||
a logical manner, and then only membership of the groups need administration, rather than needing to
|
||||
assign privileges to each entity directly and uniquely.
|
||||
|
||||
Groups may also be nested, where a group can contain another group as a member. This allows
|
||||
hierarchies to be created again for easier administration.
|
||||
|
||||
## Default Accounts and Groups
|
||||
|
||||
Kanidm ships with a number of default service accounts and groups. This is to give you the best
|
||||
out-of-box experience possible, as well as supplying best practice examples related to modern
|
||||
Identity Management (IDM) systems.
|
||||
|
||||
There are two builtin system administration accounts.
|
||||
|
||||
`admin` is the default service account which has privileges to configure and administer kanidm as a
|
||||
whole. This account can manage access controls, schema, integrations and more. However the `admin`
|
||||
can not manage persons by default to separate the privileges. As this is a service account it is
|
||||
intended for limited use.
|
||||
|
||||
`idm_admin` is the default service account which has privileges to create persons and to manage
|
||||
these accounts and groups. They can perform credential resets and more.
|
||||
|
||||
Both the `admin` and the `idm_admin` user should _NOT_ be used for daily activities - they exist for
|
||||
initial system configuration, and for disaster recovery scenarios. You should delegate permissions
|
||||
as required to named user accounts instead.
|
||||
|
||||
The majority of the builtin groups are privilege groups that provide rights over Kanidm
|
||||
administrative actions. These include groups for account management, person management (personal and
|
||||
sensitive data), group management, and more.
|
||||
|
||||
## Recovering the Initial Admin Accounts
|
||||
|
||||
By default the `admin` and `idm_admin` accounts have no password, and can not be accessed. They need
|
||||
to be "recovered" from the server that is running the kanidmd server.
|
||||
|
||||
You should have already recovered the admin account during your setup process. If not refer to the
|
||||
[server configuration chapter](server_configuration.md#default-admin-account) on how to recover this
|
||||
account.
|
||||
|
||||
Once you have access to the admin account, it is able to reset the credentials of the `idm_admin`
|
||||
account.
|
||||
|
||||
```bash
|
||||
kanidm login -D admin
|
||||
kanidm service-account credential generate -D admin idm_admin
|
||||
# Success: wJX...
|
||||
```
|
||||
|
||||
These accounts will be used through the remainder of this document for managing the server.
|
||||
|
||||
## Viewing Default Groups
|
||||
|
||||
You should take some time to inspect the default groups which are related to default permissions.
|
||||
These can be viewed with:
|
||||
|
||||
```bash
|
||||
kanidm group list
|
||||
kanidm group get <name>
|
||||
```
|
||||
|
||||
## Creating Person Accounts
|
||||
|
||||
By default `idm_admin` has the privileges to create new persons in the system.
|
||||
|
||||
```bash
|
||||
kanidm login --name idm_admin
|
||||
kanidm person create demo_user "Demonstration User" --name idm_admin
|
||||
kanidm person get demo_user --name idm_admin
|
||||
|
||||
kanidm group create demo_group --name idm_admin
|
||||
kanidm group add-members demo_group demo_user --name idm_admin
|
||||
kanidm group list-members demo_group --name idm_admin
|
||||
```
|
||||
|
||||
You can also use anonymous to view accounts and groups - note that you won't see certain fields due
|
||||
to the limits of the access control anonymous access profile.
|
||||
|
||||
```bash
|
||||
kanidm login --name anonymous
|
||||
kanidm person get demo_user --name anonymous
|
||||
```
|
||||
|
||||
Kanidm allows person accounts to include human related attributes, such as their legal name and
|
||||
email address.
|
||||
|
||||
Initially, a person does not have these attributes. If desired, a person may be modified to have
|
||||
these attributes.
|
||||
|
||||
```bash
|
||||
# Note, both the --legalname and --mail flags may be omitted
|
||||
kanidm person update demo_user --legalname "initial name" --mail "initial@email.address"
|
||||
```
|
||||
|
||||
<!-- deno-fmt-ignore-start -->
|
||||
|
||||
{{#template templates/kani-warning.md
|
||||
imagepath=images
|
||||
title=Warning!
|
||||
text=Persons may change their own displayname, name, and legal name at any time. You MUST NOT use these values as primary keys in external systems. You MUST use the `uuid` attribute present on all entries as an external primary key.
|
||||
}}
|
||||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
|
||||
## Creating Service Accounts
|
||||
|
||||
The `admin` service account can be used to create service accounts.
|
||||
|
||||
```bash
|
||||
kanidm service-account create demo_service "Demonstration Service" --name admin
|
||||
kanidm service-account get demo_service --name admin
|
||||
```
|
||||
|
||||
## Using API Tokens with Service Accounts
|
||||
|
||||
Service accounts can have api tokens generated and associated with them. These tokens can be used
|
||||
for identification of the service account, and for granting extended access rights where the service
|
||||
account may previously have not had the access. Additionally service accounts can have expiry times
|
||||
and other auditing information attached.
|
||||
|
||||
To show api tokens for a service account:
|
||||
|
||||
```bash
|
||||
kanidm service-account api-token status --name idm_admin ACCOUNT_ID
|
||||
kanidm service-account api-token status --name idm_admin demo_service
|
||||
```
|
||||
|
||||
By default api tokens are issued to be "read only", so they are unable to make changes on behalf of
|
||||
the service account they represent. To generate a new read only api token:
|
||||
|
||||
```bash
|
||||
kanidm service-account api-token generate --name idm_admin ACCOUNT_ID LABEL [EXPIRY]
|
||||
kanidm service-account api-token generate --name idm_admin demo_service "Test Token"
|
||||
kanidm service-account api-token generate --name idm_admin demo_service "Test Token" 2020-09-25T11:22:02+10:00
|
||||
```
|
||||
|
||||
If you wish to issue a token that is able to make changes on behalf of the service account, you must
|
||||
add the "--rw" flag during the generate command. It is recommended you only add --rw when the
|
||||
api-token is performing writes to Kanidm.
|
||||
|
||||
```bash
|
||||
kanidm service-account api-token generate --name idm_admin ACCOUNT_ID LABEL [EXPIRY] --rw
|
||||
kanidm service-account api-token generate --name idm_admin demo_service "Test Token" --rw
|
||||
kanidm service-account api-token generate --name idm_admin demo_service "Test Token" 2020-09-25T11:22:02+10:00 --rw
|
||||
```
|
||||
|
||||
To destroy (revoke) an api token you will need it's token id. This can be shown with the "status"
|
||||
command.
|
||||
|
||||
```bash
|
||||
kanidm service-account api-token destroy --name idm_admin ACCOUNT_ID TOKEN_ID
|
||||
kanidm service-account api-token destroy --name idm_admin demo_service 4de2a4e9-e06a-4c5e-8a1b-33f4e7dd5dc7
|
||||
```
|
||||
|
||||
Api tokens can also be used to gain extended search permissions with LDAP. To do this you can bind
|
||||
with a dn of `dn=token` and provide the api token in the password.
|
||||
|
||||
```bash
|
||||
ldapwhoami -H ldaps://URL -x -D "dn=token" -w "TOKEN"
|
||||
ldapwhoami -H ldaps://idm.example.com -x -D "dn=token" -w "..."
|
||||
# u: demo_service@idm.example.com
|
||||
```
|
||||
|
||||
## Resetting Service Account Credentials (Deprecated)
|
||||
|
||||
<!-- deno-fmt-ignore-start -->
|
||||
|
||||
{{#template templates/kani-warning.md
|
||||
imagepath=images
|
||||
text=Api Tokens are a better method to manage credentials for service accounts, and passwords may be removed in the future!
|
||||
}}
|
||||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
|
||||
Service accounts can not have their credentials interactively updated in the same manner as persons.
|
||||
Service accounts may only have server side generated high entropy passwords.
|
||||
|
||||
To re-generate this password to an account
|
||||
|
||||
```bash
|
||||
kanidm service-account credential generate demo_service --name admin
|
||||
```
|
||||
|
||||
## Nested Groups
|
||||
|
||||
Kanidm supports groups being members of groups, allowing nested groups. These nesting relationships
|
||||
are shown through the "memberof" attribute on groups and accounts.
|
||||
|
||||
Kanidm makes all group membership determinations by inspecting an entry's "memberof" attribute.
|
||||
|
||||
An example can be easily shown with:
|
||||
|
||||
```bash
|
||||
kanidm group create group_1 --name idm_admin
|
||||
kanidm group create group_2 --name idm_admin
|
||||
kanidm person create nest_example "Nesting Account Example" --name idm_admin
|
||||
kanidm group add-members group_1 group_2 --name idm_admin
|
||||
kanidm group add-members group_2 nest_example --name idm_admin
|
||||
kanidm person get nest_example --name anonymous
|
||||
```
|
||||
|
||||
## Account Validity
|
||||
|
||||
Kanidm supports accounts that are only able to authenticate between a pair of dates and times; the
|
||||
"valid from" and "expires" timestamps define these points in time.
|
||||
|
||||
This can be displayed with:
|
||||
|
||||
```bash
|
||||
kanidm person validity show demo_user --name idm_admin
|
||||
valid after: 2020-09-25T21:22:04+10:00
|
||||
expire: 2020-09-25T01:22:04+10:00
|
||||
```
|
||||
|
||||
These datetimes are stored in the server as UTC, but presented according to your local system time
|
||||
to aid correct understanding of when the events will occur.
|
||||
|
||||
To set the values, an account with account management permission is required (for example,
|
||||
idm_admin).
|
||||
|
||||
You may set these time and date values in any timezone you wish (such as your local timezone), and
|
||||
the server will transform these to UTC. These time values are in iso8601 format, and you should
|
||||
specify this as:
|
||||
|
||||
```shell
|
||||
YYYY-MM-DDThh:mm:ssZ+-hh:mm
|
||||
Year-Month-Day T hour:minutes:seconds Z +- timezone offset
|
||||
```
|
||||
|
||||
Set the earliest time the account can start authenticating:
|
||||
|
||||
```bash
|
||||
kanidm person validity begin_from demo_user '2020-09-25T11:22:04+00:00' --name idm_admin
|
||||
```
|
||||
|
||||
Set the expiry or end date of the account:
|
||||
|
||||
```bash
|
||||
kanidm person validity expire_at demo_user '2020-09-25T11:22:04+00:00' --name idm_admin
|
||||
```
|
||||
|
||||
To unset or remove these values the following can be used, where `any|clear` means you may use
|
||||
either `any` or `clear`.
|
||||
|
||||
```bash
|
||||
kanidm person validity begin_from demo_user any|clear --name idm_admin
|
||||
kanidm person validity expire_at demo_user never|clear --name idm_admin
|
||||
```
|
||||
|
||||
To "lock" an account, you can set the expire_at value to the past, or unix epoch. Even in the
|
||||
situation where the "valid from" is _after_ the expire_at, the expire_at will be respected.
|
||||
|
||||
```bash
|
||||
kanidm person validity expire_at demo_user 1970-01-01T00:00:00+00:00 --name idm_admin
|
||||
```
|
||||
|
||||
These validity settings impact all authentication functions of the account (kanidm, ldap, radius).
|
||||
|
||||
### Allowing people accounts to change their mail attribute
|
||||
|
||||
By default, Kanidm allows an account to change some attributes, but not their mail address.
|
||||
|
||||
Adding the user to the `idm_people_self_write_mail` group, as shown below, allows the user to edit
|
||||
their own mail.
|
||||
|
||||
```bash
|
||||
kanidm group add-members idm_people_self_write_mail_priv demo_user --name idm_admin
|
||||
```
|
||||
|
||||
### Denied Names
|
||||
|
||||
Users of Kanidm can change their name at any time. However, there are some cases where you may wish
|
||||
to deny some name values from being usable.
|
||||
|
||||
To achieve this you can set names to be in the denied-name list:
|
||||
|
||||
```bash
|
||||
kanidm system denied-names append <name> [<name> ...]
|
||||
```
|
||||
|
||||
You can display the currently denied names with:
|
||||
|
||||
```bash
|
||||
kanidm system denied-names show
|
||||
```
|
||||
|
||||
To allow a name to be used again it can be removed from the list:
|
||||
|
||||
```
|
||||
kanidm system denied-names remove <name> [<name> ...]
|
||||
```
|
||||
|
||||
## Why Can't I Change admin With idm\_admin?
|
||||
|
||||
As a security mechanism there is a distinction between "accounts" and "high permission accounts".
|
||||
This is to help prevent elevation attacks, where say a member of a service desk could attempt to
|
||||
reset the password of idm\_admin or admin, or even a member of HR or System Admin teams to move
|
||||
laterally.
|
||||
|
||||
Generally, membership of a "privilege" group that ships with Kanidm, such as:
|
||||
|
||||
- idm\_account\_manage\_priv
|
||||
- idm\_people\_read\_priv
|
||||
- idm\_schema\_manage\_priv
|
||||
- many more ...
|
||||
|
||||
...indirectly grants you membership to "idm\_high\_privilege". If you are a member of this group,
|
||||
the standard "account" and "people" rights groups are NOT able to alter, read or manage these
|
||||
accounts. To manage these accounts higher rights are required, such as those held by the admin
|
||||
account are required.
|
||||
|
||||
Further, groups that are considered "idm\_high\_privilege" can NOT be managed by the standard
|
||||
"idm\_group\_manage\_priv" group.
|
||||
|
||||
Management of high privilege accounts and groups is granted through the the "hp" variants of all
|
||||
privileges. A non-conclusive list:
|
||||
|
||||
- idm\_hp\_account\_read\_priv
|
||||
- idm\_hp\_account\_manage\_priv
|
||||
- idm\_hp\_account\_write\_priv
|
||||
- idm\_hp\_group\_manage\_priv
|
||||
- idm\_hp\_group\_write\_priv
|
||||
|
||||
Membership of any of these groups should be considered to be equivalent to system administration
|
||||
rights in the directory, and by extension, over all network resources that trust Kanidm.
|
||||
|
||||
All groups that are flagged as "idm\_high\_privilege" should be audited and monitored to ensure that
|
||||
they are not altered.
|
|
@ -76,7 +76,8 @@ between them. This provides proper isolation between the instances.
|
|||
|
||||
`idm.local` - This is a bad example as `.local` is an mDNS domain name suffix which means that
|
||||
client machines if they visit another network _may_ try to contact `idm.local` believing they are on
|
||||
their usual network. If TLS verification were disabled, this would allow leaking of credentials.
|
||||
their usual network. If TLS certificate verification were disabled, this would allow leaking of
|
||||
credentials.
|
||||
|
||||
`kanidm.com` - This is bad because the use of the top level domain means that any subdomain can
|
||||
access the cookies issued by `kanidm.com`, effectively leaking them to all other hosts.
|
||||
|
|
|
@ -10,8 +10,6 @@ You can configure `kanidm` to help make commands simpler by modifying `~/.config
|
|||
|
||||
```toml
|
||||
uri = "https://idm.example.com"
|
||||
verify_ca = true|false
|
||||
verify_hostnames = true|false
|
||||
ca_path = "/path/to/ca.pem"
|
||||
```
|
||||
|
||||
|
@ -32,6 +30,8 @@ establish a session token.
|
|||
```bash
|
||||
kanidm login --name USERNAME
|
||||
kanidm login --name admin
|
||||
kanidm login -D USERNAME
|
||||
kanidm login -D admin
|
||||
```
|
||||
|
||||
Once complete, you can use `kanidm` without re-authenticating for a period of time for
|
||||
|
@ -43,8 +43,7 @@ You can list active sessions with:
|
|||
kanidm session list
|
||||
```
|
||||
|
||||
Sessions will expire after a period of time (by default 1 hour). To remove these expired sessions
|
||||
locally you can use:
|
||||
Sessions will expire after a period of time. To remove these expired sessions locally you can use:
|
||||
|
||||
```bash
|
||||
kanidm session cleanup
|
||||
|
|
|
@ -9,10 +9,10 @@ projects can come in different forms so I'll answer to a few of them:
|
|||
|
||||
## Is the library in Rust?
|
||||
|
||||
If it's not in Rust, it's not eligible for inclusion. There is a single exception today (rlm
|
||||
python) but it's very likely this will also be removed in the future. Keeping a single language
|
||||
helps with testing, but also makes the project more accessible and consistent to developers.
|
||||
Additionally, features exist in Rust that help to improve the quality of the project from development to
|
||||
If it's not in Rust, it's not eligible for inclusion. There is a single exception today (rlm python)
|
||||
but it's very likely this will also be removed in the future. Keeping a single language helps with
|
||||
testing, but also makes the project more accessible and consistent to developers. Additionally,
|
||||
features exist in Rust that help to improve the quality of the project from development to
|
||||
production.
|
||||
|
||||
## Is the project going to create a microservice like architecture?
|
||||
|
@ -93,9 +93,9 @@ correctly increment/advance between the servers. However, Mongo is not aware of
|
|||
would not be able to give the experience we desire. Mongo is a very good database, it's just not the
|
||||
right choice for Kanidm.
|
||||
|
||||
Additionally, it's worth noting that most of these other databases would violate the previous desires
|
||||
to keep the language as Rust and may require external configuration or daemons which may not be
|
||||
possible to test.
|
||||
Additionally, it's worth noting that most of these other databases would violate the previous
|
||||
desires to keep the language as Rust and may require external configuration or daemons which may not
|
||||
be possible to test.
|
||||
|
||||
## How PAM/nsswitch Work
|
||||
|
||||
|
|
|
@ -120,35 +120,9 @@ alias kanidm="docker run ..."
|
|||
|
||||
The tools are available as a cargo download if you have a rust tool chain available. To install rust
|
||||
you should follow the documentation for [rustup](https://rustup.rs/). These will be installed into
|
||||
your home directory. To update these, re-run the install command. You will likely need to install additional development libraries, specified in the [Developer Guide](DEVELOPER_README.html).
|
||||
your home directory. To update these, re-run the install command. You will likely need to install
|
||||
additional development libraries, specified in the [Developer Guide](DEVELOPER_README.html).
|
||||
|
||||
```bash
|
||||
cargo install kanidm_tools
|
||||
```
|
||||
|
||||
## Initializing the configuration
|
||||
|
||||
The client requires a configuration file to connect to the server. This should be at
|
||||
`/etc/kanidm/config` or `~/.config/kanidm`, and configures the kanidm command line tool.
|
||||
|
||||
Here is a minimal example:
|
||||
|
||||
```toml
|
||||
uri = "https://idm.example.com"
|
||||
verify_ca = true
|
||||
verify_hostnames = true
|
||||
```
|
||||
|
||||
## Checking that the tools work
|
||||
|
||||
Now you can check your instance is working. You may need to provide a CA certificate for
|
||||
verification with the -C parameter:
|
||||
|
||||
```bash
|
||||
kanidm login --name anonymous
|
||||
kanidm self whoami -H https://localhost:8443 --name anonymous
|
||||
kanidm self whoami -C ../path/to/ca.pem -H https://localhost:8443 --name anonymous
|
||||
```
|
||||
|
||||
Now you can take some time to look at what commands are available - please
|
||||
[ask for help at any time](https://github.com/kanidm/kanidm#getting-in-contact--questions).
|
||||
|
|
|
@ -38,8 +38,8 @@ systemctl status kanidm-unixd-tasks
|
|||
```
|
||||
|
||||
> **NOTE** The `kanidm_unixd_tasks` daemon is not required for PAM and nsswitch functionality. If
|
||||
> disabled, your system will function as usual. It is however strongly recommended due to the features it
|
||||
> provides supporting Kanidm's capabilities.
|
||||
> disabled, your system will function as usual. It is however strongly recommended due to the
|
||||
> features it provides supporting Kanidm's capabilities.
|
||||
|
||||
Both unixd daemons use the connection configuration from /etc/kanidm/config. This is the covered in
|
||||
[client_tools](../client_tools.md#kanidm-configuration).
|
||||
|
@ -47,7 +47,7 @@ Both unixd daemons use the connection configuration from /etc/kanidm/config. Thi
|
|||
You can also configure some unixd-specific options with the file /etc/kanidm/unixd:
|
||||
|
||||
```toml
|
||||
{{#rustdoc_include ../../examples/unixd}}
|
||||
{{#rustdoc_include ../../../examples/unixd}}
|
||||
```
|
||||
|
||||
> **NOTICE:** All users in Kanidm can change their name (and their spn) at any time. If you change
|
||||
|
|
|
@ -6,33 +6,35 @@ authentication and authorisation within a technical environment.
|
|||
The intent of the Kanidm project is to:
|
||||
|
||||
- Provide a single truth source for accounts, groups and privileges.
|
||||
- Enable integrations to systems and services so they can authenticate accounts.
|
||||
- Enable integrations to systems and services so they can trust Kanidm to authenticate accounts.
|
||||
- Make system, network, application and web authentication easy and accessible.
|
||||
- Secure and reliable by default, aiming for the highest levels of quality.
|
||||
- Secure and reliable by default, aiming for the highest levels of quality and stability.
|
||||
|
||||
## Why do I want Kanidm?
|
||||
|
||||
Whether you work in a business, a volunteer organisation, or are an enthusiast who manages their
|
||||
personal services, you need methods of authenticating and identifying to your systems, and
|
||||
subsequently, ways to determine what authorisation and privileges you have while accessing these
|
||||
systems.
|
||||
personal services, you need methods of authenticating and identifying to your systems. These systems
|
||||
also need to determine what authorisation and privileges you have while accessing them.
|
||||
|
||||
We've probably all been in workplaces where you end up with multiple accounts on various systems -
|
||||
one for a workstation, different SSH keys for different tasks, maybe some shared account passwords.
|
||||
Not only is it difficult for people to manage all these different credentials and what they have
|
||||
access to, but it also means that sometimes these credentials have more access or privilege than
|
||||
they require.
|
||||
they require. In the worst case this can lead to weak credentials (`corpname123` is a common
|
||||
example) or credentials that are disclosed via git repos.
|
||||
|
||||
Kanidm acts as a central authority of accounts in your organisation and allows each account to
|
||||
associate many devices and credentials with different privileges. An example of how this looks:
|
||||
Kanidm solves this problem by acting as a central authority of accounts in your organisation. This
|
||||
allows each account to associate many devices and strong credentials with different privileges. An
|
||||
example of how this looks:
|
||||
|
||||
<img src="images/KanidmUseCases-Light.png" alt="Kanidm Use Case Diagram" class="light-mode-only" />
|
||||
<img src="images/KanidmUseCases-Dark.png" alt="Kanidm Use Case Diagram" class="dark-mode-only" />
|
||||
|
||||
A key design goal is that you authenticate with your device in some manner, and then your device
|
||||
will continue to authenticate you in the future. Each of these different types of credentials, from
|
||||
SSH keys, application passwords, to RADIUS passwords and others, are "things your device knows".
|
||||
Each password has limited capability, and can only access that exact service or resource.
|
||||
SSH keys, application passwords, to RADIUS passwords and others, are "things your device knows" or
|
||||
"things your device has". Each credential has limited capability and scope, and can only access that
|
||||
exact service or resource.
|
||||
|
||||
This helps improve security; a compromise of the service or the network transmission does not grant
|
||||
you unlimited access to your account and all its privileges. As the credentials are specific to a
|
||||
|
@ -42,7 +44,7 @@ is compromised, only the credentials for that service need to be revoked.
|
|||
Due to this model, and the design of Kanidm to centre the device and to have more per-service
|
||||
credentials, workflows and automation are added or designed to reduce human handling.
|
||||
|
||||
## Library documentation
|
||||
## For Developers
|
||||
|
||||
Looking for the `rustdoc` documentation for the libraries themselves?
|
||||
[Click here!](https://kanidm.com/documentation/)
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
# Password Quality and Badlisting
|
||||
|
||||
Kanidm embeds a set of tools to help your users use and create strong passwords. This is important
|
||||
as not all user types will require multi-factor authentication (MFA) for their roles, but
|
||||
compromised accounts still pose a risk. There may also be deployment or other barriers to a site
|
||||
rolling out sitewide MFA.
|
||||
|
||||
## Quality Checking
|
||||
|
||||
Kanidm enforces that all passwords are checked by the library
|
||||
"[zxcvbn](https://github.com/dropbox/zxcvbn)". This has a large number of checks for password
|
||||
quality. It also provides constructive feedback to users on how to improve their passwords if they
|
||||
are rejected.
|
||||
|
||||
Some things that zxcvbn looks for is use of the account name or email in the password, common
|
||||
passwords, low entropy passwords, dates, reverse words and more.
|
||||
|
||||
This library can not be disabled - all passwords in Kanidm must pass this check.
|
||||
|
||||
## Password Badlisting
|
||||
|
||||
This is the process of configuring a list of passwords to exclude from being able to be used. This
|
||||
is especially useful if a specific business has been notified of compromised accounts, allowing you
|
||||
to maintain a list of customised excluded passwords.
|
||||
|
||||
The other value to this feature is being able to badlist common passwords that zxcvbn does not
|
||||
detect, or from other large scale password compromises.
|
||||
|
||||
By default we ship with a preconfigured badlist that is updated over time as new password breach
|
||||
lists are made available.
|
||||
|
||||
The password badlist by default is append only, meaning it can only grow, but will never remove
|
||||
passwords previously considered breached.
|
||||
|
||||
### Updating your own Badlist
|
||||
|
||||
You can display the current badlist with:
|
||||
|
||||
```bash
|
||||
kanidm system pw-badlist show
|
||||
```
|
||||
|
||||
You can update your own badlist with:
|
||||
|
||||
```bash
|
||||
kanidm system pw-badlist upload "path/to/badlist" [...]
|
||||
```
|
||||
|
||||
Multiple bad lists can be listed and uploaded at once. These are preprocessed to identify and remove
|
||||
passwords that zxcvbn and our password rules would already have eliminated. That helps to make the
|
||||
bad list more efficient to operate over at run time.
|
||||
|
||||
## Password Rotation
|
||||
|
||||
Kanidm will never support this "anti-feature". Password rotation encourages poor password hygiene
|
||||
and is not shown to prevent any attacks.
|
|
@ -55,13 +55,22 @@ docker run --rm -i -t -v kanidmd:/data \
|
|||
docker start kanidmd
|
||||
```
|
||||
|
||||
### Recover the admin password
|
||||
### Recover the Admin Role Passwords
|
||||
|
||||
The `admin` account is used to configure Kanidm itself.
|
||||
|
||||
```bash
|
||||
docker exec -i -t kanidmd \
|
||||
kanidmd recover-account admin
|
||||
```
|
||||
|
||||
The `idm_admin` account is used to manage persons and groups.
|
||||
|
||||
```
|
||||
docker exec -i -t kanidmd \
|
||||
kanidmd recover-account idm_admin
|
||||
```
|
||||
|
||||
### Setup the client configuration
|
||||
|
||||
```toml
|
||||
|
@ -74,9 +83,23 @@ verify_ca = false
|
|||
### Check you can login
|
||||
|
||||
```bash
|
||||
kanidm login
|
||||
kanidm login --name idm_admin
|
||||
```
|
||||
|
||||
### Create an account for yourself
|
||||
|
||||
```
|
||||
kanidm person create <your username> <Your Displayname>
|
||||
```
|
||||
|
||||
### Setup your account credentials
|
||||
|
||||
```
|
||||
kanidm person credential create-reset-token <your username>
|
||||
```
|
||||
|
||||
Then follow the presented steps.
|
||||
|
||||
### What next?
|
||||
|
||||
You can now follow the steps in the [administration section](administrivia.md)
|
||||
|
|
|
@ -154,4 +154,7 @@ docker run --rm -i -t -u 1000:1000 -v kanidmd:/data kanidm/server:latest /sbin/k
|
|||
|
||||
## Minimum TLS key lengths
|
||||
|
||||
We enforce a minimum RSA key length of 2048 bits, and ECDSA keys need 224 bits.
|
||||
We enforce a minimum RSA and ECDSA key sizes. If your key is insufficently large, the server will
|
||||
refuse to start and inform you of this.
|
||||
|
||||
Currently accepted key sizes are minimum 2048 bit RSA and 224 bit ECDSA.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Configuring the Server
|
||||
|
||||
In this section we will configure your server and create its container instance.
|
||||
|
||||
## Configuring server.toml
|
||||
|
||||
You need a configuration file in the volume named `server.toml`. (Within the container it should be
|
||||
|
@ -26,7 +28,7 @@ text=You MUST set the `domain` name correctly, aligned with your `origin`, else
|
|||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
|
||||
## Check the configuration is valid
|
||||
### Check the configuration is valid
|
||||
|
||||
You should test your configuration is valid before you proceed. This defaults to using
|
||||
`-c /data/server.toml`.
|
||||
|
@ -45,7 +47,7 @@ Now we can run the server so that it can accept connections. This defaults to us
|
|||
docker run -p 443:8443 -v kanidmd:/data kanidm/server:latest
|
||||
```
|
||||
|
||||
## Using the NET\_BIND\_SERVICE capability
|
||||
### Using the NET\_BIND\_SERVICE capability
|
||||
|
||||
If you plan to run without using docker port mapping or some other reverse proxy, and your
|
||||
bindaddress or ldapbindaddress port is less than `1024` you will need the `NET_BIND_SERVICE` in
|
||||
|
@ -66,14 +68,26 @@ text=However you choose to run your server, you should document and keep note of
|
|||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
|
||||
## Default Admin Account
|
||||
### Default Admin Accounts
|
||||
|
||||
Now that the server is running, you can initialise the default admin account. This command will
|
||||
generate a new random password for the admin account. You must run this command as the same user as
|
||||
the kanidmd process or as root. This defaults to using `-c /data/server.toml`.
|
||||
Now that the server is running, you can initialise the default admin accounts. There are two
|
||||
parallel admin accounts that have seperate functions. `admin` which manages Kanidm's configuration,
|
||||
and `idm_admin` which manages accounts and groups in Kanidm.
|
||||
|
||||
You should consider these as "break-glass" accounts. They exist to allow the server to be
|
||||
bootstrapped and accessed in emergencies. They are not intended for day-to-day use.
|
||||
|
||||
These commands will generate a new random password for the admin accounts. You must run the commands
|
||||
as the same user as the kanidmd process or as root. This defaults to using `-c /data/server.toml`.
|
||||
|
||||
```bash
|
||||
docker exec -i -t <container name> \
|
||||
kanidmd recover-account admin
|
||||
# new_password: "xjgG4..."
|
||||
```
|
||||
|
||||
```bash
|
||||
docker exec -i -t <container name> \
|
||||
kanidmd recover-account idm_admin
|
||||
# new_password: "9Eux1..."
|
||||
```
|
||||
|
|
|
@ -50,14 +50,15 @@ text=Downgrades are not possible. It is critical you know how to backup and rest
|
|||
|
||||
<!-- deno-fmt-ignore-end -->
|
||||
|
||||
Docker updates by deleting and recreating the instance. All that needs to be preserved is contained
|
||||
in your storage volume.
|
||||
Docker updates operate by deleting and recreating the container. All state that needs to be
|
||||
preserved is within your storage volume.
|
||||
|
||||
```bash
|
||||
docker stop <previous instance name>
|
||||
```
|
||||
|
||||
You can test that your configuration is correct, and the server should correctly start.
|
||||
You can test that your configuration is correct with the new version, and the server should
|
||||
correctly start.
|
||||
|
||||
```bash
|
||||
docker run --rm -i -t -v kanidmd:/data \
|
||||
|
@ -89,7 +90,9 @@ docker start <previous instance name>
|
|||
If you deleted the previous instance, you can recreate it from your preserved tag instead.
|
||||
|
||||
```bash
|
||||
docker run -p ports -v volumes kanidm/server:<DATE>
|
||||
docker run [Your Arguments Here] -v kanidmd:/data \
|
||||
OTHER_CUSTOM_OPTIONS \
|
||||
kanidm/server:<DATE>
|
||||
```
|
||||
|
||||
If the server from your previous version fails to start, you will need to restore from backup.
|
||||
|
|
|
@ -41,7 +41,7 @@ db_path = "/var/lib/private/kanidm/kanidm.db"
|
|||
# Minimum value is 256. If unset
|
||||
# an automatic heuristic is used to scale this.
|
||||
# You should only adjust this value if you experience
|
||||
# pressure on your system.
|
||||
# memory pressure on your system.
|
||||
# db_arc_size = 2048
|
||||
#
|
||||
# TLS chain and key in pem format. Both must be present
|
||||
|
@ -50,7 +50,8 @@ tls_key = "/var/lib/private/kanidm/key.pem"
|
|||
#
|
||||
# The log level of the server. May be one of info, debug, trace
|
||||
#
|
||||
# NOTE: this is overridden by environment variables at runtime
|
||||
# NOTE: this can be overridden by the environment variable
|
||||
# `KANIDM_LOG_LEVEL` at runtime
|
||||
# Defaults to "info"
|
||||
# log_level = "info"
|
||||
#
|
||||
|
@ -59,21 +60,22 @@ tls_key = "/var/lib/private/kanidm/key.pem"
|
|||
# such as webauthn, so it *must* match your DNS
|
||||
# hostname. It is used to create
|
||||
# security principal names such as `william@idm.example.com`
|
||||
# so that in a (future)
|
||||
# trust configuration it is possible to have unique Security
|
||||
# Principal Names (spns) throughout the topology.
|
||||
# so that in a (future) trust configuration it is possible
|
||||
# to have unique Security Principal Names (spns) throughout
|
||||
# the topology.
|
||||
#
|
||||
# ⚠️ WARNING ⚠️
|
||||
#
|
||||
# Changing this value WILL break many types of registered
|
||||
# credentials for accounts
|
||||
# including but not limited to webauthn, oauth tokens, and more.
|
||||
# credentials for accounts including but not limited to
|
||||
# webauthn, oauth tokens, and more.
|
||||
# If you change this value you *must* run
|
||||
# `kanidmd domain_name_change` immediately after.
|
||||
domain = "idm.example.com"
|
||||
#
|
||||
# The origin for webauthn. This is the url to the server,
|
||||
# with the port included if
|
||||
# it is non-standard (any port except 443). This must match
|
||||
# or be a descendent of the
|
||||
# with the port included if it is non-standard (any port
|
||||
# except 443). This must match or be a descendent of the
|
||||
# domain name you configure above. If these two items are
|
||||
# not consistent, the server WILL refuse to start!
|
||||
# origin = "https://idm.example.com"
|
||||
|
|
|
@ -41,7 +41,7 @@ db_path = "/data/kanidm.db"
|
|||
# Minimum value is 256. If unset
|
||||
# an automatic heuristic is used to scale this.
|
||||
# You should only adjust this value if you experience
|
||||
# pressure on your system.
|
||||
# memory pressure on your system.
|
||||
# db_arc_size = 2048
|
||||
#
|
||||
# TLS chain and key in pem format. Both must be present
|
||||
|
@ -50,7 +50,8 @@ tls_key = "/data/key.pem"
|
|||
#
|
||||
# The log level of the server. May be one of info, debug, trace
|
||||
#
|
||||
# NOTE: this is overridden by environment variables at runtime
|
||||
# NOTE: this can be overridden by the environment variable
|
||||
# `KANIDM_LOG_LEVEL` at runtime
|
||||
# Defaults to "info"
|
||||
# log_level = "info"
|
||||
#
|
||||
|
@ -59,21 +60,22 @@ tls_key = "/data/key.pem"
|
|||
# such as webauthn, so it *must* match your DNS
|
||||
# hostname. It is used to create
|
||||
# security principal names such as `william@idm.example.com`
|
||||
# so that in a (future)
|
||||
# trust configuration it is possible to have unique Security
|
||||
# Principal Names (spns) throughout the topology.
|
||||
# so that in a (future) trust configuration it is possible
|
||||
# to have unique Security Principal Names (spns) throughout
|
||||
# the topology.
|
||||
#
|
||||
# ⚠️ WARNING ⚠️
|
||||
#
|
||||
# Changing this value WILL break many types of registered
|
||||
# credentials for accounts
|
||||
# including but not limited to webauthn, oauth tokens, and more.
|
||||
# credentials for accounts including but not limited to
|
||||
# webauthn, oauth tokens, and more.
|
||||
# If you change this value you *must* run
|
||||
# `kanidmd domain_name_change` immediately after.
|
||||
domain = "idm.example.com"
|
||||
#
|
||||
# The origin for webauthn. This is the url to the server,
|
||||
# with the port included if
|
||||
# it is non-standard (any port except 443). This must match
|
||||
# or be a descendent of the
|
||||
# with the port included if it is non-standard (any port
|
||||
# except 443). This must match or be a descendent of the
|
||||
# domain name you configure above. If these two items are
|
||||
# not consistent, the server WILL refuse to start!
|
||||
# origin = "https://idm.example.com"
|
||||
|
|
|
@ -26,7 +26,8 @@ use std::time::Duration;
|
|||
|
||||
use kanidm_proto::constants::uri::V1_AUTH_VALID;
|
||||
use kanidm_proto::constants::{
|
||||
APPLICATION_JSON, ATTR_NAME, CLIENT_TOKEN_CACHE, KOPID, KSESSIONID, KVERSION,
|
||||
APPLICATION_JSON, ATTR_ENTRY_MANAGED_BY, ATTR_NAME, CLIENT_TOKEN_CACHE, KOPID, KSESSIONID,
|
||||
KVERSION,
|
||||
};
|
||||
use kanidm_proto::v1::*;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
|
@ -1551,16 +1552,38 @@ impl KanidmClient {
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn idm_group_create(&self, name: &str) -> Result<(), ClientError> {
|
||||
pub async fn idm_group_create(
|
||||
&self,
|
||||
name: &str,
|
||||
entry_managed_by: Option<&str>,
|
||||
) -> Result<(), ClientError> {
|
||||
let mut new_group = Entry {
|
||||
attrs: BTreeMap::new(),
|
||||
};
|
||||
new_group
|
||||
.attrs
|
||||
.insert(ATTR_NAME.to_string(), vec![name.to_string()]);
|
||||
|
||||
if let Some(entry_manager) = entry_managed_by {
|
||||
new_group.attrs.insert(
|
||||
ATTR_ENTRY_MANAGED_BY.to_string(),
|
||||
vec![entry_manager.to_string()],
|
||||
);
|
||||
}
|
||||
|
||||
self.perform_post_request("/v1/group", new_group).await
|
||||
}
|
||||
|
||||
pub async fn idm_group_set_entry_managed_by(
|
||||
&self,
|
||||
id: &str,
|
||||
entry_manager: &str,
|
||||
) -> Result<(), ClientError> {
|
||||
let data = vec![entry_manager];
|
||||
self.perform_put_request(&format!("/v1/group/{}/_attr/entry_managed_by", id), data)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn idm_group_set_members(
|
||||
&self,
|
||||
id: &str,
|
||||
|
|
|
@ -119,18 +119,6 @@ impl KanidmClient {
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn idm_person_account_primary_credential_import_password(
|
||||
&self,
|
||||
id: &str,
|
||||
pw: &str,
|
||||
) -> Result<(), ClientError> {
|
||||
self.perform_put_request(
|
||||
format!("/v1/person/{}/_attr/password_import", id).as_str(),
|
||||
vec![pw.to_string()],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn idm_person_account_get_credential_status(
|
||||
&self,
|
||||
id: &str,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use kanidm_proto::constants::{ATTR_DISPLAYNAME, ATTR_MAIL, ATTR_NAME};
|
||||
use kanidm_proto::constants::{ATTR_DISPLAYNAME, ATTR_ENTRY_MANAGED_BY, ATTR_MAIL, ATTR_NAME};
|
||||
use kanidm_proto::v1::{AccountUnixExtend, ApiToken, ApiTokenGenerate, CredentialStatus, Entry};
|
||||
use time::OffsetDateTime;
|
||||
use uuid::Uuid;
|
||||
|
@ -22,6 +22,7 @@ impl KanidmClient {
|
|||
&self,
|
||||
name: &str,
|
||||
displayname: &str,
|
||||
entry_managed_by: &str,
|
||||
) -> Result<(), ClientError> {
|
||||
let mut new_acct = Entry {
|
||||
attrs: BTreeMap::new(),
|
||||
|
@ -32,6 +33,11 @@ impl KanidmClient {
|
|||
new_acct
|
||||
.attrs
|
||||
.insert(ATTR_DISPLAYNAME.to_string(), vec![displayname.to_string()]);
|
||||
new_acct.attrs.insert(
|
||||
ATTR_ENTRY_MANAGED_BY.to_string(),
|
||||
vec![entry_managed_by.to_string()],
|
||||
);
|
||||
|
||||
self.perform_post_request("/v1/service_account", new_acct)
|
||||
.await
|
||||
}
|
||||
|
@ -46,6 +52,7 @@ impl KanidmClient {
|
|||
id: &str,
|
||||
newname: Option<&str>,
|
||||
displayname: Option<&str>,
|
||||
entry_managed_by: Option<&str>,
|
||||
mail: Option<&[String]>,
|
||||
) -> Result<(), ClientError> {
|
||||
let mut update_entry = Entry {
|
||||
|
@ -57,12 +64,21 @@ impl KanidmClient {
|
|||
.attrs
|
||||
.insert(ATTR_NAME.to_string(), vec![newname.to_string()]);
|
||||
}
|
||||
|
||||
if let Some(newdisplayname) = displayname {
|
||||
update_entry.attrs.insert(
|
||||
ATTR_DISPLAYNAME.to_string(),
|
||||
vec![newdisplayname.to_string()],
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(entry_managed_by) = entry_managed_by {
|
||||
update_entry.attrs.insert(
|
||||
ATTR_ENTRY_MANAGED_BY.to_string(),
|
||||
vec![entry_managed_by.to_string()],
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(mail) = mail {
|
||||
update_entry
|
||||
.attrs
|
||||
|
|
|
@ -34,7 +34,6 @@ CROSS_CONFIG=platform/crossbuild/ubuntu-22.04/Cross.toml \
|
|||
--bin kanidm_ssh_authorizedkeys \
|
||||
--bin kanidm-unix \
|
||||
--release
|
||||
|
||||
```
|
||||
|
||||
Things will end up in `./target/aarch64-unknown-linux-gnu/release/`
|
||||
|
|
|
@ -865,6 +865,7 @@ pub async fn create_server_core(
|
|||
match &config.integration_test_config {
|
||||
Some(itc) => {
|
||||
let mut idms_prox_write = idms.proxy_write(duration_from_epoch_now()).await;
|
||||
// We need to get the admin pw.
|
||||
match idms_prox_write.recover_account("admin", Some(&itc.admin_password)) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
|
@ -875,6 +876,22 @@ pub async fn create_server_core(
|
|||
return Err(());
|
||||
}
|
||||
};
|
||||
// Add admin to idm_admins to allow tests more flexibility wrt to permissions.
|
||||
// This way our default access controls can be stricter to prevent lateral
|
||||
// movement.
|
||||
match idms_prox_write.qs_write.internal_modify_uuid(
|
||||
UUID_IDM_ADMINS,
|
||||
&ModifyList::new_append(Attribute::Member, Value::Refer(UUID_ADMIN)),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
error!(
|
||||
"Unable to configure INTEGRATION TEST admin as member of idm_admins -> {:?}",
|
||||
e
|
||||
);
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
match idms_prox_write.commit() {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -738,7 +738,7 @@ lazy_static! {
|
|||
Attribute::Description,
|
||||
Value::new_utf8s("System (local) info and metadata object.")
|
||||
),
|
||||
(Attribute::Version, Value::Uint32(16))
|
||||
(Attribute::Version, Value::Uint32(17))
|
||||
);
|
||||
|
||||
pub static ref E_DOMAIN_INFO_V1: EntryInitNew = entry_init!(
|
||||
|
|
|
@ -10,6 +10,7 @@ pub struct BuiltinGroup {
|
|||
pub description: &'static str,
|
||||
pub uuid: uuid::Uuid,
|
||||
pub members: Vec<uuid::Uuid>,
|
||||
pub entry_managed_by: Option<uuid::Uuid>,
|
||||
pub dyngroup: bool,
|
||||
pub dyngroup_filter: Option<Filter>,
|
||||
pub extra_attributes: Vec<(Attribute, Value)>,
|
||||
|
@ -47,6 +48,11 @@ impl TryFrom<BuiltinGroup> for EntryInitNew {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(entry_manager) = val.entry_managed_by {
|
||||
entry.add_ava(Attribute::EntryManagedBy, Value::Refer(entry_manager));
|
||||
}
|
||||
|
||||
entry.add_ava(Attribute::Uuid, Value::Uuid(val.uuid));
|
||||
entry.set_ava(
|
||||
Attribute::Member,
|
||||
|
@ -65,201 +71,133 @@ impl TryFrom<BuiltinGroup> for EntryInitNew {
|
|||
}
|
||||
|
||||
lazy_static! {
|
||||
|
||||
|
||||
/// Builtin IDM Administrators Group.
|
||||
pub static ref BUILTIN_GROUP_IDM_ADMINS_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_admins",
|
||||
description: "Builtin IDM Administrators Group.",
|
||||
uuid: UUID_IDM_ADMINS,
|
||||
members: vec![UUID_IDM_ADMIN],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// There are our built in "roles". They encapsulate some higher level collections
|
||||
// of roles. The intent is to allow a pretty generic and correct by default set
|
||||
// of these use cases.
|
||||
pub static ref BUILTIN_GROUP_SYSTEM_ADMINS_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "system_admins",
|
||||
description: "Builtin System Administrators Group.",
|
||||
uuid: UUID_SYSTEM_ADMINS,
|
||||
members: vec![BUILTIN_ACCOUNT_ADMIN.uuid],
|
||||
entry_managed_by: Some(UUID_SYSTEM_ADMINS),
|
||||
members: vec![UUID_ADMIN],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref BUILTIN_GROUP_IDM_ADMINS_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_admins",
|
||||
description: "Builtin IDM Administrators Group.",
|
||||
uuid: UUID_IDM_ADMINS,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![UUID_IDM_ADMIN],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref BUILTIN_GROUP_SERVICE_DESK: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_service_desk",
|
||||
description: "Builtin Service Desk Group.",
|
||||
uuid: UUID_IDM_SERVICE_DESK,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// These are the "finer" roles. They encapsulate different concepts in the system.
|
||||
// The next section is the "system style" roles. These adjust the operation of
|
||||
// kanidm and relate to it's internals and how it functions.
|
||||
pub static ref BUILTIN_GROUP_RECYCLE_BIN_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_recycle_bin_admins",
|
||||
description: "Builtin Recycle Bin Administrators Group.",
|
||||
uuid: UUID_IDM_RECYCLE_BIN_ADMINS,
|
||||
entry_managed_by: Some(UUID_SYSTEM_ADMINS),
|
||||
members: vec![UUID_SYSTEM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting local domain administration rights and trust administration rights
|
||||
pub static ref BUILTIN_GROUP_DOMAIN_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "domain_admins",
|
||||
description: "Builtin IDM Group for granting local domain administration rights and trust administration rights.",
|
||||
uuid: UUID_DOMAIN_ADMINS,
|
||||
entry_managed_by: Some(UUID_SYSTEM_ADMINS),
|
||||
members: vec![UUID_SYSTEM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref BUILTIN_GROUP_SCHEMA_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_schema_admins",
|
||||
description: "Builtin Schema Administration Group.",
|
||||
uuid: UUID_IDM_SCHEMA_ADMINS,
|
||||
entry_managed_by: Some(UUID_SYSTEM_ADMINS),
|
||||
members: vec![UUID_SYSTEM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref BUILTIN_GROUP_ACCESS_CONTROL_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_access_control_admins",
|
||||
description: "Builtin Access Control Administration Group.",
|
||||
entry_managed_by: Some(UUID_SYSTEM_ADMINS),
|
||||
uuid: UUID_IDM_ACCESS_CONTROL_ADMINS,
|
||||
members: vec![UUID_SYSTEM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// These are the IDM roles. They concern application integration, user permissions
|
||||
// and credential security management.
|
||||
|
||||
/// Builtin IDM Group for managing persons and their account details
|
||||
pub static ref BUILTIN_GROUP_PEOPLE_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_admins",
|
||||
description: "Builtin People Administration Group.",
|
||||
uuid: UUID_IDM_PEOPLE_ADMINS,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![UUID_IDM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref BUILTIN_GROUP_PEOPLE_ON_BOARDING: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_on_boarding",
|
||||
description: "Builtin People On Boarding Group.",
|
||||
uuid: UUID_IDM_PEOPLE_ON_BOARDING,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// * People read managers
|
||||
/// Builtin IDM Group for granting elevated people (personal data) read permissions.
|
||||
pub static ref IDM_PEOPLE_READ_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_read_priv",
|
||||
pub static ref BUILTIN_GROUP_PEOPLE_PII_READ: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_pii_read",
|
||||
description: "Builtin IDM Group for granting elevated people (personal data) read permissions.",
|
||||
uuid: UUID_IDM_PEOPLE_READ_PRIV,
|
||||
members: vec![UUID_IDM_PEOPLE_WRITE_PRIV],
|
||||
..Default::default()
|
||||
};
|
||||
pub static ref IDM_PEOPLE_WRITE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_write_priv",
|
||||
description: "Builtin IDM Group for granting elevated people (personal data) write permissions.",
|
||||
uuid: UUID_IDM_PEOPLE_WRITE_PRIV,
|
||||
members: vec![UUID_IDM_PEOPLE_MANAGE_PRIV,UUID_IDM_PEOPLE_EXTEND_PRIV],
|
||||
uuid: UUID_IDM_PEOPLE_PII_READ,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// * People write managers
|
||||
/// Builtin IDM Group for granting elevated people (personal data) write and lifecycle management permissions.
|
||||
pub static ref IDM_PEOPLE_MANAGE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_manage_priv",
|
||||
description: "Builtin IDM Group for granting elevated people (personal data) write and lifecycle management permissions.",
|
||||
uuid: UUID_IDM_PEOPLE_MANAGE_PRIV,
|
||||
pub static ref BUILTIN_GROUP_SERVICE_ACCOUNT_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_service_account_admins",
|
||||
description: "Builtin Service Account Administration Group.",
|
||||
uuid: UUID_IDM_SERVICE_ACCOUNT_ADMINS,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![UUID_IDM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for importing passwords to person accounts - intended for service account membership only.
|
||||
pub static ref IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_account_password_import_priv",
|
||||
description: "Builtin IDM Group for importing passwords to person accounts - intended for service account membership only.",
|
||||
uuid: UUID_IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV,
|
||||
/// Builtin IDM Group for managing oauth2 resource server integrations to this authentication domain.
|
||||
pub static ref BUILTIN_GROUP_OAUTH2_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_oauth2_admins",
|
||||
description: "Builtin Oauth2 Integration Administration Group.",
|
||||
uuid: UUID_IDM_OAUTH2_ADMINS,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![UUID_IDM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for allowing the ability to extend accounts to have the "person" flag set.
|
||||
pub static ref IDM_PEOPLE_EXTEND_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_extend_priv",
|
||||
description: "Builtin System Administrators Group.",
|
||||
uuid: UUID_IDM_PEOPLE_EXTEND_PRIV,
|
||||
members: vec![UUID_SYSTEM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
/// Self-write of mail
|
||||
pub static ref IDM_PEOPLE_SELF_WRITE_MAIL_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_self_write_mail_priv",
|
||||
description: "Builtin IDM Group for people accounts to update their own mail.",
|
||||
uuid: UUID_IDM_PEOPLE_SELF_WRITE_MAIL_PRIV,
|
||||
members: Vec::new(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting elevated high privilege people (personal data) read permissions.
|
||||
pub static ref IDM_HP_PEOPLE_READ_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_people_read_priv",
|
||||
description: "Builtin IDM Group for granting elevated high privilege people (personal data) read permissions.",
|
||||
uuid: UUID_IDM_HP_PEOPLE_READ_PRIV,
|
||||
members: vec![UUID_IDM_HP_PEOPLE_WRITE_PRIV],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting elevated high privilege people (personal data) write permissions.
|
||||
pub static ref IDM_HP_PEOPLE_WRITE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_people_write_priv",
|
||||
description: "Builtin IDM Group for granting elevated high privilege people (personal data) write permissions.",
|
||||
uuid: UUID_IDM_HP_PEOPLE_WRITE_PRIV,
|
||||
members: vec![UUID_IDM_HP_PEOPLE_EXTEND_PRIV],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for extending high privilege accounts to be people.
|
||||
pub static ref IDM_HP_PEOPLE_EXTEND_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_people_extend_priv",
|
||||
description: "Builtin IDM Group for extending high privilege accounts to be people.",
|
||||
uuid: UUID_IDM_HP_PEOPLE_EXTEND_PRIV,
|
||||
members: vec![UUID_SYSTEM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// * group write manager (no read, everyone has read via the anon, etc)
|
||||
|
||||
/// Builtin IDM Group for granting elevated group write and lifecycle permissions.
|
||||
pub static ref IDM_GROUP_MANAGE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_group_manage_priv",
|
||||
description: "Builtin IDM Group for granting elevated group write and lifecycle permissions.",
|
||||
uuid: UUID_IDM_GROUP_MANAGE_PRIV,
|
||||
members: vec![
|
||||
BUILTIN_GROUP_IDM_ADMINS_V1.uuid,
|
||||
BUILTIN_GROUP_SYSTEM_ADMINS_V1.uuid,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting elevated group write and lifecycle permissions.
|
||||
pub static ref IDM_GROUP_WRITE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_group_write_priv",
|
||||
description: "Builtin IDM Group for granting elevated group write permissions.",
|
||||
uuid: UUID_IDM_GROUP_WRITE_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_GROUP_MANAGE_PRIV
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting unix group extension permissions.
|
||||
pub static ref IDM_GROUP_UNIX_EXTEND_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_group_unix_extend_priv",
|
||||
description: "Builtin IDM Group for granting UNIX group extension permissions.",
|
||||
uuid: UUID_IDM_GROUP_UNIX_EXTEND_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_ADMINS
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Account read manager
|
||||
pub static ref IDM_ACCOUNT_READ_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_account_read_priv",
|
||||
description: "Builtin IDM Group for granting elevated account read permissions.",
|
||||
uuid: UUID_IDM_ACCOUNT_READ_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_ACCOUNT_WRITE_PRIV,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref IDM_ACCOUNT_MANAGE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_account_manage_priv",
|
||||
description: "Builtin IDM Group for granting elevated account write and lifecycle permissions.",
|
||||
uuid: UUID_IDM_ACCOUNT_MANAGE_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref IDM_ACCOUNT_WRITE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_account_write_priv",
|
||||
description: "Builtin IDM Group for granting elevated account write permissions.",
|
||||
uuid: UUID_IDM_ACCOUNT_WRITE_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_ACCOUNT_MANAGE_PRIV,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref IDM_ACCOUNT_UNIX_EXTEND_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_account_unix_extend_priv",
|
||||
description: "Builtin IDM Group for granting account unix extend permissions.",
|
||||
uuid: UUID_IDM_ACCOUNT_UNIX_EXTEND_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for RADIUS secret write for all non-hp accounts.
|
||||
pub static ref IDM_RADIUS_SECRET_WRITE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_radius_secret_write_priv",
|
||||
description: "Builtin IDM Group for RADIUS secret write for all non-hp accounts.",
|
||||
uuid: UUID_IDM_RADIUS_SECRET_WRITE_PRIV_V1,
|
||||
members: vec![
|
||||
UUID_IDM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for RADIUS secret reading for all non-hp accounts.
|
||||
pub static ref IDM_RADIUS_SECRET_READ_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_radius_secret_read_priv",
|
||||
description: "Builtin IDM Group for RADIUS secret reading for all non-hp accounts.",
|
||||
uuid: UUID_IDM_RADIUS_SECRET_READ_PRIV_V1,
|
||||
members: vec![
|
||||
UUID_IDM_RADIUS_SECRET_WRITE_PRIV_V1,
|
||||
],
|
||||
pub static ref BUILTIN_GROUP_RADIUS_SERVICE_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_radius_service_admins",
|
||||
description: "Builtin Radius Administration Group.",
|
||||
uuid: UUID_IDM_RADIUS_ADMINS,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![UUID_IDM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -268,158 +206,53 @@ lazy_static! {
|
|||
name: "idm_radius_servers",
|
||||
description: "Builtin IDM Group for RADIUS server access delegation.",
|
||||
uuid: UUID_IDM_RADIUS_SERVERS,
|
||||
entry_managed_by: Some(UUID_IDM_RADIUS_ADMINS),
|
||||
members: vec![
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// High privilege account read manager
|
||||
pub static ref IDM_HP_ACCOUNT_READ_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_account_read_priv",
|
||||
description: "Builtin IDM Group for granting elevated account read permissions over high privilege accounts.",
|
||||
uuid: UUID_IDM_HP_ACCOUNT_READ_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_HP_ACCOUNT_WRITE_PRIV
|
||||
],
|
||||
pub static ref BUILTIN_GROUP_ACCOUNT_POLICY_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_account_policy_admins",
|
||||
description: "Builtin Account Policy Administration Group.",
|
||||
uuid: UUID_IDM_ACCOUNT_POLICY_ADMINS,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![UUID_IDM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting elevated account write permissions over high privilege accounts.
|
||||
pub static ref IDM_HP_ACCOUNT_MANAGE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_account_manage_priv",
|
||||
description: "Builtin IDM Group for granting elevated account write and lifecycle permissions over high privilege accounts.",
|
||||
uuid: UUID_IDM_HP_ACCOUNT_MANAGE_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
/// Builtin IDM Group for granting elevated account write permissions over high privilege accounts.
|
||||
pub static ref IDM_HP_ACCOUNT_WRITE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_account_write_priv",
|
||||
description: "Builtin IDM Group for granting elevated account write permissions over high privilege accounts.",
|
||||
uuid: UUID_IDM_HP_ACCOUNT_WRITE_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_HP_ACCOUNT_MANAGE_PRIV,
|
||||
],
|
||||
/// Builtin IDM Group for managing posix/unix attributes on groups and users.
|
||||
pub static ref BUILTIN_GROUP_UNIX_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_unix_admins",
|
||||
description: "Builtin Unix Administration Group.",
|
||||
uuid: UUID_IDM_UNIX_ADMINS,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![UUID_IDM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting account unix extend permissions for high privilege accounts.
|
||||
pub static ref IDM_HP_ACCOUNT_UNIX_EXTEND_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_account_unix_extend_priv",
|
||||
description: "Builtin IDM Group for granting account UNIX extend permissions for high privilege accounts.",
|
||||
uuid: UUID_IDM_HP_ACCOUNT_UNIX_EXTEND_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
/// Builtin IDM Group for granting elevated group write and lifecycle permissions.
|
||||
pub static ref IDM_GROUP_ADMINS_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_group_admins",
|
||||
description: "Builtin IDM Group for granting elevated group write and lifecycle permissions.",
|
||||
uuid: UUID_IDM_GROUP_ADMINS,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
members: vec![UUID_IDM_ADMINS],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// * Schema write manager
|
||||
pub static ref IDM_SCHEMA_MANAGE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_schema_manage_priv",
|
||||
description: "Builtin IDM Group for granting elevated schema write and management permissions.",
|
||||
uuid: UUID_IDM_SCHEMA_MANAGE_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
/// Self-write of mail
|
||||
pub static ref IDM_PEOPLE_SELF_WRITE_MAIL_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_people_self_write_mail",
|
||||
description: "Builtin IDM Group for people accounts to update their own mail.",
|
||||
uuid: UUID_IDM_PEOPLE_SELF_WRITE_MAIL,
|
||||
members: Vec::new(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// ACP read/write manager
|
||||
pub static ref IDM_ACP_MANAGE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_acp_manage_priv",
|
||||
description: "Builtin IDM Group for granting control over all access control profile modifications.",
|
||||
uuid: UUID_IDM_ACP_MANAGE_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting elevated group write and lifecycle privileges for high privilege groups.
|
||||
pub static ref IDM_HP_GROUP_MANAGE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_group_manage_priv",
|
||||
description: "Builtin IDM Group for granting elevated group write and lifecycle privileges for high privilege groups.",
|
||||
uuid: UUID_IDM_HP_GROUP_MANAGE_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting elevated group write privileges for high privilege groups.
|
||||
pub static ref IDM_HP_GROUP_WRITE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_group_write_priv",
|
||||
description: "Builtin IDM Group for granting elevated group write privileges for high privilege groups.",
|
||||
uuid: UUID_IDM_HP_GROUP_WRITE_PRIV,
|
||||
members: vec![
|
||||
UUID_IDM_HP_GROUP_MANAGE_PRIV,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// at some point vs code just gives up on syntax highlighting inside lazy_static...
|
||||
lazy_static! {
|
||||
|
||||
/// Builtin IDM Group for granting unix group extension permissions for high privilege groups.
|
||||
pub static ref IDM_HP_GROUP_UNIX_EXTEND_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_group_unix_extend_priv",
|
||||
description: "Builtin IDM Group for granting unix group extension permissions for high privilege groups.",
|
||||
uuid: UUID_IDM_HP_GROUP_UNIX_EXTEND_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for granting local domain administration rights and trust administration rights
|
||||
pub static ref DOMAIN_ADMINS: BuiltinGroup = BuiltinGroup {
|
||||
name: "domain_admins",
|
||||
description: "Builtin IDM Group for granting local domain administration rights and trust administration rights.",
|
||||
uuid: UUID_DOMAIN_ADMINS,
|
||||
members: vec![
|
||||
UUID_ADMIN,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
/// Builtin IDM Group for managing oauth2 resource server integrations to this authentication domain.
|
||||
pub static ref IDM_HP_OAUTH2_MANAGE_PRIV_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_oauth2_manage_priv",
|
||||
description: "Builtin IDM Group for managing oauth2 resource server integrations to this authentication domain.",
|
||||
uuid: UUID_IDM_HP_OAUTH2_MANAGE_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
/// Builtin IDM Group for allowing migrations of service accounts into persons
|
||||
pub static ref IDM_HP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_PRIV: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_service_account_into_person_migrate_priv",
|
||||
description:"Builtin IDM Group for allowing migrations of service accounts into persons",
|
||||
uuid: UUID_IDM_HP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
pub static ref IDM_HP_SYNC_ACCOUNT_MANAGE_PRIV: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_hp_sync_account_manage_priv",
|
||||
description: "Builtin IDM Group for managing synchronisation from external identity sources",
|
||||
uuid: UUID_IDM_HP_SYNC_ACCOUNT_MANAGE_PRIV,
|
||||
members: vec![
|
||||
UUID_SYSTEM_ADMINS,
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref IDM_ALL_PERSONS: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_all_persons",
|
||||
description: "Builtin IDM dynamic group containing all persons.",
|
||||
|
@ -438,6 +271,7 @@ lazy_static! {
|
|||
// Enforce this is a system protected object
|
||||
(Attribute::Class, EntryClass::System.to_value()),
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
pub static ref IDM_ALL_ACCOUNTS: BuiltinGroup = BuiltinGroup {
|
||||
|
@ -455,6 +289,7 @@ lazy_static! {
|
|||
// Enforce this is a system protected object
|
||||
(Attribute::Class, EntryClass::System.to_value()),
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
|
@ -462,6 +297,7 @@ lazy_static! {
|
|||
name: "idm_ui_enable_experimental_features",
|
||||
description: "Members of this group will have access to experimental web UI features.",
|
||||
uuid: UUID_IDM_UI_ENABLE_EXPERIMENTAL_FEATURES,
|
||||
entry_managed_by: Some(UUID_IDM_ADMINS),
|
||||
extra_attributes: vec![
|
||||
(Attribute::GrantUiHint, Value::UiHint(UiHint::ExperimentalFeatures))
|
||||
],
|
||||
|
@ -469,10 +305,11 @@ lazy_static! {
|
|||
};
|
||||
|
||||
/// Members of this group will have access to read the mail attribute of all persons and service accounts.
|
||||
pub static ref IDM_ACCOUNT_MAIL_READ_PRIV: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_account_mail_read_priv",
|
||||
pub static ref IDM_ACCOUNT_MAIL_READ: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_account_mail_read",
|
||||
description: "Members of this group will have access to read the mail attribute of all persons and service accounts.",
|
||||
uuid: UUID_IDM_ACCOUNT_MAIL_READ_PRIV,
|
||||
entry_managed_by: Some(UUID_IDM_ACCESS_CONTROL_ADMINS),
|
||||
uuid: UUID_IDM_ACCOUNT_MAIL_READ,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -480,41 +317,29 @@ lazy_static! {
|
|||
pub static ref IDM_HIGH_PRIVILEGE_V1: BuiltinGroup = BuiltinGroup {
|
||||
name: "idm_high_privilege",
|
||||
uuid: UUID_IDM_HIGH_PRIVILEGE,
|
||||
entry_managed_by: Some(UUID_IDM_ACCESS_CONTROL_ADMINS),
|
||||
description: "Builtin IDM provided groups with high levels of access that should be audited and limited in modification.",
|
||||
members: vec![
|
||||
UUID_IDM_ADMINS,
|
||||
UUID_IDM_PEOPLE_READ_PRIV,
|
||||
UUID_IDM_PEOPLE_WRITE_PRIV,
|
||||
UUID_IDM_GROUP_WRITE_PRIV,
|
||||
UUID_IDM_ACCOUNT_READ_PRIV,
|
||||
UUID_IDM_ACCOUNT_WRITE_PRIV,
|
||||
UUID_IDM_RADIUS_SERVERS,
|
||||
UUID_IDM_HP_ACCOUNT_READ_PRIV,
|
||||
UUID_IDM_HP_ACCOUNT_WRITE_PRIV,
|
||||
UUID_IDM_SCHEMA_MANAGE_PRIV,
|
||||
UUID_IDM_ACP_MANAGE_PRIV,
|
||||
UUID_IDM_HP_GROUP_WRITE_PRIV,
|
||||
UUID_IDM_PEOPLE_MANAGE_PRIV,
|
||||
UUID_IDM_ACCOUNT_MANAGE_PRIV,
|
||||
UUID_IDM_GROUP_MANAGE_PRIV,
|
||||
UUID_IDM_HP_ACCOUNT_MANAGE_PRIV,
|
||||
UUID_IDM_HP_GROUP_MANAGE_PRIV,
|
||||
UUID_SYSTEM_ADMINS,
|
||||
UUID_IDM_ADMINS,
|
||||
UUID_DOMAIN_ADMINS,
|
||||
UUID_IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV,
|
||||
UUID_IDM_PEOPLE_EXTEND_PRIV,
|
||||
UUID_IDM_HP_ACCOUNT_UNIX_EXTEND_PRIV,
|
||||
UUID_IDM_HP_GROUP_UNIX_EXTEND_PRIV,
|
||||
UUID_IDM_HP_OAUTH2_MANAGE_PRIV,
|
||||
UUID_IDM_RADIUS_SECRET_WRITE_PRIV_V1,
|
||||
UUID_IDM_RADIUS_SECRET_READ_PRIV_V1,
|
||||
UUID_IDM_HP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_PRIV,
|
||||
UUID_IDM_HP_SYNC_ACCOUNT_MANAGE_PRIV,
|
||||
UUID_IDM_SERVICE_DESK,
|
||||
UUID_IDM_RECYCLE_BIN_ADMINS,
|
||||
UUID_IDM_SCHEMA_ADMINS,
|
||||
UUID_IDM_ACCESS_CONTROL_ADMINS,
|
||||
UUID_IDM_OAUTH2_ADMINS,
|
||||
UUID_IDM_RADIUS_ADMINS,
|
||||
UUID_IDM_ACCOUNT_POLICY_ADMINS,
|
||||
UUID_IDM_RADIUS_SERVERS,
|
||||
UUID_IDM_GROUP_ADMINS,
|
||||
UUID_IDM_UNIX_ADMINS,
|
||||
UUID_IDM_PEOPLE_PII_READ,
|
||||
UUID_IDM_PEOPLE_ADMINS,
|
||||
UUID_IDM_PEOPLE_ON_BOARDING,
|
||||
UUID_IDM_SERVICE_ACCOUNT_ADMINS,
|
||||
UUID_IDM_HIGH_PRIVILEGE,
|
||||
],
|
||||
dyngroup: false,
|
||||
dyngroup_filter: None,
|
||||
extra_attributes: Vec::new(),
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -522,46 +347,30 @@ lazy_static! {
|
|||
pub fn idm_builtin_non_admin_groups() -> Vec<&'static BuiltinGroup> {
|
||||
// Create any system default schema entries.
|
||||
vec![
|
||||
&BUILTIN_GROUP_DOMAIN_ADMINS,
|
||||
&BUILTIN_GROUP_SCHEMA_ADMINS,
|
||||
&BUILTIN_GROUP_ACCESS_CONTROL_ADMINS,
|
||||
&BUILTIN_GROUP_UNIX_ADMINS,
|
||||
&BUILTIN_GROUP_RECYCLE_BIN_ADMINS,
|
||||
&BUILTIN_GROUP_SERVICE_DESK,
|
||||
&BUILTIN_GROUP_OAUTH2_ADMINS,
|
||||
&BUILTIN_GROUP_RADIUS_SERVICE_ADMINS,
|
||||
&BUILTIN_GROUP_ACCOUNT_POLICY_ADMINS,
|
||||
&BUILTIN_GROUP_PEOPLE_ADMINS,
|
||||
&BUILTIN_GROUP_PEOPLE_PII_READ,
|
||||
&BUILTIN_GROUP_PEOPLE_ON_BOARDING,
|
||||
&BUILTIN_GROUP_SERVICE_ACCOUNT_ADMINS,
|
||||
&IDM_GROUP_ADMINS_V1,
|
||||
&IDM_ALL_PERSONS,
|
||||
&IDM_ALL_ACCOUNTS,
|
||||
&IDM_PEOPLE_MANAGE_PRIV_V1,
|
||||
&IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1,
|
||||
&IDM_PEOPLE_EXTEND_PRIV_V1,
|
||||
&IDM_PEOPLE_SELF_WRITE_MAIL_PRIV_V1,
|
||||
&IDM_PEOPLE_WRITE_PRIV_V1,
|
||||
&IDM_PEOPLE_READ_PRIV_V1,
|
||||
&IDM_HP_PEOPLE_EXTEND_PRIV_V1,
|
||||
&IDM_HP_PEOPLE_WRITE_PRIV_V1,
|
||||
&IDM_HP_PEOPLE_READ_PRIV_V1,
|
||||
&IDM_GROUP_MANAGE_PRIV_V1,
|
||||
&IDM_GROUP_WRITE_PRIV_V1,
|
||||
&IDM_GROUP_UNIX_EXTEND_PRIV_V1,
|
||||
&IDM_ACCOUNT_MANAGE_PRIV_V1,
|
||||
&IDM_ACCOUNT_WRITE_PRIV_V1,
|
||||
&IDM_ACCOUNT_UNIX_EXTEND_PRIV_V1,
|
||||
&IDM_ACCOUNT_READ_PRIV_V1,
|
||||
&IDM_RADIUS_SECRET_WRITE_PRIV_V1,
|
||||
&IDM_RADIUS_SECRET_READ_PRIV_V1,
|
||||
&IDM_RADIUS_SERVERS_V1,
|
||||
&IDM_PEOPLE_SELF_WRITE_MAIL_V1,
|
||||
// Write deps on read, so write must be added first.
|
||||
&IDM_HP_ACCOUNT_MANAGE_PRIV_V1,
|
||||
&IDM_HP_ACCOUNT_WRITE_PRIV_V1,
|
||||
&IDM_HP_ACCOUNT_READ_PRIV_V1,
|
||||
&IDM_HP_ACCOUNT_UNIX_EXTEND_PRIV_V1,
|
||||
&IDM_SCHEMA_MANAGE_PRIV_V1,
|
||||
&IDM_HP_GROUP_MANAGE_PRIV_V1,
|
||||
&IDM_HP_GROUP_WRITE_PRIV_V1,
|
||||
&IDM_HP_GROUP_UNIX_EXTEND_PRIV_V1,
|
||||
&IDM_ACP_MANAGE_PRIV_V1,
|
||||
&DOMAIN_ADMINS,
|
||||
&IDM_HP_OAUTH2_MANAGE_PRIV_V1,
|
||||
&IDM_HP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_PRIV,
|
||||
&IDM_HP_SYNC_ACCOUNT_MANAGE_PRIV,
|
||||
// All members must exist before we write HP
|
||||
&IDM_HIGH_PRIVILEGE_V1,
|
||||
// other things
|
||||
&IDM_UI_ENABLE_EXPERIMENTAL_FEATURES,
|
||||
&IDM_ACCOUNT_MAIL_READ_PRIV,
|
||||
&IDM_ACCOUNT_MAIL_READ,
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -44,12 +44,13 @@ pub const SYSTEM_INDEX_VERSION: i64 = 30;
|
|||
pub type DomainVersion = u32;
|
||||
|
||||
pub const DOMAIN_LEVEL_1: DomainVersion = 1;
|
||||
pub const DOMAIN_LEVEL_2: DomainVersion = 2;
|
||||
// The minimum supported domain functional level
|
||||
pub const DOMAIN_MIN_LEVEL: DomainVersion = DOMAIN_LEVEL_1;
|
||||
pub const DOMAIN_MIN_LEVEL: DomainVersion = DOMAIN_LEVEL_2;
|
||||
// The target supported domain functional level
|
||||
pub const DOMAIN_TGT_LEVEL: DomainVersion = DOMAIN_LEVEL_1;
|
||||
pub const DOMAIN_TGT_LEVEL: DomainVersion = DOMAIN_LEVEL_2;
|
||||
// The maximum supported domain functional level
|
||||
pub const DOMAIN_MAX_LEVEL: DomainVersion = DOMAIN_LEVEL_1;
|
||||
pub const DOMAIN_MAX_LEVEL: DomainVersion = DOMAIN_LEVEL_2;
|
||||
|
||||
// On test builds, define to 60 seconds
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -6,7 +6,7 @@ use uuid::{uuid, Uuid};
|
|||
pub const STR_UUID_ADMIN: &str = "00000000-0000-0000-0000-000000000000";
|
||||
pub const UUID_ADMIN: Uuid = uuid!("00000000-0000-0000-0000-000000000000");
|
||||
pub const UUID_IDM_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000001");
|
||||
pub const UUID_IDM_PEOPLE_READ_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000002");
|
||||
pub const UUID_IDM_PEOPLE_PII_READ: Uuid = uuid!("00000000-0000-0000-0000-000000000002");
|
||||
pub const UUID_IDM_PEOPLE_WRITE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000003");
|
||||
pub const UUID_IDM_GROUP_WRITE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000004");
|
||||
pub const UUID_IDM_ACCOUNT_READ_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000005");
|
||||
|
@ -14,17 +14,17 @@ pub const UUID_IDM_ACCOUNT_WRITE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000
|
|||
pub const UUID_IDM_RADIUS_SERVERS: Uuid = uuid!("00000000-0000-0000-0000-000000000007");
|
||||
pub const UUID_IDM_HP_ACCOUNT_READ_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000008");
|
||||
pub const UUID_IDM_HP_ACCOUNT_WRITE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000009");
|
||||
pub const UUID_IDM_SCHEMA_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000010");
|
||||
pub const UUID_IDM_ACP_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000011");
|
||||
pub const UUID_IDM_SCHEMA_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000010");
|
||||
pub const UUID_IDM_ACCESS_CONTROL_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000011");
|
||||
pub const UUID_IDM_HP_GROUP_WRITE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000012");
|
||||
pub const UUID_IDM_PEOPLE_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000013");
|
||||
pub const UUID_IDM_PEOPLE_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000013");
|
||||
pub const UUID_IDM_ACCOUNT_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000014");
|
||||
pub const UUID_IDM_GROUP_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000015");
|
||||
pub const UUID_IDM_GROUP_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000015");
|
||||
pub const UUID_IDM_HP_ACCOUNT_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000016");
|
||||
pub const UUID_IDM_HP_GROUP_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000017");
|
||||
pub const UUID_IDM_ADMIN: Uuid = uuid!("00000000-0000-0000-0000-000000000018");
|
||||
|
||||
pub const STR_UUID_SYSTEM_ADMINS: &str = "00000000-0000-0000-0000-000000000000";
|
||||
pub const STR_UUID_SYSTEM_ADMINS: &str = "00000000-0000-0000-0000-000000000019";
|
||||
pub const UUID_SYSTEM_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000019");
|
||||
pub const UUID_DOMAIN_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000020");
|
||||
pub const UUID_IDM_ACCOUNT_UNIX_EXTEND_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000021");
|
||||
|
@ -35,7 +35,7 @@ pub const UUID_IDM_PEOPLE_EXTEND_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000
|
|||
pub const UUID_IDM_HP_ACCOUNT_UNIX_EXTEND_PRIV: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-000000000025");
|
||||
pub const UUID_IDM_HP_GROUP_UNIX_EXTEND_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000026");
|
||||
pub const UUID_IDM_HP_OAUTH2_MANAGE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000027");
|
||||
pub const UUID_IDM_OAUTH2_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000027");
|
||||
pub const UUID_IDM_HP_PEOPLE_READ_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000028");
|
||||
pub const UUID_IDM_HP_PEOPLE_WRITE_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000029");
|
||||
pub const UUID_IDM_HP_PEOPLE_EXTEND_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000030");
|
||||
|
@ -43,22 +43,29 @@ pub const UUID_IDM_HP_PEOPLE_EXTEND_PRIV: Uuid = uuid!("00000000-0000-0000-0000-
|
|||
pub const UUID_IDM_RADIUS_SECRET_READ_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-000000000032");
|
||||
pub const UUID_IDM_RADIUS_SECRET_WRITE_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-000000000031");
|
||||
pub const UUID_IDM_PEOPLE_SELF_WRITE_MAIL_PRIV: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-000000000033");
|
||||
pub const UUID_IDM_PEOPLE_SELF_WRITE_MAIL: Uuid = uuid!("00000000-0000-0000-0000-000000000033");
|
||||
pub const UUID_IDM_HP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_PRIV: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-000000000034");
|
||||
|
||||
pub const UUID_IDM_ALL_PERSONS: Uuid = uuid!("00000000-0000-0000-0000-000000000035");
|
||||
pub const STR_UUID_IDM_ALL_ACCOUNTS: &str = "00000000-0000-0000-0000-000000000036";
|
||||
pub const UUID_IDM_ALL_ACCOUNTS: Uuid = uuid!("00000000-0000-0000-0000-000000000036");
|
||||
|
||||
pub const UUID_IDM_HP_SYNC_ACCOUNT_MANAGE_PRIV: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-000000000037");
|
||||
|
||||
pub const UUID_IDM_UI_ENABLE_EXPERIMENTAL_FEATURES: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-000000000038");
|
||||
pub const UUID_IDM_ACCOUNT_MAIL_READ_PRIV: Uuid = uuid!("00000000-0000-0000-0000-000000000039");
|
||||
pub const UUID_IDM_ACCOUNT_MAIL_READ: Uuid = uuid!("00000000-0000-0000-0000-000000000039");
|
||||
pub const UUID_IDM_GROUP_ACCOUNT_POLICY_MANAGE_PRIV: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-000000000040");
|
||||
pub const UUID_IDM_SERVICE_DESK: Uuid = uuid!("00000000-0000-0000-0000-000000000041");
|
||||
pub const UUID_IDM_RECYCLE_BIN_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000042");
|
||||
pub const UUID_IDM_RADIUS_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000043");
|
||||
pub const UUID_IDM_UNIX_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000044");
|
||||
pub const UUID_IDM_PEOPLE_ON_BOARDING: Uuid = uuid!("00000000-0000-0000-0000-000000000045");
|
||||
pub const UUID_IDM_SERVICE_ACCOUNT_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000046");
|
||||
pub const UUID_IDM_ACCOUNT_POLICY_ADMINS: Uuid = uuid!("00000000-0000-0000-0000-000000000047");
|
||||
|
||||
//
|
||||
pub const UUID_IDM_HIGH_PRIVILEGE: Uuid = uuid!("00000000-0000-0000-0000-000000001000");
|
||||
|
@ -272,42 +279,42 @@ pub const UUID_DOMAIN_INFO: Uuid = uuid!("00000000-0000-0000-0000-ffffff000025")
|
|||
|
||||
// Access controls
|
||||
// skip 00 / 01 - see system info
|
||||
pub const UUID_IDM_ADMINS_ACP_RECYCLE_SEARCH_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000002");
|
||||
pub const UUID_IDM_ADMINS_ACP_REVIVE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000003");
|
||||
pub const UUID_IDM_SELF_ACP_READ_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000004");
|
||||
pub const UUID_IDM_ALL_ACP_READ_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000006");
|
||||
pub const UUID_IDM_ACP_PEOPLE_READ_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000007");
|
||||
pub const UUID_IDM_ACP_RECYCLE_BIN_SEARCH_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000002");
|
||||
pub const UUID_IDM_ACP_RECYCLE_BIN_REVIVE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000003");
|
||||
pub const UUID_IDM_ACP_SELF_READ_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000004");
|
||||
pub const UUID_IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000006");
|
||||
pub const UUID_IDM_ACP_PEOPLE_PII_READ_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000007");
|
||||
pub const UUID_IDM_ACP_PEOPLE_WRITE_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000008");
|
||||
pub const UUID_IDM_ACP_GROUP_WRITE_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000009");
|
||||
pub const UUID_IDM_ACP_ACCOUNT_READ_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000010");
|
||||
pub const UUID_IDM_ACP_ACCOUNT_WRITE_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000011");
|
||||
pub const UUID_IDM_ACP_ACCOUNT_MANAGE_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000012");
|
||||
pub const UUID_IDM_ACP_PEOPLE_MANAGE_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000013");
|
||||
pub const UUID_IDM_ACP_PEOPLE_PII_MANAGE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000013");
|
||||
pub const UUID_IDM_ACP_RADIUS_SERVERS_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000014");
|
||||
pub const UUID_IDM_ACP_HP_ACCOUNT_READ_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000015");
|
||||
pub const UUID_IDM_ACP_HP_ACCOUNT_WRITE_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000016");
|
||||
pub const UUID_IDM_ACP_HP_GROUP_WRITE_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000017");
|
||||
pub const UUID_IDM_ACP_SCHEMA_WRITE_ATTRS_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000018");
|
||||
pub const UUID_IDM_ACP_ACP_MANAGE_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000019");
|
||||
pub const UUID_IDM_ACP_SCHEMA_WRITE_CLASSES_PRIV_V1: Uuid =
|
||||
pub const UUID_IDM_ACP_SCHEMA_WRITE_ATTRS_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000018");
|
||||
pub const UUID_IDM_ACP_ACP_MANAGE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000019");
|
||||
pub const UUID_IDM_ACP_SCHEMA_WRITE_CLASSES_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000020");
|
||||
pub const UUID_IDM_SELF_ACP_WRITE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000021");
|
||||
pub const UUID_IDM_ACP_GROUP_MANAGE_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000022");
|
||||
pub const UUID_IDM_ACP_SELF_WRITE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000021");
|
||||
pub const UUID_IDM_ACP_GROUP_MANAGE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000022");
|
||||
pub const UUID_IDM_ACP_HP_ACCOUNT_MANAGE_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000023");
|
||||
pub const UUID_IDM_ACP_HP_GROUP_MANAGE_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000024");
|
||||
// Skip 25 - see domain info.
|
||||
pub const UUID_IDM_ACP_DOMAIN_ADMIN_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000026");
|
||||
pub const UUID_IDM_ACP_DOMAIN_ADMIN_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000026");
|
||||
|
||||
pub const STR_UUID_SYSTEM_CONFIG: &str = "00000000-0000-0000-0000-ffffff000027";
|
||||
pub const UUID_SYSTEM_CONFIG: Uuid = uuid!("00000000-0000-0000-0000-ffffff000027");
|
||||
|
||||
pub const UUID_IDM_ACP_SYSTEM_CONFIG_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000028");
|
||||
pub const UUID_IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000028");
|
||||
pub const UUID_IDM_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000029");
|
||||
pub const UUID_IDM_ACP_GROUP_UNIX_EXTEND_PRIV_V1: Uuid =
|
||||
|
@ -319,8 +326,7 @@ pub const UUID_IDM_HP_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1: Uuid =
|
|||
uuid!("00000000-0000-0000-0000-ffffff000033");
|
||||
pub const UUID_IDM_HP_ACP_GROUP_UNIX_EXTEND_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000034");
|
||||
pub const UUID_IDM_HP_ACP_OAUTH2_MANAGE_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000035");
|
||||
pub const UUID_IDM_ACP_OAUTH2_MANAGE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000035");
|
||||
pub const UUID_IDM_ACP_HP_PEOPLE_READ_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000036");
|
||||
pub const UUID_IDM_ACP_HP_PEOPLE_WRITE_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000037");
|
||||
|
@ -330,18 +336,50 @@ pub const UUID_IDM_ACP_RADIUS_SECRET_READ_PRIV_V1: Uuid =
|
|||
uuid!("00000000-0000-0000-0000-ffffff000039");
|
||||
pub const UUID_IDM_ACP_RADIUS_SECRET_WRITE_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000040");
|
||||
pub const UUID_IDM_PEOPLE_SELF_ACP_WRITE_MAIL_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000041");
|
||||
pub const UUID_IDM_ACP_PEOPLE_SELF_WRITE_MAIL: Uuid = uuid!("00000000-0000-0000-0000-ffffff000041");
|
||||
pub const UUID_IDM_HP_ACP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000042");
|
||||
pub const UUID_IDM_ACP_OAUTH2_READ_PRIV_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000043");
|
||||
pub const UUID_IDM_HP_ACP_SYNC_ACCOUNT_MANAGE_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000044");
|
||||
pub const UUID_IDM_ACP_ACCOUNT_MAIL_READ_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000045");
|
||||
pub const UUID_IDM_ACCOUNT_SELF_ACP_WRITE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000046");
|
||||
pub const UUID_IDM_ACP_ACCOUNT_MAIL_READ_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000045");
|
||||
pub const UUID_IDM_ACP_ACCOUNT_SELF_WRITE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000046");
|
||||
pub const UUID_IDM_ACP_SYSTEM_CONFIG_SESSION_EXP_PRIV_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000047");
|
||||
pub const UUID_IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000048");
|
||||
pub const UUID_IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000049");
|
||||
pub const UUID_IDM_ACP_GROUP_ENTRY_MANAGER_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000050");
|
||||
pub const UUID_IDM_ACP_SELF_NAME_WRITE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000051");
|
||||
pub const UUID_IDM_ACP_GROUP_READ: Uuid = uuid!("00000000-0000-0000-0000-ffffff000052");
|
||||
pub const UUID_IDM_ACP_PEOPLE_READ_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000053");
|
||||
pub const UUID_IDM_ACP_PEOPLE_CREATE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000054");
|
||||
pub const UUID_IDM_ACP_PEOPLE_DELETE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000055");
|
||||
pub const UUID_IDM_ACP_PEOPLE_MANAGE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000056");
|
||||
pub const UUID_IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000057");
|
||||
pub const UUID_IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000058");
|
||||
pub const UUID_IDM_ACP_SERVICE_ACCOUNT_CREATE_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000059");
|
||||
pub const UUID_IDM_ACP_SERVICE_ACCOUNT_DELETE_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000060");
|
||||
pub const UUID_IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000061");
|
||||
pub const UUID_IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000062");
|
||||
pub const UUID_IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000063");
|
||||
pub const UUID_IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000064");
|
||||
pub const UUID_IDM_ACP_SYNC_ACCOUNT_MANAGE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000065");
|
||||
pub const UUID_IDM_ACP_RADIUS_SECRET_MANAGE_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000066");
|
||||
pub const UUID_IDM_ACP_HP_GROUP_UNIX_MANAGE_V1: Uuid =
|
||||
uuid!("00000000-0000-0000-0000-ffffff000067");
|
||||
pub const UUID_IDM_ACP_GROUP_UNIX_MANAGE_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000068");
|
||||
pub const UUID_IDM_ACP_ACCOUNT_UNIX_EXTEND_V1: Uuid = uuid!("00000000-0000-0000-0000-ffffff000069");
|
||||
|
||||
// End of system ranges
|
||||
pub const UUID_DOES_NOT_EXIST: Uuid = uuid!("00000000-0000-0000-0000-fffffffffffe");
|
||||
|
|
|
@ -2149,8 +2149,8 @@ impl<STATE> Entry<EntryValid, STATE> {
|
|||
|
||||
if !missing_must.is_empty() {
|
||||
admin_warn!(
|
||||
"Validation error, the following required (must) attributes are missing - {:?}",
|
||||
missing_must
|
||||
"Validation error, the following required ({}) (must) attributes are missing - {:?}",
|
||||
self.get_display_id(), missing_must
|
||||
);
|
||||
// We if are in the recycle bin, we don't hard error here. This can occur when
|
||||
// a migration occurs and we delete an acp, and then the related group. Because
|
||||
|
@ -2235,8 +2235,11 @@ impl<STATE> Entry<EntryValid, STATE> {
|
|||
}
|
||||
None => {
|
||||
admin_error!(
|
||||
"{} - not found in the list of valid attributes for this set of classes - valid attributes are {:?}",
|
||||
"{} {} - not found in the list of valid attributes for this set of classes {:?} - valid attributes are {:?}",
|
||||
|
||||
attr_name.to_string(),
|
||||
self.get_display_id(),
|
||||
entry_classes.iter().collect::<Vec<_>>(),
|
||||
may.keys().collect::<Vec<_>>()
|
||||
);
|
||||
Err(SchemaError::AttributeNotValidForClass(
|
||||
|
@ -2935,9 +2938,9 @@ impl<VALID, STATE> Entry<VALID, STATE> {
|
|||
// valid, we still have strict typing checks between the filter -> entry to guarantee
|
||||
// they should be functional. We'll never match something that isn't syntactially valid.
|
||||
#[inline(always)]
|
||||
#[instrument(level = "trace", name = "entry::entry_match_no_index", skip(self))]
|
||||
/// Test if the following filter applies to and matches this entry.
|
||||
pub fn entry_match_no_index(&self, filter: &Filter<FilterValidResolved>) -> bool {
|
||||
let _entered = trace_span!("entry::entry_match_no_index").entered();
|
||||
self.entry_match_no_index_inner(filter.to_inner())
|
||||
}
|
||||
|
||||
|
|
|
@ -1074,7 +1074,7 @@ mod tests {
|
|||
let me = ModifyEvent::new_internal_invalid(
|
||||
filter!(f_eq(
|
||||
Attribute::Name,
|
||||
PartialValue::new_iname(IDM_PEOPLE_READ_PRIV_V1.name)
|
||||
PartialValue::new_iname(BUILTIN_GROUP_PEOPLE_PII_READ.name)
|
||||
)),
|
||||
ModifyList::new_list(vec![Modify::Present(
|
||||
Attribute::Member.into(),
|
||||
|
|
|
@ -171,13 +171,13 @@ fn enforce_unique<VALID, STATE>(
|
|||
|
||||
while let Some(cand_query) = queue.pop_front() {
|
||||
let filt_in = filter!(f_or(cand_query.to_vec()));
|
||||
let conflict_cand = qs.internal_exists(filt_in).map_err(|e| {
|
||||
let conflict_cand = qs.internal_search(filt_in).map_err(|e| {
|
||||
admin_error!("internal exists error {:?}", e);
|
||||
e
|
||||
})?;
|
||||
|
||||
// A conflict was found!
|
||||
if conflict_cand {
|
||||
if let Some(conflict_cand_zero) = conflict_cand.get(0) {
|
||||
if cand_query.len() >= 2 {
|
||||
// Continue to split to isolate.
|
||||
let mid = cand_query.len() / 2;
|
||||
|
@ -187,7 +187,7 @@ fn enforce_unique<VALID, STATE>(
|
|||
// Continue!
|
||||
} else {
|
||||
// Report this as a failing query.
|
||||
error!(cand_filters = ?cand_query, "The following filter conditions failed to assert uniqueness");
|
||||
error!(cand_filters = ?cand_query, conflicting_with = %conflict_cand_zero.get_display_id(), "The following filter conditions failed to assert uniqueness");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,11 +109,14 @@ pub(super) fn apply_modify_access<'a>(
|
|||
match &acm.target_condition {
|
||||
AccessControlTargetCondition::Scope(f_res) => {
|
||||
if !entry.entry_match_no_index(f_res) {
|
||||
debug!(entry = ?entry.get_display_id(), acm = %acm.acp.acp.name, "entry DOES NOT match acs");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
debug!(entry = ?entry.get_display_id(), acs = %acm.acp.acp.name, "acs applied to entry");
|
||||
|
||||
Some(acm.acp)
|
||||
})
|
||||
.collect();
|
||||
|
|
|
@ -115,6 +115,35 @@ impl QueryServer {
|
|||
if system_info_version < 16 {
|
||||
write_txn.migrate_15_to_16()?;
|
||||
}
|
||||
|
||||
if system_info_version < 17 {
|
||||
write_txn.migrate_16_to_17()?;
|
||||
}
|
||||
}
|
||||
|
||||
// This is the start of domain info related migrations which we will need in future
|
||||
// to handle replication. Due to the access control rework, and the addition of "managed by"
|
||||
// syntax, we need to ensure both node "fence" replication from each other. We do this
|
||||
// by changing domain infos to be incompatible during this phase.
|
||||
let domain_info_version = match write_txn.internal_search_uuid(UUID_DOMAIN_INFO) {
|
||||
Ok(e) => Ok(e.get_ava_single_uint32(Attribute::Version).unwrap_or(0)),
|
||||
Err(OperationError::NoMatchingEntries) => Ok(0),
|
||||
Err(r) => Err(r),
|
||||
}?;
|
||||
admin_debug!(?domain_info_version);
|
||||
|
||||
if domain_info_version < DOMAIN_TGT_LEVEL {
|
||||
write_txn
|
||||
.internal_modify_uuid(
|
||||
UUID_DOMAIN_INFO,
|
||||
&ModifyList::new_purge_and_set(
|
||||
Attribute::Version,
|
||||
Value::new_uint32(DOMAIN_TGT_LEVEL),
|
||||
),
|
||||
)
|
||||
.map(|()| {
|
||||
warn!("Domain level has been raised to {}", DOMAIN_TGT_LEVEL);
|
||||
})?;
|
||||
}
|
||||
|
||||
// Reload if anything in migrations requires it.
|
||||
|
@ -514,6 +543,106 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
// Complete
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip_all)]
|
||||
/// This migration will:
|
||||
/// * ensure that all access controls have the needed group receiver type
|
||||
/// * delete legacy entries that are no longer needed.
|
||||
pub fn migrate_16_to_17(&mut self) -> Result<(), OperationError> {
|
||||
admin_warn!("starting 16 to 17 migration.");
|
||||
|
||||
let filter = filter!(f_and!([
|
||||
f_or!([
|
||||
f_pres(Attribute::AcpReceiverGroup),
|
||||
f_pres(Attribute::AcpTargetScope),
|
||||
]),
|
||||
f_eq(
|
||||
Attribute::Class,
|
||||
EntryClass::AccessControlProfile.to_partialvalue()
|
||||
)
|
||||
]));
|
||||
// Delete the incorrectly added "member" attr.
|
||||
let modlist = ModifyList::new_list(vec![
|
||||
Modify::Present(
|
||||
Attribute::Class.into(),
|
||||
EntryClass::AccessControlReceiverGroup.to_value(),
|
||||
),
|
||||
Modify::Present(
|
||||
Attribute::Class.into(),
|
||||
EntryClass::AccessControlTargetScope.to_value(),
|
||||
),
|
||||
]);
|
||||
self.internal_modify(&filter, &modlist)?;
|
||||
|
||||
let delete_entries = [
|
||||
UUID_IDM_ACP_OAUTH2_READ_PRIV_V1,
|
||||
UUID_IDM_ACP_RADIUS_SECRET_READ_PRIV_V1,
|
||||
UUID_IDM_ACP_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1,
|
||||
UUID_IDM_ACP_SYSTEM_CONFIG_SESSION_EXP_PRIV_V1,
|
||||
UUID_IDM_ACP_HP_GROUP_WRITE_PRIV_V1,
|
||||
UUID_IDM_ACP_HP_GROUP_MANAGE_PRIV_V1,
|
||||
UUID_IDM_ACP_HP_PEOPLE_WRITE_PRIV_V1,
|
||||
UUID_IDM_ACP_ACCOUNT_READ_PRIV_V1,
|
||||
UUID_IDM_ACP_ACCOUNT_WRITE_PRIV_V1,
|
||||
UUID_IDM_ACP_ACCOUNT_MANAGE_PRIV_V1,
|
||||
UUID_IDM_ACP_HP_ACCOUNT_READ_PRIV_V1,
|
||||
UUID_IDM_ACP_HP_ACCOUNT_WRITE_PRIV_V1,
|
||||
UUID_IDM_ACP_GROUP_WRITE_PRIV_V1,
|
||||
UUID_IDM_ACP_HP_PEOPLE_EXTEND_PRIV_V1,
|
||||
UUID_IDM_ACP_PEOPLE_EXTEND_PRIV_V1,
|
||||
UUID_IDM_ACP_HP_ACCOUNT_MANAGE_PRIV_V1,
|
||||
UUID_IDM_HP_ACP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_V1,
|
||||
UUID_IDM_HP_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1,
|
||||
UUID_IDM_HP_ACP_SYNC_ACCOUNT_MANAGE_PRIV_V1,
|
||||
UUID_IDM_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1,
|
||||
UUID_IDM_ACP_RADIUS_SECRET_WRITE_PRIV_V1,
|
||||
UUID_IDM_HP_ACP_GROUP_UNIX_EXTEND_PRIV_V1,
|
||||
UUID_IDM_ACP_GROUP_UNIX_EXTEND_PRIV_V1,
|
||||
UUID_IDM_ACP_HP_PEOPLE_READ_PRIV_V1,
|
||||
UUID_IDM_ACP_PEOPLE_WRITE_PRIV_V1,
|
||||
UUID_IDM_HP_SYNC_ACCOUNT_MANAGE_PRIV,
|
||||
UUID_IDM_RADIUS_SECRET_WRITE_PRIV_V1,
|
||||
UUID_IDM_RADIUS_SECRET_READ_PRIV_V1,
|
||||
UUID_IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV,
|
||||
UUID_IDM_PEOPLE_EXTEND_PRIV,
|
||||
UUID_IDM_HP_PEOPLE_EXTEND_PRIV,
|
||||
UUID_IDM_HP_GROUP_MANAGE_PRIV,
|
||||
UUID_IDM_HP_GROUP_WRITE_PRIV,
|
||||
UUID_IDM_HP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_PRIV,
|
||||
UUID_IDM_GROUP_ACCOUNT_POLICY_MANAGE_PRIV,
|
||||
UUID_IDM_HP_GROUP_UNIX_EXTEND_PRIV,
|
||||
UUID_IDM_GROUP_WRITE_PRIV,
|
||||
UUID_IDM_GROUP_UNIX_EXTEND_PRIV,
|
||||
UUID_IDM_HP_ACCOUNT_UNIX_EXTEND_PRIV,
|
||||
UUID_IDM_ACCOUNT_UNIX_EXTEND_PRIV,
|
||||
UUID_IDM_PEOPLE_WRITE_PRIV,
|
||||
UUID_IDM_HP_PEOPLE_READ_PRIV,
|
||||
UUID_IDM_HP_PEOPLE_WRITE_PRIV,
|
||||
UUID_IDM_PEOPLE_WRITE_PRIV,
|
||||
UUID_IDM_ACCOUNT_READ_PRIV,
|
||||
UUID_IDM_ACCOUNT_MANAGE_PRIV,
|
||||
UUID_IDM_ACCOUNT_WRITE_PRIV,
|
||||
UUID_IDM_HP_ACCOUNT_READ_PRIV,
|
||||
UUID_IDM_HP_ACCOUNT_MANAGE_PRIV,
|
||||
UUID_IDM_HP_ACCOUNT_WRITE_PRIV,
|
||||
];
|
||||
|
||||
let res: Result<(), _> = delete_entries
|
||||
.into_iter()
|
||||
.try_for_each(|entry_uuid| self.internal_delete_uuid_if_exists(entry_uuid));
|
||||
if res.is_ok() {
|
||||
admin_debug!("initialise_idm -> result Ok!");
|
||||
} else {
|
||||
admin_error!(?res, "initialise_idm p3 -> result");
|
||||
}
|
||||
debug_assert!(res.is_ok());
|
||||
res?;
|
||||
|
||||
self.changed_schema = true;
|
||||
self.changed_acp = true;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip_all)]
|
||||
pub fn initialise_schema_core(&mut self) -> Result<(), OperationError> {
|
||||
admin_debug!("initialise_schema_core -> start ...");
|
||||
|
@ -678,6 +807,8 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
// The domain info now exists, we should be able to do these migrations as they will
|
||||
// cause SPN regenerations to occur
|
||||
|
||||
// Delete entries that no longer need to exist.
|
||||
// TODO: Shouldn't this be a migration?
|
||||
// Check the admin object exists (migrations).
|
||||
// Create the default idm_admin group.
|
||||
let admin_entries: Vec<EntryInitNew> = idm_builtin_admin_entries()?;
|
||||
|
@ -704,49 +835,46 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
|
||||
let idm_entries: Vec<BuiltinAcp> = vec![
|
||||
// Built in access controls.
|
||||
IDM_ADMINS_ACP_RECYCLE_SEARCH_V1.clone(),
|
||||
IDM_ADMINS_ACP_REVIVE_V1.clone(),
|
||||
IDM_ALL_ACP_READ_V1.clone(),
|
||||
IDM_SELF_ACP_READ_V1.clone(),
|
||||
IDM_SELF_ACP_WRITE_V1.clone(),
|
||||
E_IDM_PEOPLE_SELF_ACP_WRITE_MAIL_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_READ_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_READ_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_ACCOUNT_READ_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_ACCOUNT_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_ACCOUNT_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_GROUP_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_GROUP_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_GROUP_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_GROUP_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_SCHEMA_WRITE_ATTRS_PRIV_V1.clone(),
|
||||
IDM_ACP_SCHEMA_WRITE_CLASSES_PRIV_V1.clone(),
|
||||
IDM_ACP_ACP_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_RECYCLE_BIN_SEARCH_V1.clone(),
|
||||
IDM_ACP_RECYCLE_BIN_REVIVE_V1.clone(),
|
||||
IDM_ACP_SCHEMA_WRITE_ATTRS_V1.clone(),
|
||||
IDM_ACP_SCHEMA_WRITE_CLASSES_V1.clone(),
|
||||
IDM_ACP_ACP_MANAGE_V1.clone(),
|
||||
IDM_ACP_GROUP_ENTRY_MANAGED_BY_MODIFY_V1.clone(),
|
||||
IDM_ACP_GROUP_ENTRY_MANAGER_V1.clone(),
|
||||
IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_V1.clone(),
|
||||
IDM_ACP_OAUTH2_MANAGE_V1.clone(),
|
||||
IDM_ACP_DOMAIN_ADMIN_V1.clone(),
|
||||
IDM_ACP_SYNC_ACCOUNT_MANAGE_V1.clone(),
|
||||
IDM_ACP_RADIUS_SERVERS_V1.clone(),
|
||||
IDM_ACP_DOMAIN_ADMIN_PRIV_V1.clone(),
|
||||
IDM_ACP_SYSTEM_CONFIG_PRIV_V1.clone(),
|
||||
IDM_ACP_SYSTEM_CONFIG_SESSION_EXP_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_EXTEND_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_PEOPLE_READ_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_PEOPLE_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_PEOPLE_EXTEND_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1.clone(),
|
||||
E_IDM_HP_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1.clone(),
|
||||
IDM_ACP_GROUP_UNIX_EXTEND_PRIV_V1.clone(),
|
||||
E_IDM_HP_ACP_GROUP_UNIX_EXTEND_PRIV_V1.clone(),
|
||||
E_IDM_HP_ACP_OAUTH2_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_RADIUS_SECRET_READ_PRIV_V1.clone(),
|
||||
IDM_ACP_RADIUS_SECRET_WRITE_PRIV_V1.clone(),
|
||||
E_IDM_HP_ACP_SERVICE_ACCOUNT_INTO_PERSON_MIGRATE_V1.clone(),
|
||||
E_IDM_HP_ACP_SYNC_ACCOUNT_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_MAIL_READ_PRIV_V1.clone(),
|
||||
IDM_ACCOUNT_SELF_ACP_WRITE_V1.clone(),
|
||||
IDM_ACP_GROUP_ACCOUNT_POLICY_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_RADIUS_SECRET_MANAGE_V1.clone(),
|
||||
IDM_ACP_PEOPLE_SELF_WRITE_MAIL_V1.clone(),
|
||||
IDM_ACP_SELF_READ_V1.clone(),
|
||||
IDM_ACP_SELF_WRITE_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_SELF_WRITE_V1.clone(),
|
||||
IDM_ACP_SELF_NAME_WRITE_V1.clone(),
|
||||
IDM_ACP_ALL_ACCOUNTS_POSIX_READ_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_MAIL_READ_V1.clone(),
|
||||
IDM_ACP_SYSTEM_CONFIG_ACCOUNT_POLICY_MANAGE_V1.clone(),
|
||||
IDM_ACP_GROUP_UNIX_MANAGE_V1.clone(),
|
||||
IDM_ACP_HP_GROUP_UNIX_MANAGE_V1.clone(),
|
||||
IDM_ACP_GROUP_READ_V1.clone(),
|
||||
IDM_ACP_GROUP_MANAGE_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_UNIX_EXTEND_V1.clone(),
|
||||
IDM_ACP_PEOPLE_PII_READ_V1.clone(),
|
||||
IDM_ACP_PEOPLE_PII_MANAGE_V1.clone(),
|
||||
IDM_ACP_PEOPLE_CREATE_V1.clone(),
|
||||
IDM_ACP_PEOPLE_READ_V1.clone(),
|
||||
IDM_ACP_PEOPLE_MANAGE_V1.clone(),
|
||||
IDM_ACP_PEOPLE_DELETE_V1.clone(),
|
||||
IDM_ACP_PEOPLE_CREDENTIAL_RESET_V1.clone(),
|
||||
IDM_ACP_HP_PEOPLE_CREDENTIAL_RESET_V1.clone(),
|
||||
IDM_ACP_SERVICE_ACCOUNT_CREATE_V1.clone(),
|
||||
IDM_ACP_SERVICE_ACCOUNT_DELETE_V1.clone(),
|
||||
IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGER_V1.clone(),
|
||||
IDM_ACP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1.clone(),
|
||||
IDM_ACP_HP_SERVICE_ACCOUNT_ENTRY_MANAGED_BY_MODIFY_V1.clone(),
|
||||
IDM_ACP_SERVICE_ACCOUNT_MANAGE_V1.clone(),
|
||||
];
|
||||
|
||||
let res: Result<(), _> = idm_entries
|
||||
|
@ -760,21 +888,6 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
debug_assert!(res.is_ok());
|
||||
res?;
|
||||
|
||||
// Delete entries that no longer need to exist.
|
||||
// TODO: Shouldn't this be a migration?
|
||||
let delete_entries: [Uuid; 1] = [UUID_IDM_ACP_OAUTH2_READ_PRIV_V1];
|
||||
|
||||
let res: Result<(), _> = delete_entries
|
||||
.into_iter()
|
||||
.try_for_each(|entry_uuid| self.internal_delete_uuid_if_exists(entry_uuid));
|
||||
if res.is_ok() {
|
||||
admin_debug!("initialise_idm -> result Ok!");
|
||||
} else {
|
||||
admin_error!(?res, "initialise_idm p3 -> result");
|
||||
}
|
||||
debug_assert!(res.is_ok());
|
||||
res?;
|
||||
|
||||
// Some attributes we don't want to stomp if they already exist. So we conditionally
|
||||
// modify them.
|
||||
|
||||
|
|
|
@ -18,10 +18,7 @@ use kanidm_client::{KanidmClient, KanidmClientBuilder};
|
|||
use kanidm_proto::v1::{Filter, Modify, ModifyList};
|
||||
use kanidmd_core::config::{Configuration, IntegrationTestConfig};
|
||||
use kanidmd_core::{create_server_core, CoreHandle};
|
||||
use kanidmd_lib::prelude::{
|
||||
Attribute, BUILTIN_GROUP_IDM_ADMINS_V1, IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1,
|
||||
IDM_PEOPLE_EXTEND_PRIV_V1,
|
||||
};
|
||||
use kanidmd_lib::prelude::{Attribute, BUILTIN_GROUP_IDM_ADMINS_V1};
|
||||
use tokio::task;
|
||||
|
||||
pub const ADMIN_TEST_USER: &str = "admin";
|
||||
|
@ -116,7 +113,7 @@ pub async fn create_user(rsclient: &KanidmClient, id: &str, group_name: &str) {
|
|||
{
|
||||
#[allow(clippy::panic)]
|
||||
rsclient
|
||||
.idm_group_create(group_name)
|
||||
.idm_group_create(group_name, None)
|
||||
.await
|
||||
.unwrap_or_else(|_| panic!("Failed to create group {}", group_name));
|
||||
}
|
||||
|
@ -260,21 +257,6 @@ pub async fn is_attr_writable(rsclient: &KanidmClient, id: &str, attr: Attribute
|
|||
}
|
||||
|
||||
pub async fn login_account(rsclient: &KanidmClient, id: &str) {
|
||||
#[allow(clippy::expect_used)]
|
||||
rsclient
|
||||
.idm_group_add_members(
|
||||
IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1.name,
|
||||
&[ADMIN_TEST_USER],
|
||||
)
|
||||
.await
|
||||
.expect("Failed to add user to idm_people_account_password_import_priv");
|
||||
|
||||
#[allow(clippy::expect_used)]
|
||||
rsclient
|
||||
.idm_group_add_members(IDM_PEOPLE_EXTEND_PRIV_V1.name, &[ADMIN_TEST_USER])
|
||||
.await
|
||||
.expect("Failed to add user to idm_people_extend_priv");
|
||||
|
||||
#[allow(clippy::expect_used)]
|
||||
rsclient
|
||||
.idm_person_account_primary_credential_set_password(id, NOT_ADMIN_TEST_PASSWORD)
|
||||
|
|
|
@ -1,751 +0,0 @@
|
|||
#![deny(warnings)]
|
||||
use lazy_static::lazy_static;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use kanidm_client::KanidmClient;
|
||||
use kanidm_proto::constants::APPLICATION_JSON;
|
||||
use kanidmd_lib::prelude::*;
|
||||
use kanidmd_testkit::*;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
|
||||
static USER_READABLE_ATTRS: [Attribute; 9] = [
|
||||
Attribute::Name,
|
||||
Attribute::Spn,
|
||||
Attribute::DisplayName,
|
||||
Attribute::Class,
|
||||
Attribute::MemberOf,
|
||||
Attribute::Uuid,
|
||||
Attribute::GidNumber,
|
||||
Attribute::LoginShell,
|
||||
Attribute::SshPublicKey,
|
||||
];
|
||||
static SELF_WRITEABLE_ATTRS: [Attribute; 7] = [
|
||||
Attribute::Name,
|
||||
Attribute::DisplayName,
|
||||
Attribute::LegalName,
|
||||
Attribute::RadiusSecret,
|
||||
Attribute::SshPublicKey,
|
||||
Attribute::UnixPassword,
|
||||
// needs to be last
|
||||
Attribute::PrimaryCredential,
|
||||
];
|
||||
|
||||
lazy_static! {
|
||||
static ref DEFAULT_HP_GROUP_NAMES: [&'static str; 24] = [
|
||||
BUILTIN_GROUP_IDM_ADMINS_V1.name,
|
||||
BUILTIN_GROUP_SYSTEM_ADMINS_V1.name,
|
||||
IDM_PEOPLE_MANAGE_PRIV_V1.name,
|
||||
IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1.name,
|
||||
IDM_PEOPLE_EXTEND_PRIV_V1.name,
|
||||
IDM_PEOPLE_WRITE_PRIV_V1.name,
|
||||
IDM_PEOPLE_READ_PRIV_V1.name,
|
||||
IDM_GROUP_MANAGE_PRIV_V1.name,
|
||||
IDM_GROUP_WRITE_PRIV_V1.name,
|
||||
IDM_ACCOUNT_MANAGE_PRIV_V1.name,
|
||||
IDM_ACCOUNT_WRITE_PRIV_V1.name,
|
||||
IDM_ACCOUNT_READ_PRIV_V1.name,
|
||||
IDM_RADIUS_SERVERS_V1.name,
|
||||
IDM_HP_ACCOUNT_MANAGE_PRIV_V1.name,
|
||||
IDM_HP_ACCOUNT_WRITE_PRIV_V1.name,
|
||||
IDM_HP_ACCOUNT_READ_PRIV_V1.name,
|
||||
IDM_HP_ACCOUNT_UNIX_EXTEND_PRIV_V1.name,
|
||||
IDM_SCHEMA_MANAGE_PRIV_V1.name,
|
||||
IDM_HP_GROUP_MANAGE_PRIV_V1.name,
|
||||
IDM_HP_GROUP_WRITE_PRIV_V1.name,
|
||||
IDM_HP_GROUP_UNIX_EXTEND_PRIV_V1.name,
|
||||
IDM_ACP_MANAGE_PRIV_V1.name,
|
||||
DOMAIN_ADMINS.name,
|
||||
IDM_HIGH_PRIVILEGE_V1.name,
|
||||
];
|
||||
static ref DEFAULT_NOT_HP_GROUP_NAMES: [&'static str; 2] = [
|
||||
IDM_ACCOUNT_UNIX_EXTEND_PRIV_V1.name,
|
||||
IDM_GROUP_UNIX_EXTEND_PRIV_V1.name,
|
||||
];
|
||||
}
|
||||
|
||||
// Users
|
||||
// - Read to all self attributes (within security constraints).
|
||||
// - Write to a limited set of self attributes, such as:
|
||||
// name, displayname, legalname, ssh-keys, credentials etc.
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_users(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
create_user_with_all_attrs(&rsclient, "self_account", Some("self_group")).await;
|
||||
create_user_with_all_attrs(&rsclient, "other_account", Some("other_group")).await;
|
||||
|
||||
login_account(&rsclient, "self_account").await;
|
||||
|
||||
test_read_attrs(&rsclient, "self_account", &USER_READABLE_ATTRS, true).await;
|
||||
test_read_attrs(&rsclient, "other_account", &USER_READABLE_ATTRS, true).await;
|
||||
|
||||
static GROUP_READABLE_ATTRS: [Attribute; 5] = [
|
||||
Attribute::Class,
|
||||
Attribute::Name,
|
||||
Attribute::Spn,
|
||||
Attribute::Uuid,
|
||||
Attribute::Member,
|
||||
];
|
||||
test_read_attrs(&rsclient, "self_group", &GROUP_READABLE_ATTRS, true).await;
|
||||
test_read_attrs(&rsclient, "other_group", &GROUP_READABLE_ATTRS, true).await;
|
||||
|
||||
static USER_SENSITIVE_ATTRS: [Attribute; 2] = [Attribute::LegalName, Attribute::Mail];
|
||||
test_read_attrs(&rsclient, "other_account", &USER_SENSITIVE_ATTRS, false).await;
|
||||
|
||||
static SELF_READABLE_ATTRS: [Attribute; 1] = [Attribute::RadiusSecret];
|
||||
test_read_attrs(&rsclient, "self_account", &SELF_READABLE_ATTRS, true).await;
|
||||
test_read_attrs(&rsclient, "other_account", &SELF_READABLE_ATTRS, false).await;
|
||||
|
||||
test_write_attrs(&rsclient, "self_account", &SELF_WRITEABLE_ATTRS, true).await;
|
||||
test_write_attrs(&rsclient, "other_account", &SELF_WRITEABLE_ATTRS, false).await;
|
||||
|
||||
static NON_SELF_WRITEABLE_ATTRS: [Attribute; 5] = [
|
||||
Attribute::Spn,
|
||||
Attribute::Class,
|
||||
Attribute::MemberOf,
|
||||
Attribute::GidNumber,
|
||||
Attribute::Uuid,
|
||||
];
|
||||
test_write_attrs(&rsclient, "self_account", &NON_SELF_WRITEABLE_ATTRS, false).await;
|
||||
}
|
||||
|
||||
// Account Managers
|
||||
// read and write to accounts, including write credentials but NOT private data (see people manager)
|
||||
// ability to lock and unlock accounts, excluding high access members.
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_account_managers(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
create_user(
|
||||
&rsclient,
|
||||
"account_manager",
|
||||
IDM_ACCOUNT_MANAGE_PRIV_V1.name,
|
||||
)
|
||||
.await;
|
||||
create_user_with_all_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, Some("test_group")).await;
|
||||
|
||||
login_account(&rsclient, "account_manager").await;
|
||||
|
||||
test_read_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&USER_READABLE_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
static ACCOUNT_MANAGER_ATTRS: [Attribute; 5] = [
|
||||
Attribute::Name,
|
||||
Attribute::DisplayName,
|
||||
Attribute::PrimaryCredential,
|
||||
Attribute::SshPublicKey,
|
||||
Attribute::Mail,
|
||||
];
|
||||
test_write_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&ACCOUNT_MANAGER_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
|
||||
static PRIVATE_DATA_ATTRS: [Attribute; 1] = [Attribute::LegalName];
|
||||
test_read_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&PRIVATE_DATA_ATTRS,
|
||||
false,
|
||||
)
|
||||
.await;
|
||||
test_write_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&PRIVATE_DATA_ATTRS,
|
||||
false,
|
||||
)
|
||||
.await;
|
||||
// TODO #59: lock and _unlock, except high access members
|
||||
}
|
||||
|
||||
// Group Managers
|
||||
// read all groups
|
||||
// write group but not high access
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_group_managers(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
create_user(&rsclient, "group_manager", IDM_GROUP_MANAGE_PRIV_V1.name).await;
|
||||
// create test user without creating new groups
|
||||
create_user(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
BUILTIN_GROUP_IDM_ADMINS_V1.name,
|
||||
)
|
||||
.await;
|
||||
|
||||
login_account(&rsclient, "group_manager").await;
|
||||
|
||||
let default_group_names: HashSet<String> =
|
||||
[&DEFAULT_HP_GROUP_NAMES[..], &DEFAULT_NOT_HP_GROUP_NAMES[..]]
|
||||
.concat()
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect();
|
||||
|
||||
let groups = rsclient.idm_group_list().await.unwrap();
|
||||
let group_names: HashSet<String> = groups
|
||||
.iter()
|
||||
.map(|entry| {
|
||||
entry
|
||||
.attrs
|
||||
.get(Attribute::Name.as_ref())
|
||||
.unwrap()
|
||||
.first()
|
||||
.unwrap()
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
assert!(default_group_names.is_subset(&group_names));
|
||||
|
||||
test_modify_group(&rsclient, &(*DEFAULT_HP_GROUP_NAMES), false).await;
|
||||
test_modify_group(&rsclient, &(*DEFAULT_NOT_HP_GROUP_NAMES), true).await;
|
||||
|
||||
rsclient.idm_group_create("test_group").await.unwrap();
|
||||
rsclient
|
||||
.idm_group_add_members("test_group", &[NOT_ADMIN_TEST_USERNAME])
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(
|
||||
is_attr_writable(&rsclient, "test_group", Attribute::Description)
|
||||
.await
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
// Admins
|
||||
// read and write access control entries.
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_admins_access_control_entries(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
static ACP_COMMON_ATTRS: [Attribute; 4] = [
|
||||
Attribute::Name,
|
||||
Attribute::Description,
|
||||
Attribute::AcpReceiverGroup,
|
||||
Attribute::AcpTargetScope,
|
||||
];
|
||||
let acp_entries = vec![
|
||||
IDM_ADMINS_ACP_RECYCLE_SEARCH_V1.clone(),
|
||||
IDM_ADMINS_ACP_REVIVE_V1.clone(),
|
||||
IDM_SELF_ACP_READ_V1.clone(),
|
||||
IDM_SELF_ACP_WRITE_V1.clone(),
|
||||
IDM_ALL_ACP_READ_V1.clone(),
|
||||
IDM_ACP_PEOPLE_READ_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1.clone(),
|
||||
IDM_ACP_PEOPLE_EXTEND_PRIV_V1.clone(),
|
||||
IDM_ACP_GROUP_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_READ_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_RADIUS_SERVERS_V1.clone(),
|
||||
IDM_ACP_HP_ACCOUNT_READ_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_ACCOUNT_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_GROUP_WRITE_PRIV_V1.clone(),
|
||||
IDM_ACP_SCHEMA_WRITE_ATTRS_PRIV_V1.clone(),
|
||||
IDM_ACP_ACP_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_SCHEMA_WRITE_CLASSES_PRIV_V1.clone(),
|
||||
IDM_ACP_GROUP_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_ACCOUNT_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_HP_GROUP_MANAGE_PRIV_V1.clone(),
|
||||
IDM_ACP_DOMAIN_ADMIN_PRIV_V1.clone(),
|
||||
IDM_ACP_SYSTEM_CONFIG_PRIV_V1.clone(),
|
||||
IDM_ACP_ACCOUNT_UNIX_EXTEND_PRIV_V1.clone(),
|
||||
IDM_ACP_GROUP_UNIX_EXTEND_PRIV_V1.clone(),
|
||||
];
|
||||
|
||||
for entry in acp_entries.iter() {
|
||||
test_read_attrs(&rsclient, entry.name, &ACP_COMMON_ATTRS, true).await;
|
||||
test_write_attrs(&rsclient, entry.name, &ACP_COMMON_ATTRS, true).await;
|
||||
}
|
||||
}
|
||||
|
||||
// read schema entries.
|
||||
// TODO #252: write schema entries
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_admins_schema_entries(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
let default_classnames: HashSet<String> = [
|
||||
EntryClass::AccessControlCreate,
|
||||
EntryClass::AccessControlDelete,
|
||||
EntryClass::AccessControlModify,
|
||||
EntryClass::AccessControlProfile,
|
||||
EntryClass::AccessControlSearch,
|
||||
EntryClass::AttributeType,
|
||||
EntryClass::ClassType,
|
||||
EntryClass::ExtensibleObject,
|
||||
EntryClass::MemberOf,
|
||||
EntryClass::Object,
|
||||
EntryClass::Recycled,
|
||||
EntryClass::System,
|
||||
EntryClass::SystemInfo,
|
||||
EntryClass::Tombstone,
|
||||
EntryClass::Person,
|
||||
EntryClass::Group,
|
||||
EntryClass::Account,
|
||||
EntryClass::DomainInfo,
|
||||
EntryClass::PosixAccount,
|
||||
EntryClass::PosixGroup,
|
||||
EntryClass::SystemConfig,
|
||||
]
|
||||
.into_iter()
|
||||
.map(|e| e.into())
|
||||
.collect();
|
||||
|
||||
let classtype_entries = rsclient.idm_schema_classtype_list().await.unwrap();
|
||||
let classnames: HashSet<String> = classtype_entries
|
||||
.iter()
|
||||
.map(|entry| {
|
||||
entry
|
||||
.attrs
|
||||
.get(Attribute::ClassName.as_ref())
|
||||
.unwrap()
|
||||
.first()
|
||||
.unwrap()
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
println!("{:?}", classnames);
|
||||
|
||||
assert!(default_classnames.is_subset(&classnames));
|
||||
|
||||
// TODO: this could probably just iterate on the enum?
|
||||
let default_attributenames: HashSet<String> = [
|
||||
Attribute::AcpCreateAttr,
|
||||
Attribute::AcpCreateClass,
|
||||
Attribute::AcpEnable,
|
||||
Attribute::AcpModifyClass,
|
||||
Attribute::AcpModifyPresentAttr,
|
||||
Attribute::AcpModifyRemovedAttr,
|
||||
Attribute::AcpReceiverGroup,
|
||||
Attribute::AcpSearchAttr,
|
||||
Attribute::AcpTargetScope,
|
||||
Attribute::AttributeName,
|
||||
Attribute::Claim,
|
||||
Attribute::Class,
|
||||
Attribute::ClassName,
|
||||
Attribute::Description,
|
||||
Attribute::DirectMemberOf,
|
||||
Attribute::Domain,
|
||||
Attribute::Index,
|
||||
Attribute::LastModifiedCid,
|
||||
Attribute::May,
|
||||
Attribute::Member,
|
||||
Attribute::MemberOf,
|
||||
Attribute::MultiValue,
|
||||
Attribute::Must,
|
||||
Attribute::Name,
|
||||
Attribute::PasswordImport,
|
||||
Attribute::Phantom,
|
||||
Attribute::Spn,
|
||||
Attribute::Syntax,
|
||||
Attribute::SystemMay,
|
||||
Attribute::SystemMust,
|
||||
Attribute::Unique,
|
||||
Attribute::Uuid,
|
||||
Attribute::Version,
|
||||
Attribute::DisplayName,
|
||||
Attribute::LegalName,
|
||||
Attribute::Mail,
|
||||
Attribute::SshPublicKey,
|
||||
Attribute::PrimaryCredential,
|
||||
Attribute::RadiusSecret,
|
||||
Attribute::DomainName,
|
||||
Attribute::DomainDisplayName,
|
||||
Attribute::DomainUuid,
|
||||
Attribute::DomainSsid,
|
||||
Attribute::GidNumber,
|
||||
Attribute::BadlistPassword,
|
||||
Attribute::AuthSessionExpiry,
|
||||
Attribute::PrivilegeExpiry,
|
||||
Attribute::LoginShell,
|
||||
Attribute::UnixPassword,
|
||||
Attribute::NsUniqueId,
|
||||
]
|
||||
.iter()
|
||||
.map(|a| a.as_ref().to_string())
|
||||
.collect();
|
||||
|
||||
let attributename_entries = rsclient.idm_schema_attributetype_list().await.unwrap();
|
||||
println!("{:?}", attributename_entries);
|
||||
let attributenames = attributename_entries
|
||||
.iter()
|
||||
.map(|entry| {
|
||||
entry
|
||||
.attrs
|
||||
.get(Attribute::AttributeName.as_ref())
|
||||
.unwrap()
|
||||
.first()
|
||||
.unwrap()
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
assert!(default_attributenames.is_subset(&attributenames));
|
||||
}
|
||||
|
||||
// modify all groups including high access groups.
|
||||
// create new accounts (to bootstrap the system).
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_admins_group_entries(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
create_user(&rsclient, NOT_ADMIN_TEST_USERNAME, "test_group").await;
|
||||
|
||||
let default_group_names =
|
||||
[&DEFAULT_HP_GROUP_NAMES[..], &DEFAULT_NOT_HP_GROUP_NAMES[..]].concat();
|
||||
|
||||
test_modify_group(&rsclient, &default_group_names, true).await;
|
||||
}
|
||||
|
||||
// modify high access accounts as an escalation for security sensitive accounts.
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_admins_ha_accounts(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
static MAIN_ATTRS: [Attribute; 3] = [
|
||||
Attribute::Name,
|
||||
Attribute::DisplayName,
|
||||
Attribute::PrimaryCredential,
|
||||
];
|
||||
test_write_attrs(&rsclient, BUILTIN_ACCOUNT_IDM_ADMIN.name, &MAIN_ATTRS, true).await;
|
||||
}
|
||||
|
||||
// recover from the recycle bin
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_admins_recycle_accounts(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
create_user(&rsclient, NOT_ADMIN_TEST_USERNAME, "test_group").await;
|
||||
|
||||
rsclient
|
||||
.idm_person_account_delete(NOT_ADMIN_TEST_USERNAME)
|
||||
.await
|
||||
.unwrap();
|
||||
rsclient
|
||||
.recycle_bin_revive(NOT_ADMIN_TEST_USERNAME)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let acc = rsclient
|
||||
.idm_person_account_get(NOT_ADMIN_TEST_USERNAME)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(acc.is_some());
|
||||
}
|
||||
|
||||
// People Managers
|
||||
// read private or sensitive data of persons, IE legalName
|
||||
// write private or sensitive data of persons, IE legalName
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_people_managers(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
create_user(
|
||||
&rsclient,
|
||||
"read_people_manager",
|
||||
IDM_PEOPLE_READ_PRIV_V1.name,
|
||||
)
|
||||
.await;
|
||||
create_user_with_all_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, Some("test_group")).await;
|
||||
|
||||
static PEOPLE_MANAGER_ATTRS: [Attribute; 2] = [Attribute::LegalName, Attribute::Mail];
|
||||
|
||||
static TECHNICAL_ATTRS: [Attribute; 3] = [
|
||||
Attribute::PrimaryCredential,
|
||||
Attribute::RadiusSecret,
|
||||
Attribute::UnixPassword,
|
||||
];
|
||||
test_read_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&PEOPLE_MANAGER_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
|
||||
login_account(&rsclient, "read_people_manager").await;
|
||||
|
||||
test_read_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&PEOPLE_MANAGER_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
test_read_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, &TECHNICAL_ATTRS, false).await;
|
||||
test_write_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&PEOPLE_MANAGER_ATTRS,
|
||||
false,
|
||||
)
|
||||
.await;
|
||||
test_write_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, &TECHNICAL_ATTRS, false).await;
|
||||
|
||||
let _ = rsclient.logout();
|
||||
rsclient
|
||||
.auth_simple_password(ADMIN_TEST_USER, ADMIN_TEST_PASSWORD)
|
||||
.await
|
||||
.unwrap();
|
||||
create_user(
|
||||
&rsclient,
|
||||
"write_people_manager",
|
||||
IDM_PEOPLE_WRITE_PRIV_V1.name,
|
||||
)
|
||||
.await;
|
||||
login_account(&rsclient, "write_people_manager").await;
|
||||
|
||||
test_read_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&PEOPLE_MANAGER_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
test_read_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, &TECHNICAL_ATTRS, false).await;
|
||||
test_write_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&PEOPLE_MANAGER_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
test_write_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, &TECHNICAL_ATTRS, false).await;
|
||||
}
|
||||
|
||||
// Anonymous Clients + Everyone Else
|
||||
// read memberof, unix attrs, name, displayname, class
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_anonymous_entry(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
create_user_with_all_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, Some("test_group")).await;
|
||||
rsclient
|
||||
.idm_group_add_members("test_group", &["anonymous"])
|
||||
.await
|
||||
.unwrap();
|
||||
add_all_attrs(&rsclient, "anonymous", "test_group", None).await;
|
||||
|
||||
let _ = rsclient.logout();
|
||||
rsclient.auth_anonymous().await.unwrap();
|
||||
|
||||
test_read_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&USER_READABLE_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
test_read_attrs(&rsclient, "anonymous", &USER_READABLE_ATTRS, true).await;
|
||||
test_write_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&SELF_WRITEABLE_ATTRS,
|
||||
false,
|
||||
)
|
||||
.await;
|
||||
test_write_attrs(&rsclient, "anonymous", &SELF_WRITEABLE_ATTRS, false).await;
|
||||
}
|
||||
|
||||
// RADIUS Servers
|
||||
// Read radius credentials
|
||||
// Read other needed attributes to fulfil radius functions.
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_default_entries_rbac_radius_servers(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
create_user(&rsclient, "radius_server", IDM_RADIUS_SERVERS_V1.name).await;
|
||||
create_user_with_all_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, Some("test_group")).await;
|
||||
|
||||
login_account(&rsclient, "radius_server").await;
|
||||
static RADIUS_NECESSARY_ATTRS: [Attribute; 4] = [
|
||||
Attribute::Name,
|
||||
Attribute::Spn,
|
||||
Attribute::Uuid,
|
||||
Attribute::RadiusSecret,
|
||||
];
|
||||
|
||||
test_read_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&USER_READABLE_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
test_read_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&RADIUS_NECESSARY_ATTRS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
test_write_attrs(
|
||||
&rsclient,
|
||||
NOT_ADMIN_TEST_USERNAME,
|
||||
&RADIUS_NECESSARY_ATTRS,
|
||||
false,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_self_write_mail_priv_people(rsclient: KanidmClient) {
|
||||
login_put_admin_idm_admins(&rsclient).await;
|
||||
|
||||
// test and other, each can write to themselves, but not each other
|
||||
create_user_with_all_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, None).await;
|
||||
create_user_with_all_attrs(&rsclient, "other", None).await;
|
||||
rsclient
|
||||
.idm_group_add_members(
|
||||
IDM_PEOPLE_SELF_WRITE_MAIL_PRIV_V1.name,
|
||||
&["other", NOT_ADMIN_TEST_USERNAME],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
// a non-person, they can't write to themselves even with the priv
|
||||
create_user(&rsclient, "nonperson", "nonperson_group").await;
|
||||
|
||||
login_account(&rsclient, NOT_ADMIN_TEST_USERNAME).await;
|
||||
// can write to own mail
|
||||
test_write_attrs(&rsclient, NOT_ADMIN_TEST_USERNAME, &[Attribute::Mail], true).await;
|
||||
// not someone elses
|
||||
test_write_attrs(&rsclient, "other", &[Attribute::Mail], false).await;
|
||||
|
||||
// but they can write to theirs
|
||||
login_account_via_admin(&rsclient, "other").await;
|
||||
test_write_attrs(&rsclient, "other", &[Attribute::Mail], true).await;
|
||||
login_account_via_admin(&rsclient, "nonperson").await;
|
||||
test_write_attrs(&rsclient, "nonperson", &[Attribute::Mail], false).await;
|
||||
}
|
||||
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_https_robots_txt(rsclient: KanidmClient) {
|
||||
// We need to do manual reqwests here.
|
||||
|
||||
let response = match reqwest::get(rsclient.make_url("/robots.txt")).await {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
panic!(
|
||||
"Failed to query {:?} : {:#?}",
|
||||
rsclient.make_url("/robots.txt"),
|
||||
error
|
||||
);
|
||||
}
|
||||
};
|
||||
eprintln!("response: {:#?}", response);
|
||||
assert_eq!(response.status(), 200);
|
||||
|
||||
eprintln!(
|
||||
"csp headers: {:#?}",
|
||||
response
|
||||
.headers()
|
||||
.get(http::header::CONTENT_SECURITY_POLICY)
|
||||
);
|
||||
assert_ne!(
|
||||
response
|
||||
.headers()
|
||||
.get(http::header::CONTENT_SECURITY_POLICY),
|
||||
None
|
||||
);
|
||||
eprintln!("{}", response.text().await.unwrap());
|
||||
}
|
||||
|
||||
/// This literally tests that the thing exists and responds in a way we expect, probably worth testing it better...
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_v1_raw_delete(rsclient: KanidmClient) {
|
||||
// We need to do manual reqwests here.
|
||||
|
||||
let client = reqwest::ClientBuilder::new()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let post_body = serde_json::json!({"filter": "self"}).to_string();
|
||||
|
||||
let response = match client
|
||||
.post(rsclient.make_url("/v1/raw/delete"))
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||
.body(post_body)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
panic!(
|
||||
"Failed to query {:?} : {:#?}",
|
||||
rsclient.make_url("/v1/raw/delete"),
|
||||
error
|
||||
);
|
||||
}
|
||||
};
|
||||
eprintln!("response: {:#?}", response);
|
||||
assert_eq!(response.status(), 401);
|
||||
|
||||
let body = response.text().await.unwrap();
|
||||
eprintln!("{}", body);
|
||||
}
|
||||
|
||||
/// This literally tests that the thing exists and responds in a way we expect, probably worth testing it better...
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_v1_raw_logout(rsclient: KanidmClient) {
|
||||
// We need to do manual reqwests here.
|
||||
let client = reqwest::ClientBuilder::new()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let response = match client.get(rsclient.make_url("/v1/logout")).send().await {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
panic!(
|
||||
"Failed to query {:?} : {:#?}",
|
||||
rsclient.make_url("/v1/logout"),
|
||||
error
|
||||
);
|
||||
}
|
||||
};
|
||||
eprintln!("response: {:#?}", response);
|
||||
assert_eq!(response.status(), 401);
|
||||
|
||||
let body = response.text().await.unwrap();
|
||||
eprintln!("{}", body);
|
||||
}
|
||||
|
||||
/// This literally tests that the thing exists and responds in a way we expect, probably worth testing it better...
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_status_endpoint(rsclient: KanidmClient) {
|
||||
// We need to do manual reqwests here.
|
||||
let client = reqwest::ClientBuilder::new()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let response = match client.get(rsclient.make_url("/status")).send().await {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
panic!(
|
||||
"Failed to query {:?} : {:#?}",
|
||||
rsclient.make_url("/status"),
|
||||
error
|
||||
);
|
||||
}
|
||||
};
|
||||
eprintln!("response: {:#?}", response);
|
||||
assert_eq!(response.status(), 200);
|
||||
|
||||
let body = response.text().await.unwrap();
|
||||
eprintln!("{}", body);
|
||||
assert!(body.contains("true") == true);
|
||||
}
|
|
@ -5,16 +5,11 @@ use kanidm_proto::{
|
|||
v1::Entry,
|
||||
};
|
||||
|
||||
use kanidmd_lib::prelude::{
|
||||
Attribute, BUILTIN_GROUP_IDM_ADMINS_V1, IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1,
|
||||
IDM_PEOPLE_MANAGE_PRIV_V1,
|
||||
};
|
||||
use kanidmd_lib::prelude::Attribute;
|
||||
use kanidmd_testkit::ADMIN_TEST_PASSWORD;
|
||||
use reqwest::StatusCode;
|
||||
|
||||
static UNIVERSAL_PW: &'static str = "eicieY7ahchaoCh0eeTa";
|
||||
static UNIVERSAL_PW_HASH: &'static str =
|
||||
"pbkdf2_sha256$36000$xIEozuZVAoYm$uW1b35DUKyhvQAf1mBqMvoBDcqSD06juzyO/nmyV0+w=";
|
||||
|
||||
static USER_A_NAME: &'static str = "valid_user_a";
|
||||
|
||||
|
@ -272,23 +267,6 @@ async fn setup_server(rsclient: &KanidmClient) {
|
|||
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
||||
.await;
|
||||
assert!(res.is_ok());
|
||||
|
||||
// To enable the admin to actually make some of these changes, we have
|
||||
// to make them a people admin. NOT recommended in production!
|
||||
rsclient
|
||||
.idm_group_add_members(IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1.name, &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
rsclient
|
||||
.idm_group_add_members(IDM_PEOPLE_MANAGE_PRIV_V1.name, &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
rsclient
|
||||
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn create_user(rsclient: &KanidmClient, user: &str) -> String {
|
||||
|
@ -306,10 +284,12 @@ async fn create_user(rsclient: &KanidmClient, user: &str) -> String {
|
|||
let res = rsclient.create(vec![e.clone()]).await;
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
||||
rsclient
|
||||
.idm_person_account_primary_credential_import_password(user, UNIVERSAL_PW_HASH)
|
||||
.idm_person_account_primary_credential_set_password(user, UNIVERSAL_PW)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let r = rsclient
|
||||
.idm_person_account_get_attr(user, Attribute::Uuid.as_ref())
|
||||
.await
|
||||
|
|
|
@ -10,7 +10,7 @@ use kanidm_proto::oauth2::{
|
|||
AccessTokenIntrospectRequest, AccessTokenIntrospectResponse, AccessTokenRequest,
|
||||
AccessTokenResponse, AuthorisationResponse, GrantTypeReq, OidcDiscoveryResponse,
|
||||
};
|
||||
use kanidmd_lib::prelude::{Attribute, BUILTIN_GROUP_IDM_ADMINS_V1, IDM_ALL_ACCOUNTS};
|
||||
use kanidmd_lib::prelude::{Attribute, IDM_ALL_ACCOUNTS};
|
||||
use oauth2_ext::PkceCodeChallenge;
|
||||
use reqwest::header::{HeaderValue, CONTENT_TYPE};
|
||||
use reqwest::StatusCode;
|
||||
|
@ -66,11 +66,6 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
|||
.expect("Failed to create oauth2 config");
|
||||
|
||||
// Extend the admin account with extended details for openid claims.
|
||||
rsclient
|
||||
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
rsclient
|
||||
.idm_person_account_create("oauth_test", "oauth_test")
|
||||
.await
|
||||
|
@ -429,11 +424,6 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
|||
.expect("Failed to create oauth2 config");
|
||||
|
||||
// Extend the admin account with extended details for openid claims.
|
||||
rsclient
|
||||
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
rsclient
|
||||
.idm_person_account_create("oauth_test", "oauth_test")
|
||||
.await
|
||||
|
|
|
@ -6,13 +6,11 @@ use kanidm_proto::constants::KSESSIONID;
|
|||
use kanidm_proto::internal::ImageValue;
|
||||
use kanidm_proto::v1::{
|
||||
ApiToken, AuthCredential, AuthIssueSession, AuthMech, AuthRequest, AuthResponse, AuthState,
|
||||
AuthStep, CURegState, CredentialDetailType, Entry, Filter, Modify, ModifyList, UatPurpose,
|
||||
UserAuthToken,
|
||||
AuthStep, CURegState, Entry, Filter, Modify, ModifyList, UatPurpose, UserAuthToken,
|
||||
};
|
||||
use kanidmd_lib::credential::totp::Totp;
|
||||
use kanidmd_lib::prelude::{
|
||||
Attribute, BUILTIN_GROUP_IDM_ADMINS_V1, BUILTIN_GROUP_SYSTEM_ADMINS_V1,
|
||||
IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1,
|
||||
};
|
||||
use tracing::{debug, trace};
|
||||
|
||||
|
@ -53,29 +51,6 @@ async fn test_server_create(rsclient: KanidmClient) {
|
|||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_server_modify(rsclient: KanidmClient) {
|
||||
// Build a self mod.
|
||||
let f = Filter::SelfUuid;
|
||||
let m = ModifyList::new_list(vec![
|
||||
Modify::Purged(Attribute::DisplayName.to_string()),
|
||||
Modify::Present(Attribute::DisplayName.to_string(), "test".to_string()),
|
||||
]);
|
||||
|
||||
// Not logged in - should fail!
|
||||
let res = rsclient.modify(f.clone(), m.clone()).await;
|
||||
assert!(res.is_err());
|
||||
|
||||
let a_res = rsclient
|
||||
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
||||
.await;
|
||||
assert!(a_res.is_ok());
|
||||
|
||||
let res = rsclient.modify(f, m).await;
|
||||
println!("{:?}", res);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_server_whoami_anonymous(rsclient: KanidmClient) {
|
||||
// First show we are un-authenticated.
|
||||
|
@ -181,7 +156,10 @@ async fn test_server_rest_group_lifecycle(rsclient: KanidmClient) {
|
|||
assert!(!g_list.is_empty());
|
||||
|
||||
// Create a new group
|
||||
rsclient.idm_group_create("demo_group").await.unwrap();
|
||||
rsclient
|
||||
.idm_group_create("demo_group", Some(BUILTIN_GROUP_IDM_ADMINS_V1.name))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// List again, ensure one more.
|
||||
let g_list_2 = rsclient.idm_group_list().await.unwrap();
|
||||
|
@ -246,7 +224,13 @@ async fn test_server_rest_group_lifecycle(rsclient: KanidmClient) {
|
|||
.await
|
||||
.unwrap();
|
||||
println!("{:?}", members);
|
||||
assert!(members == Some(vec!["idm_admin@localhost".to_string()]));
|
||||
assert!(
|
||||
members
|
||||
== Some(vec![
|
||||
"admin@localhost".to_string(),
|
||||
"idm_admin@localhost".to_string()
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[kanidmd_testkit::test]
|
||||
|
@ -552,7 +536,10 @@ async fn test_server_rest_posix_lifecycle(rsclient: KanidmClient) {
|
|||
// Create a group
|
||||
|
||||
// Extend the group with posix attrs
|
||||
rsclient.idm_group_create("posix_group").await.unwrap();
|
||||
rsclient
|
||||
.idm_group_create("posix_group", Some(BUILTIN_GROUP_IDM_ADMINS_V1.name))
|
||||
.await
|
||||
.unwrap();
|
||||
rsclient
|
||||
.idm_group_add_members("posix_group", &["posix_account"])
|
||||
.await
|
||||
|
@ -784,67 +771,6 @@ async fn test_server_rest_recycle_lifecycle(rsclient: KanidmClient) {
|
|||
assert!(acc.is_some());
|
||||
}
|
||||
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_server_rest_account_import_password(rsclient: KanidmClient) {
|
||||
let res = rsclient
|
||||
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
||||
.await;
|
||||
assert!(res.is_ok());
|
||||
// To enable the admin to actually make some of these changes, we have
|
||||
// to make them a password import admin. NOT recommended in production!
|
||||
rsclient
|
||||
.idm_group_add_members(IDM_PEOPLE_ACCOUNT_PASSWORD_IMPORT_PRIV_V1.name, &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
rsclient
|
||||
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Create a new person
|
||||
rsclient
|
||||
.idm_person_account_create("demo_account", "Deeeeemo")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Attempt to import a bad password
|
||||
let r = rsclient
|
||||
.idm_person_account_primary_credential_import_password("demo_account", "password")
|
||||
.await;
|
||||
assert!(r.is_err());
|
||||
|
||||
// Import a good password
|
||||
// eicieY7ahchaoCh0eeTa
|
||||
// pbkdf2_sha256$36000$xIEozuZVAoYm$uW1b35DUKyhvQAf1mBqMvoBDcqSD06juzyO/nmyV0+w=
|
||||
rsclient
|
||||
.idm_person_account_primary_credential_import_password(
|
||||
"demo_account",
|
||||
"pbkdf2_sha256$36000$xIEozuZVAoYm$uW1b35DUKyhvQAf1mBqMvoBDcqSD06juzyO/nmyV0+w=",
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Now show we can auth with it
|
||||
// "reset" the client.
|
||||
let _ = rsclient.logout();
|
||||
let res = rsclient
|
||||
.auth_simple_password("demo_account", "eicieY7ahchaoCh0eeTa")
|
||||
.await;
|
||||
assert!(res.is_ok());
|
||||
|
||||
// And that the account can self read the cred status.
|
||||
let cred_state = rsclient
|
||||
.idm_person_account_get_credential_status("demo_account")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
if let Some(cred) = cred_state.creds.get(0) {
|
||||
assert!(cred.type_ == CredentialDetailType::Password)
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[kanidmd_testkit::test]
|
||||
async fn test_server_rest_oauth2_basic_lifecycle(rsclient: KanidmClient) {
|
||||
let res = rsclient
|
||||
|
@ -852,6 +778,11 @@ async fn test_server_rest_oauth2_basic_lifecycle(rsclient: KanidmClient) {
|
|||
.await;
|
||||
assert!(res.is_ok());
|
||||
|
||||
rsclient
|
||||
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// List, there are non.
|
||||
let initial_configs = rsclient
|
||||
.idm_oauth2_rs_list()
|
||||
|
@ -1119,6 +1050,23 @@ async fn test_server_credential_update_session_pw(rsclient: KanidmClient) {
|
|||
.auth_simple_password("demo_account", "eicieY7ahchaoCh0eeTa")
|
||||
.await;
|
||||
assert!(res.is_ok());
|
||||
|
||||
// Get privs
|
||||
let res = rsclient
|
||||
.reauth_simple_password("eicieY7ahchaoCh0eeTa")
|
||||
.await;
|
||||
assert!(res.is_ok());
|
||||
|
||||
// Build a self mod.
|
||||
let f = Filter::SelfUuid;
|
||||
let m = ModifyList::new_list(vec![
|
||||
Modify::Purged(Attribute::DisplayName.to_string()),
|
||||
Modify::Present(Attribute::DisplayName.to_string(), "test".to_string()),
|
||||
]);
|
||||
|
||||
let res = rsclient.modify(f, m).await;
|
||||
println!("{:?}", res);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[kanidmd_testkit::test]
|
||||
|
@ -1341,12 +1289,6 @@ async fn setup_demo_account_password(
|
|||
.await
|
||||
.expect("Failed to authenticate as admin");
|
||||
|
||||
// Not recommended in production!
|
||||
rsclient
|
||||
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
||||
.await
|
||||
.expect("Failed to add admin to idm_admins");
|
||||
|
||||
rsclient
|
||||
.idm_person_account_create("demo_account", "Deeeeemo")
|
||||
.await
|
||||
|
@ -1417,14 +1359,12 @@ async fn test_server_api_token_lifecycle(rsclient: KanidmClient) {
|
|||
|
||||
let test_service_account_username = "test_service";
|
||||
|
||||
// Not recommended in production!
|
||||
rsclient
|
||||
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &[ADMIN_TEST_USER])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
rsclient
|
||||
.idm_service_account_create(test_service_account_username, "Test Service")
|
||||
.idm_service_account_create(
|
||||
test_service_account_username,
|
||||
"Test Service",
|
||||
BUILTIN_GROUP_IDM_ADMINS_V1.name,
|
||||
)
|
||||
.await
|
||||
.expect("Failed to create service account");
|
||||
|
||||
|
@ -1539,7 +1479,7 @@ async fn test_server_api_token_lifecycle(rsclient: KanidmClient) {
|
|||
|
||||
// because you have to set *something*
|
||||
assert!(rsclient
|
||||
.idm_service_account_update(test_service_account_username, None, None, None)
|
||||
.idm_service_account_update(test_service_account_username, None, None, None, None)
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
|
@ -1549,6 +1489,7 @@ async fn test_server_api_token_lifecycle(rsclient: KanidmClient) {
|
|||
test_service_account_username,
|
||||
None,
|
||||
Some(&format!("{}displayzzzz", test_service_account_username)),
|
||||
None,
|
||||
Some(&[format!("{}@example.crabs", test_service_account_username)]),
|
||||
)
|
||||
.await
|
||||
|
@ -1598,12 +1539,6 @@ async fn test_server_user_auth_token_lifecycle(rsclient: KanidmClient) {
|
|||
.await;
|
||||
assert!(res.is_ok());
|
||||
|
||||
// Not recommended in production!
|
||||
rsclient
|
||||
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &[ADMIN_TEST_USER])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
rsclient
|
||||
.idm_person_account_create("demo_account", "Deeeeemo")
|
||||
.await
|
||||
|
|
Binary file not shown.
Binary file not shown.
BIN
server/web_ui/pkg/external/bootstrap.min.css.map.br
vendored
BIN
server/web_ui/pkg/external/bootstrap.min.css.map.br
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -225,7 +225,7 @@ function makeMutClosure(arg0, arg1, dtor, f) {
|
|||
return real;
|
||||
}
|
||||
function __wbg_adapter_48(arg0, arg1) {
|
||||
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h0c62d2840bb83f65(arg0, arg1);
|
||||
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hde72e8f1b6402df0(arg0, arg1);
|
||||
}
|
||||
|
||||
let stack_pointer = 128;
|
||||
|
@ -1141,20 +1141,20 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1150 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 572, __wbg_adapter_48);
|
||||
imports.wbg.__wbindgen_closure_wrapper930 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 527, __wbg_adapter_48);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3558 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1660, __wbg_adapter_51);
|
||||
imports.wbg.__wbindgen_closure_wrapper3569 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1662, __wbg_adapter_51);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3751 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1707, __wbg_adapter_54);
|
||||
imports.wbg.__wbindgen_closure_wrapper3762 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1709, __wbg_adapter_54);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3835 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1738, __wbg_adapter_57);
|
||||
imports.wbg.__wbindgen_closure_wrapper3846 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1740, __wbg_adapter_57);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -384,6 +384,7 @@ impl CredentialResetApp {
|
|||
CUExtPortal::None => html! { <></> },
|
||||
CUExtPortal::Hidden => html! {
|
||||
<>
|
||||
<hr class="my-4" />
|
||||
<p>{ "This account is externally managed. Some features may not be available." }</p>
|
||||
</>
|
||||
},
|
||||
|
@ -391,6 +392,7 @@ impl CredentialResetApp {
|
|||
let url_str = url.as_str().to_string();
|
||||
html! {
|
||||
<>
|
||||
<hr class="my-4" />
|
||||
<p>{ "This account is externally managed. Some features may not be available." }</p>
|
||||
<a href={ url_str } >{ "Visit the external account portal" }</a>
|
||||
</>
|
||||
|
@ -468,7 +470,6 @@ impl CredentialResetApp {
|
|||
|
||||
<div class="row g-3">
|
||||
<form class="needs-validation" novalidate=true>
|
||||
<hr class="my-4" />
|
||||
|
||||
{ ext_cred_portal_html }
|
||||
|
||||
|
@ -738,7 +739,7 @@ impl CredentialResetApp {
|
|||
let cb = self.cb.clone();
|
||||
|
||||
match attested_passkeys_state {
|
||||
CUCredState::Modifiable | CUCredState::DeleteOnly => {
|
||||
CUCredState::Modifiable => {
|
||||
html! {
|
||||
<>
|
||||
<hr class="my-4" />
|
||||
|
@ -756,16 +757,34 @@ impl CredentialResetApp {
|
|||
)
|
||||
}
|
||||
|
||||
{
|
||||
if attested_passkeys_state == CUCredState::Modifiable {
|
||||
html! { <PasskeyModalApp token={ token.clone() } cb={ cb } class={ PasskeyClass::Attested } allowed_devices={ Some(attested_passkeys_allowed_devices.to_vec()) } /> }
|
||||
} else {
|
||||
html! { <></> }
|
||||
}
|
||||
}
|
||||
<PasskeyModalApp token={ token.clone() } cb={ cb } class={ PasskeyClass::Attested } allowed_devices={ Some(attested_passkeys_allowed_devices.to_vec()) } />
|
||||
</>
|
||||
}
|
||||
}
|
||||
CUCredState::DeleteOnly => {
|
||||
if attested_passkeys.is_empty() {
|
||||
html! { <></> }
|
||||
} else {
|
||||
html! {
|
||||
<>
|
||||
<hr class="my-4" />
|
||||
<h4>{"Attested Passkeys"}</h4>
|
||||
|
||||
{ for attested_passkeys.iter()
|
||||
.map(|detail|
|
||||
PasskeyRemoveModalApp::render_button(&detail.tag, detail.uuid)
|
||||
)
|
||||
}
|
||||
{ for attested_passkeys.iter()
|
||||
.map(|detail|
|
||||
html! { <PasskeyRemoveModalApp token={ token.clone() } tag={ detail.tag.clone() } uuid={ detail.uuid } cb={ cb.clone() } class={ PasskeyClass::Attested } /> }
|
||||
)
|
||||
}
|
||||
|
||||
</>
|
||||
}
|
||||
}
|
||||
}
|
||||
CUCredState::AccessDeny | CUCredState::PolicyDeny => {
|
||||
// Don't display anything.
|
||||
html! { <></> }
|
||||
|
|
|
@ -53,7 +53,10 @@ RUN \
|
|||
--target-dir="/usr/src/kanidm/target/" \
|
||||
--features="${KANIDM_FEATURES}" \
|
||||
--release && \
|
||||
cargo install --force fido-mds-tool \
|
||||
cargo install \
|
||||
--git https://github.com/kanidm/webauthn-rs.git \
|
||||
--rev 5f4db4172f8e22aedc68c282d177e98db2b1892f \
|
||||
--force fido-mds-tool \
|
||||
--target-dir="/usr/src/kanidm/target/" && \
|
||||
sccache -s
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ impl GroupOpt {
|
|||
match self {
|
||||
GroupOpt::List(copt) => copt.debug,
|
||||
GroupOpt::Get(gcopt) => gcopt.copt.debug,
|
||||
GroupOpt::Create(gcopt) => gcopt.copt.debug,
|
||||
GroupOpt::SetEntryManagedBy { copt, .. } | GroupOpt::Create { copt, .. } => copt.debug,
|
||||
GroupOpt::Delete(gcopt) => gcopt.copt.debug,
|
||||
GroupOpt::ListMembers(gcopt) => gcopt.copt.debug,
|
||||
GroupOpt::AddMembers(gcopt) => gcopt.copt.debug,
|
||||
|
@ -58,13 +58,20 @@ impl GroupOpt {
|
|||
Err(e) => handle_client_error(e, gcopt.copt.output_mode),
|
||||
}
|
||||
}
|
||||
GroupOpt::Create(gcopt) => {
|
||||
let client = gcopt.copt.to_client(OpType::Write).await;
|
||||
match client.idm_group_create(gcopt.name.as_str()).await {
|
||||
GroupOpt::Create {
|
||||
copt,
|
||||
name,
|
||||
entry_managed_by,
|
||||
} => {
|
||||
let client = copt.to_client(OpType::Write).await;
|
||||
match client
|
||||
.idm_group_create(name.as_str(), entry_managed_by.as_deref())
|
||||
.await
|
||||
{
|
||||
Err(err) => {
|
||||
error!("Error -> {:?}", err)
|
||||
}
|
||||
Ok(_) => println!("Successfully created group '{}'", gcopt.name.as_str()),
|
||||
Ok(_) => println!("Successfully created group '{}'", name.as_str()),
|
||||
}
|
||||
}
|
||||
GroupOpt::Delete(gcopt) => {
|
||||
|
@ -124,7 +131,6 @@ impl GroupOpt {
|
|||
Ok(_) => println!("Successfully removed members from {}", gcopt.name.as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
GroupOpt::SetMembers(gcopt) => {
|
||||
let client = gcopt.copt.to_client(OpType::Write).await;
|
||||
let new_members: Vec<&str> = gcopt.members.iter().map(String::as_str).collect();
|
||||
|
@ -137,6 +143,21 @@ impl GroupOpt {
|
|||
Ok(_) => println!("Successfully set members for group {}", gcopt.name.as_str()),
|
||||
}
|
||||
}
|
||||
GroupOpt::SetEntryManagedBy {
|
||||
name,
|
||||
entry_managed_by,
|
||||
copt,
|
||||
} => {
|
||||
let client = copt.to_client(OpType::Write).await;
|
||||
|
||||
match client
|
||||
.idm_group_set_entry_managed_by(name.as_str(), entry_managed_by.as_str())
|
||||
.await
|
||||
{
|
||||
Err(e) => handle_client_error(e, copt.output_mode),
|
||||
Ok(_) => println!("Successfully set members for group {}", name.as_str()),
|
||||
}
|
||||
}
|
||||
GroupOpt::Posix { commands } => match commands {
|
||||
GroupPosix::Show(gcopt) => {
|
||||
let client = gcopt.copt.to_client(OpType::Read).await;
|
||||
|
|
|
@ -38,7 +38,7 @@ impl ServiceAccountOpt {
|
|||
ServiceAccountOpt::Get(aopt) => aopt.copt.debug,
|
||||
ServiceAccountOpt::Update(aopt) => aopt.copt.debug,
|
||||
ServiceAccountOpt::Delete(aopt) => aopt.copt.debug,
|
||||
ServiceAccountOpt::Create(aopt) => aopt.copt.debug,
|
||||
ServiceAccountOpt::Create { copt, .. } => copt.debug,
|
||||
ServiceAccountOpt::Validity { commands } => match commands {
|
||||
AccountValidity::Show(ano) => ano.copt.debug,
|
||||
AccountValidity::ExpireAt(ano) => ano.copt.debug,
|
||||
|
@ -301,6 +301,7 @@ impl ServiceAccountOpt {
|
|||
aopt.aopts.account_id.as_str(),
|
||||
aopt.newname.as_deref(),
|
||||
aopt.displayname.as_deref(),
|
||||
aopt.entry_managed_by.as_deref(),
|
||||
aopt.mail.as_deref(),
|
||||
)
|
||||
.await
|
||||
|
@ -349,16 +350,22 @@ impl ServiceAccountOpt {
|
|||
}
|
||||
};
|
||||
}
|
||||
ServiceAccountOpt::Create(acopt) => {
|
||||
let client = acopt.copt.to_client(OpType::Write).await;
|
||||
ServiceAccountOpt::Create {
|
||||
aopts,
|
||||
copt,
|
||||
display_name,
|
||||
entry_managed_by,
|
||||
} => {
|
||||
let client = copt.to_client(OpType::Write).await;
|
||||
if let Err(e) = client
|
||||
.idm_service_account_create(
|
||||
acopt.aopts.account_id.as_str(),
|
||||
acopt.display_name.as_str(),
|
||||
aopts.account_id.as_str(),
|
||||
display_name.as_str(),
|
||||
entry_managed_by.as_str(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
handle_client_error(e, acopt.copt.output_mode)
|
||||
handle_client_error(e, copt.output_mode)
|
||||
}
|
||||
}
|
||||
ServiceAccountOpt::Validity { commands } => match commands {
|
||||
|
|
|
@ -209,7 +209,14 @@ pub enum GroupOpt {
|
|||
Get(Named),
|
||||
/// Create a new group
|
||||
#[clap(name = "create")]
|
||||
Create(Named),
|
||||
Create {
|
||||
/// The name of the group
|
||||
name: String,
|
||||
/// Optional name/spn of a group that have entry manager rights over this group.
|
||||
entry_managed_by: Option<String>,
|
||||
#[clap(flatten)]
|
||||
copt: CommonOpt,
|
||||
},
|
||||
/// Delete a group
|
||||
#[clap(name = "delete")]
|
||||
Delete(Named),
|
||||
|
@ -220,6 +227,16 @@ pub enum GroupOpt {
|
|||
/// set operation.
|
||||
#[clap(name = "set-members")]
|
||||
SetMembers(GroupNamedMembers),
|
||||
/// Set a new entry-managed-by for this group.
|
||||
#[clap(name = "set-entry-manager")]
|
||||
SetEntryManagedBy {
|
||||
/// The name of the group
|
||||
name: String,
|
||||
/// Optional name/spn of a group that have entry manager rights over this group.
|
||||
entry_managed_by: String,
|
||||
#[clap(flatten)]
|
||||
copt: CommonOpt,
|
||||
},
|
||||
/// Delete all members of a group.
|
||||
#[clap(name = "purge-members")]
|
||||
PurgeMembers(Named),
|
||||
|
@ -345,7 +362,6 @@ pub enum AccountCredential {
|
|||
#[clap(flatten)]
|
||||
copt: CommonOpt,
|
||||
/// Optionally set how many seconds the reset token should be valid for.
|
||||
#[clap(long = "ttl")]
|
||||
ttl: Option<u32>,
|
||||
},
|
||||
}
|
||||
|
@ -571,6 +587,12 @@ pub struct ServiceAccountUpdateOpt {
|
|||
help = "Set the display name for the service account."
|
||||
)]
|
||||
displayname: Option<String>,
|
||||
#[clap(
|
||||
long,
|
||||
short = 'e',
|
||||
help = "Set the entry manager for the service account."
|
||||
)]
|
||||
entry_managed_by: Option<String>,
|
||||
#[clap(
|
||||
long,
|
||||
short,
|
||||
|
@ -621,7 +643,16 @@ pub enum ServiceAccountOpt {
|
|||
Get(AccountNamedOpt),
|
||||
/// Create a new service account
|
||||
#[clap(name = "create")]
|
||||
Create(AccountCreateOpt),
|
||||
Create {
|
||||
#[clap(flatten)]
|
||||
aopts: AccountCommonOpt,
|
||||
#[clap(name = "display-name")]
|
||||
display_name: String,
|
||||
#[clap(name = "entry-managed-by")]
|
||||
entry_managed_by: String,
|
||||
#[clap(flatten)]
|
||||
copt: CommonOpt,
|
||||
},
|
||||
/// Update a specific service account's attributes
|
||||
#[clap(name = "update")]
|
||||
Update(ServiceAccountUpdateOpt),
|
||||
|
|
|
@ -160,7 +160,7 @@ impl KaniHttpServer {
|
|||
}
|
||||
Entity::Group(g) => {
|
||||
self.client
|
||||
.idm_group_create(&g.name)
|
||||
.idm_group_create(&g.name, None)
|
||||
.await
|
||||
.map(|_| ())
|
||||
.or_else(|e| {
|
||||
|
|
|
@ -158,12 +158,6 @@ async fn test_fixture(rsclient: KanidmClient) {
|
|||
debug!("auth_simple_password res: {:?}", res);
|
||||
trace!("{:?}", &res);
|
||||
assert!(res.is_ok());
|
||||
// Not recommended in production!
|
||||
rsclient
|
||||
.idm_group_add_members("idm_admins", &["admin"])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Create a new account
|
||||
rsclient
|
||||
.idm_person_account_create("testaccount1", "Posix Demo Account")
|
||||
|
@ -188,7 +182,7 @@ async fn test_fixture(rsclient: KanidmClient) {
|
|||
.unwrap();
|
||||
|
||||
// Setup a group
|
||||
rsclient.idm_group_create("testgroup1").await.unwrap();
|
||||
rsclient.idm_group_create("testgroup1", None).await.unwrap();
|
||||
rsclient
|
||||
.idm_group_add_members("testgroup1", &["testaccount1"])
|
||||
.await
|
||||
|
@ -199,14 +193,20 @@ async fn test_fixture(rsclient: KanidmClient) {
|
|||
.unwrap();
|
||||
|
||||
// Setup the allowed group
|
||||
rsclient.idm_group_create("allowed_group").await.unwrap();
|
||||
rsclient
|
||||
.idm_group_create("allowed_group", None)
|
||||
.await
|
||||
.unwrap();
|
||||
rsclient
|
||||
.idm_group_unix_extend("allowed_group", Some(20002))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Setup a group that is masked by nxset, but allowed in overrides
|
||||
rsclient.idm_group_create("masked_group").await.unwrap();
|
||||
rsclient
|
||||
.idm_group_create("masked_group", None)
|
||||
.await
|
||||
.unwrap();
|
||||
rsclient
|
||||
.idm_group_unix_extend("masked_group", Some(20003))
|
||||
.await
|
||||
|
|
Loading…
Reference in a new issue