From 0a0c45fb98845bfda006d192ff2b3c7340c5b75d Mon Sep 17 00:00:00 2001 From: "Adam C. Stephens" Date: Mon, 10 Feb 2025 13:53:31 -0500 Subject: [PATCH 1/2] kanidm_1_5: init at 1.5.0 https://github.com/kanidm/kanidm/releases/tag/v1.5.0 --- pkgs/by-name/ka/kanidm/1_5.nix | 6 + pkgs/by-name/ka/kanidm/README.md | 47 +++ pkgs/by-name/ka/kanidm/generic.nix | 21 +- .../1_5/oauth2-basic-secret-modify.patch | 308 ++++++++++++++++++ .../kanidm/patches/1_5/recover-account.patch | 173 ++++++++++ pkgs/top-level/all-packages.nix | 5 + 6 files changed, 559 insertions(+), 1 deletion(-) create mode 100644 pkgs/by-name/ka/kanidm/1_5.nix create mode 100644 pkgs/by-name/ka/kanidm/README.md create mode 100644 pkgs/by-name/ka/kanidm/patches/1_5/oauth2-basic-secret-modify.patch create mode 100644 pkgs/by-name/ka/kanidm/patches/1_5/recover-account.patch diff --git a/pkgs/by-name/ka/kanidm/1_5.nix b/pkgs/by-name/ka/kanidm/1_5.nix new file mode 100644 index 000000000000..93afad5ee0f8 --- /dev/null +++ b/pkgs/by-name/ka/kanidm/1_5.nix @@ -0,0 +1,6 @@ +import ./generic.nix { + version = "1.5.0"; + hash = "sha256-swrqyjA7Wgq17vd+753LDFcXrSFixVNLhTvj1bhG3DU="; + cargoHash = "sha256-72IwS8Nk1y6xDH9y8JW2LpbhFWaq0tpORx7JQSCF5/M="; + patchDir = ./patches/1_5; +} diff --git a/pkgs/by-name/ka/kanidm/README.md b/pkgs/by-name/ka/kanidm/README.md new file mode 100644 index 000000000000..34a354596218 --- /dev/null +++ b/pkgs/by-name/ka/kanidm/README.md @@ -0,0 +1,47 @@ +# Kanidm release guide + +Kanidm supports one release at any given time, with a 30-day overlap to allow for upgrades from old to new version. +Version upgrades are only supported on adjacent releases, with no support for jumping versions. + +To ensure we provide sufficient coverage for upgrading, we will aim to have two or three releases in tree at any given time. +Unsupported versions will be marked as vulnerable (lacking an "unsupported" mechanism), but built by hydra to avoid pushing the very large rebuild on users. + +The default version will be updated with each new version, but the default will not be backported. +It is expected that stable users will have to manually specify the version, and update that version, throughout the lifecycle of a NixOS release. + +## New release + +For example, when upgrading from 1.4 -> 1.5 + +### Init new version + +1. `cp pkgs/by-name/ka/kanidm/1_4.nix pkgs/by-name/ka/kanidm/1_5.nix` +1. `cp -r pkgs/by-name/ka/kanidm/patches/1_4 pkgs/by-name/ka/kanidm/patches/1_5` +1. Update `1_5.nix` hashes/paths, and as needed for upstream changes, `generic.nix` +1. Update `all-packages.nix` to add `kanidm_1_5` and `kanidmWithSecretProvisioning_1_5`, leave default +1. Create commit, `kanidm_1_5: init at 1.5.0` - this is the only commit that will be backported + +### Mark previous version deprecated + +1. Update `pkgs/by-name/ka/kanidm/1_4.nix` by adding `deprecated = true;` +1. Create commit `kanidm_1_4: update default to 1.5.0, deprecate 1.4.0` + +### Update default and mark deprecation + +1. `sed -i 's/1_4/1_5/' pkgs/by-name/ka/kanidm/package.nix` +1. Update `all-packages.nix` and set `kanidmWithSecretProvisioning = kanidmWithSecretProvisioning_1_5;` +1. Create commit `kanidm: update default to 1.5.0` + +### Backport to stable + +1. Manually create a backport using _only_ the init commit + +## Remove release + +Kanidm versions are supported for 30 days after the release of new versions. Following the example above, 1.5.x superseding 1.4.x in 30 days, do the following near the end of the 30 day window + +1. Update `pkgs/top-level/release.nix` and add `kanidm_1_4-1.4.6` to `permittedInsecurePackages` +1. Update `pkgs/top-level/release.nix` and remove `kanidm_1_3-1.3.3` from `permittedInsecurePackages` +1. Remove the third oldest release from `all-packages.nix`, e.g. 1.3.x continuing the example. Remove `kanidm_1_3` and `kanidmWithSecretProvisioning_1_3` +1. Update `pkgs/by-name/ka/kanidm/1_4.nix` by adding `unsupported = true;` +1. Open a PR and backport it to stable diff --git a/pkgs/by-name/ka/kanidm/generic.nix b/pkgs/by-name/ka/kanidm/generic.nix index 8512f1fc357c..ddaaba190fff 100644 --- a/pkgs/by-name/ka/kanidm/generic.nix +++ b/pkgs/by-name/ka/kanidm/generic.nix @@ -4,6 +4,7 @@ cargoHash, patchDir, extraMeta ? { }, + unsupported ? false, }: { @@ -60,8 +61,18 @@ rustPlatform.buildRustPackage rec { format = (formats.toml { }).generate "${KANIDM_BUILD_PROFILE}.toml"; profile = { - admin_bind_path = "/run/kanidmd/sock"; cpu_flags = if stdenv.hostPlatform.isx86_64 then "x86_64_legacy" else "none"; + } + // lib.optionalAttrs (lib.versionAtLeast version "1.5") { + client_config_path = "/etc/kanidm/config"; + resolver_config_path = "/etc/kanidm/unixd"; + resolver_unix_shell_path = "${lib.getBin bashInteractive}/bin/bash"; + server_admin_bind_path = "/run/kanidmd/sock"; + server_config_path = "/etc/kanidm/server.toml"; + server_ui_pkg_path = "@htmx_ui_pkg_path@"; + } + // lib.optionalAttrs (lib.versionOlder version "1.5") { + admin_bind_path = "/run/kanidmd/sock"; default_config_path = "/etc/kanidm/server.toml"; default_unix_shell_path = "${lib.getBin bashInteractive}/bin/bash"; htmx_ui_pkg_path = "@htmx_ui_pkg_path@"; @@ -160,6 +171,14 @@ rustPlatform.buildRustPackage rec { adamcstephens Flakebi ]; + knownVulnerabilities = lib.optionals unsupported [ + '' + kanidm ${version} has reached EOL. + + Please upgrade by verifying `kanidmd domain upgrade-check` and choosing the next version with `services.kanidm.package = pkgs.kanidm_1_x;` + See upgrade guide at https://kanidm.github.io/kanidm/master/server_updates.html + '' + ]; } // extraMeta; } diff --git a/pkgs/by-name/ka/kanidm/patches/1_5/oauth2-basic-secret-modify.patch b/pkgs/by-name/ka/kanidm/patches/1_5/oauth2-basic-secret-modify.patch new file mode 100644 index 000000000000..80bd4c16bd9b --- /dev/null +++ b/pkgs/by-name/ka/kanidm/patches/1_5/oauth2-basic-secret-modify.patch @@ -0,0 +1,308 @@ +From e9dfca73e6fb80faf6fc106e7aee6b93c0908525 Mon Sep 17 00:00:00 2001 +From: oddlama +Date: Fri, 1 Nov 2024 12:26:17 +0100 +Subject: [PATCH 1/2] oauth2 basic secret modify + +--- + server/core/src/actors/v1_write.rs | 42 ++++++++++++++++++++++++++++++ + server/core/src/https/v1.rs | 6 ++++- + server/core/src/https/v1_oauth2.rs | 29 +++++++++++++++++++++ + server/lib/src/constants/acp.rs | 6 +++++ + 4 files changed, 82 insertions(+), 1 deletion(-) + +diff --git a/server/core/src/actors/v1_write.rs b/server/core/src/actors/v1_write.rs +index 732e826c8..0fe66503f 100644 +--- a/server/core/src/actors/v1_write.rs ++++ b/server/core/src/actors/v1_write.rs +@@ -317,20 +317,62 @@ impl QueryServerWriteV1 { + }; + + trace!(?del, "Begin delete event"); + + idms_prox_write + .qs_write + .delete(&del) + .and_then(|_| idms_prox_write.commit().map(|_| ())) + } + ++ #[instrument( ++ level = "info", ++ skip_all, ++ fields(uuid = ?eventid) ++ )] ++ pub async fn handle_oauth2_basic_secret_write( ++ &self, ++ client_auth_info: ClientAuthInfo, ++ filter: Filter, ++ new_secret: String, ++ eventid: Uuid, ++ ) -> Result<(), OperationError> { ++ // Given a protoEntry, turn this into a modification set. ++ let ct = duration_from_epoch_now(); ++ let mut idms_prox_write = self.idms.proxy_write(ct).await?; ++ let ident = idms_prox_write ++ .validate_client_auth_info_to_ident(client_auth_info, ct) ++ .map_err(|e| { ++ admin_error!(err = ?e, "Invalid identity"); ++ e ++ })?; ++ ++ let modlist = ModifyList::new_purge_and_set( ++ Attribute::OAuth2RsBasicSecret, ++ Value::SecretValue(new_secret), ++ ); ++ ++ let mdf = ++ ModifyEvent::from_internal_parts(ident, &modlist, &filter, &idms_prox_write.qs_write) ++ .map_err(|e| { ++ admin_error!(err = ?e, "Failed to begin modify during handle_oauth2_basic_secret_write"); ++ e ++ })?; ++ ++ trace!(?mdf, "Begin modify event"); ++ ++ idms_prox_write ++ .qs_write ++ .modify(&mdf) ++ .and_then(|_| idms_prox_write.commit()) ++ } ++ + #[instrument( + level = "info", + skip_all, + fields(uuid = ?eventid) + )] + pub async fn handle_reviverecycled( + &self, + client_auth_info: ClientAuthInfo, + filter: Filter, + eventid: Uuid, +diff --git a/server/core/src/https/v1.rs b/server/core/src/https/v1.rs +index c410a4b5d..cc67cac6c 100644 +--- a/server/core/src/https/v1.rs ++++ b/server/core/src/https/v1.rs +@@ -1,17 +1,17 @@ + //! The V1 API things! + + use axum::extract::{Path, State}; + use axum::http::{HeaderMap, HeaderValue}; + use axum::middleware::from_fn; + use axum::response::{IntoResponse, Response}; +-use axum::routing::{delete, get, post, put}; ++use axum::routing::{delete, get, post, put, patch}; + use axum::{Extension, Json, Router}; + use axum_extra::extract::cookie::{Cookie, CookieJar, SameSite}; + use compact_jwt::{Jwk, Jws, JwsSigner}; + use kanidm_proto::constants::uri::V1_AUTH_VALID; + use std::net::IpAddr; + use uuid::Uuid; + + use kanidm_proto::internal::{ + ApiToken, AppLink, CUIntentToken, CURequest, CUSessionToken, CUStatus, CreateRequest, + CredentialStatus, DeleteRequest, IdentifyUserRequest, IdentifyUserResponse, ModifyRequest, +@@ -3120,20 +3120,24 @@ pub(crate) fn route_setup(state: ServerState) -> Router { + ) + .route( + "/v1/oauth2/:rs_name/_image", + post(super::v1_oauth2::oauth2_id_image_post) + .delete(super::v1_oauth2::oauth2_id_image_delete), + ) + .route( + "/v1/oauth2/:rs_name/_basic_secret", + get(super::v1_oauth2::oauth2_id_get_basic_secret), + ) ++ .route( ++ "/v1/oauth2/:rs_name/_basic_secret", ++ patch(super::v1_oauth2::oauth2_id_patch_basic_secret), ++ ) + .route( + "/v1/oauth2/:rs_name/_scopemap/:group", + post(super::v1_oauth2::oauth2_id_scopemap_post) + .delete(super::v1_oauth2::oauth2_id_scopemap_delete), + ) + .route( + "/v1/oauth2/:rs_name/_sup_scopemap/:group", + post(super::v1_oauth2::oauth2_id_sup_scopemap_post) + .delete(super::v1_oauth2::oauth2_id_sup_scopemap_delete), + ) +diff --git a/server/core/src/https/v1_oauth2.rs b/server/core/src/https/v1_oauth2.rs +index d3966a7ad..f89c02c69 100644 +--- a/server/core/src/https/v1_oauth2.rs ++++ b/server/core/src/https/v1_oauth2.rs +@@ -144,20 +144,49 @@ pub(crate) async fn oauth2_id_get_basic_secret( + ) -> Result>, WebError> { + let filter = oauth2_id(&rs_name); + state + .qe_r_ref + .handle_oauth2_basic_secret_read(client_auth_info, filter, kopid.eventid) + .await + .map(Json::from) + .map_err(WebError::from) + } + ++#[utoipa::path( ++ patch, ++ path = "/v1/oauth2/{rs_name}/_basic_secret", ++ request_body=ProtoEntry, ++ responses( ++ DefaultApiResponse, ++ ), ++ security(("token_jwt" = [])), ++ tag = "v1/oauth2", ++ operation_id = "oauth2_id_patch_basic_secret" ++)] ++/// Overwrite the basic secret for a given OAuth2 Resource Server. ++#[instrument(level = "info", skip(state, new_secret))] ++pub(crate) async fn oauth2_id_patch_basic_secret( ++ State(state): State, ++ Extension(kopid): Extension, ++ VerifiedClientInformation(client_auth_info): VerifiedClientInformation, ++ Path(rs_name): Path, ++ Json(new_secret): Json, ++) -> Result, WebError> { ++ let filter = oauth2_id(&rs_name); ++ state ++ .qe_w_ref ++ .handle_oauth2_basic_secret_write(client_auth_info, filter, new_secret, kopid.eventid) ++ .await ++ .map(Json::from) ++ .map_err(WebError::from) ++} ++ + #[utoipa::path( + patch, + path = "/v1/oauth2/{rs_name}", + request_body=ProtoEntry, + responses( + DefaultApiResponse, + ), + security(("token_jwt" = [])), + tag = "v1/oauth2", + operation_id = "oauth2_id_patch" +diff --git a/server/lib/src/constants/acp.rs b/server/lib/src/constants/acp.rs +index be1836345..ebf4445be 100644 +--- a/server/lib/src/constants/acp.rs ++++ b/server/lib/src/constants/acp.rs +@@ -658,36 +658,38 @@ lazy_static! { + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, ++ Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, ++ Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::OAuth2ResourceServer, +@@ -759,37 +761,39 @@ lazy_static! { + Attribute::Image, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, ++ Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Name, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, ++ Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + ], + create_classes: vec![ + EntryClass::Object, + EntryClass::Account, +@@ -864,38 +868,40 @@ lazy_static! { + Attribute::OAuth2StrictRedirectUri, + ], + modify_present_attrs: vec![ + Attribute::Description, + Attribute::DisplayName, + Attribute::Name, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, ++ Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + create_attrs: vec![ + Attribute::Class, + Attribute::Description, + Attribute::Name, + Attribute::DisplayName, + Attribute::OAuth2RsName, + Attribute::OAuth2RsOrigin, + Attribute::OAuth2RsOriginLanding, + Attribute::OAuth2RsSupScopeMap, + Attribute::OAuth2RsScopeMap, ++ Attribute::OAuth2RsBasicSecret, + Attribute::OAuth2AllowInsecureClientDisablePkce, + Attribute::OAuth2JwtLegacyCryptoEnable, + Attribute::OAuth2PreferShortUsername, + Attribute::OAuth2AllowLocalhostRedirect, + Attribute::OAuth2RsClaimMap, + Attribute::Image, + Attribute::OAuth2StrictRedirectUri, + ], + create_classes: vec![ + EntryClass::Object, +-- +2.46.1 + diff --git a/pkgs/by-name/ka/kanidm/patches/1_5/recover-account.patch b/pkgs/by-name/ka/kanidm/patches/1_5/recover-account.patch new file mode 100644 index 000000000000..1ec61301f036 --- /dev/null +++ b/pkgs/by-name/ka/kanidm/patches/1_5/recover-account.patch @@ -0,0 +1,173 @@ +From c8ed69efe3f702b19834c2659be1dd3ec2d41c17 Mon Sep 17 00:00:00 2001 +From: oddlama +Date: Fri, 1 Nov 2024 12:27:43 +0100 +Subject: [PATCH 2/2] recover account + +--- + server/core/src/actors/internal.rs | 3 ++- + server/core/src/admin.rs | 6 +++--- + server/daemon/src/main.rs | 14 +++++++++++++- + server/daemon/src/opt.rs | 4 ++++ + 4 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/server/core/src/actors/internal.rs b/server/core/src/actors/internal.rs +index 420e72c6c..5c4353116 100644 +--- a/server/core/src/actors/internal.rs ++++ b/server/core/src/actors/internal.rs +@@ -171,25 +171,26 @@ impl QueryServerWriteV1 { + } + + #[instrument( + level = "info", + skip(self, eventid), + fields(uuid = ?eventid) + )] + pub(crate) async fn handle_admin_recover_account( + &self, + name: String, ++ password: Option, + eventid: Uuid, + ) -> Result { + let ct = duration_from_epoch_now(); + let mut idms_prox_write = self.idms.proxy_write(ct).await?; +- let pw = idms_prox_write.recover_account(name.as_str(), None)?; ++ let pw = idms_prox_write.recover_account(name.as_str(), password.as_deref())?; + + idms_prox_write.commit().map(|()| pw) + } + + #[instrument( + level = "info", + skip_all, + fields(uuid = ?eventid) + )] + pub(crate) async fn handle_domain_raise(&self, eventid: Uuid) -> Result { +diff --git a/server/core/src/admin.rs b/server/core/src/admin.rs +index 90ccb1927..85e31ddef 100644 +--- a/server/core/src/admin.rs ++++ b/server/core/src/admin.rs +@@ -17,21 +17,21 @@ use tokio_util::codec::{Decoder, Encoder, Framed}; + use tracing::{span, Instrument, Level}; + use uuid::Uuid; + + pub use kanidm_proto::internal::{ + DomainInfo as ProtoDomainInfo, DomainUpgradeCheckReport as ProtoDomainUpgradeCheckReport, + DomainUpgradeCheckStatus as ProtoDomainUpgradeCheckStatus, + }; + + #[derive(Serialize, Deserialize, Debug)] + pub enum AdminTaskRequest { +- RecoverAccount { name: String }, ++ RecoverAccount { name: String, password: Option }, + ShowReplicationCertificate, + RenewReplicationCertificate, + RefreshReplicationConsumer, + DomainShow, + DomainUpgradeCheck, + DomainRaise, + DomainRemigrate { level: Option }, + } + + #[derive(Serialize, Deserialize, Debug)] +@@ -302,22 +302,22 @@ async fn handle_client( + let mut reqs = Framed::new(sock, ServerCodec); + + trace!("Waiting for requests ..."); + while let Some(Ok(req)) = reqs.next().await { + // Setup the logging span + let eventid = Uuid::new_v4(); + let nspan = span!(Level::INFO, "handle_admin_client_request", uuid = ?eventid); + + let resp = async { + match req { +- AdminTaskRequest::RecoverAccount { name } => { +- match server_rw.handle_admin_recover_account(name, eventid).await { ++ AdminTaskRequest::RecoverAccount { name, password } => { ++ match server_rw.handle_admin_recover_account(name, password, eventid).await { + Ok(password) => AdminTaskResponse::RecoverAccount { password }, + Err(e) => { + error!(err = ?e, "error during recover-account"); + AdminTaskResponse::Error + } + } + } + AdminTaskRequest::ShowReplicationCertificate => match repl_ctrl_tx.as_mut() { + Some(ctrl_tx) => show_replication_certificate(ctrl_tx).await, + None => { +diff --git a/server/daemon/src/main.rs b/server/daemon/src/main.rs +index 7486d34a8..784106352 100644 +--- a/server/daemon/src/main.rs ++++ b/server/daemon/src/main.rs +@@ -903,27 +903,39 @@ async fn kanidm_main( + } else { + let output_mode: ConsoleOutputMode = commonopts.output_mode.to_owned().into(); + submit_admin_req( + config.adminbindpath.as_str(), + AdminTaskRequest::RefreshReplicationConsumer, + output_mode, + ) + .await; + } + } +- KanidmdOpt::RecoverAccount { name, commonopts } => { ++ KanidmdOpt::RecoverAccount { name, from_environment, commonopts } => { + info!("Running account recovery ..."); + let output_mode: ConsoleOutputMode = commonopts.output_mode.to_owned().into(); ++ let password = if *from_environment { ++ match std::env::var("KANIDM_RECOVER_ACCOUNT_PASSWORD") { ++ Ok(val) => Some(val), ++ _ => { ++ error!("Environment variable KANIDM_RECOVER_ACCOUNT_PASSWORD not set"); ++ return ExitCode::FAILURE; ++ } ++ } ++ } else { ++ None ++ }; + submit_admin_req( + config.adminbindpath.as_str(), + AdminTaskRequest::RecoverAccount { + name: name.to_owned(), ++ password, + }, + output_mode, + ) + .await; + } + KanidmdOpt::Database { + commands: DbCommands::Reindex(_copt), + } => { + info!("Running in reindex mode ..."); + reindex_server_core(&config).await; +diff --git a/server/daemon/src/opt.rs b/server/daemon/src/opt.rs +index f1b45a5b3..9c013e32e 100644 +--- a/server/daemon/src/opt.rs ++++ b/server/daemon/src/opt.rs +@@ -229,20 +229,24 @@ enum KanidmdOpt { + /// Create a self-signed ca and tls certificate in the locations listed from the + /// configuration. These certificates should *not* be used in production, they + /// are for testing and evaluation only! + CertGenerate(CommonOpt), + #[clap(name = "recover-account")] + /// Recover an account's password + RecoverAccount { + #[clap(value_parser)] + /// The account name to recover credentials for. + name: String, ++ /// Use the password given in the environment variable ++ /// `KANIDM_RECOVER_ACCOUNT_PASSWORD` instead of generating one. ++ #[clap(long = "from-environment")] ++ from_environment: bool, + #[clap(flatten)] + commonopts: CommonOpt, + }, + /// Display this server's replication certificate + ShowReplicationCertificate { + #[clap(flatten)] + commonopts: CommonOpt, + }, + /// Renew this server's replication certificate + RenewReplicationCertificate { +-- +2.46.1 + diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 0a58cf1edb0c..ba7e68c24a95 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -11376,6 +11376,7 @@ with pkgs; kanidm_1_3 = callPackage ../by-name/ka/kanidm/1_3.nix { }; kanidm_1_4 = callPackage ../by-name/ka/kanidm/1_4.nix { }; + kanidm_1_5 = callPackage ../by-name/ka/kanidm/1_5.nix { }; kanidmWithSecretProvisioning = kanidmWithSecretProvisioning_1_4; @@ -11387,6 +11388,10 @@ with pkgs; enableSecretProvisioning = true; }; + kanidmWithSecretProvisioning_1_5 = callPackage ../by-name/ka/kanidm/1_5.nix { + enableSecretProvisioning = true; + }; + knot-resolver = callPackage ../servers/dns/knot-resolver { systemd = systemdMinimal; # in closure already anyway }; From 1db4d963aab2230697d944a2c7d2efcca1a78689 Mon Sep 17 00:00:00 2001 From: "Adam C. Stephens" Date: Mon, 10 Feb 2025 15:14:46 -0500 Subject: [PATCH 2/2] kanidm: update default to 1.5.0 --- pkgs/by-name/ka/kanidm/package.nix | 2 +- pkgs/top-level/all-packages.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/ka/kanidm/package.nix b/pkgs/by-name/ka/kanidm/package.nix index a7bf92b6be6d..0b9178b3d6a7 100644 --- a/pkgs/by-name/ka/kanidm/package.nix +++ b/pkgs/by-name/ka/kanidm/package.nix @@ -1 +1 @@ -import ./1_4.nix +import ./1_5.nix diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index ba7e68c24a95..176f52d2aa03 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -11378,7 +11378,7 @@ with pkgs; kanidm_1_4 = callPackage ../by-name/ka/kanidm/1_4.nix { }; kanidm_1_5 = callPackage ../by-name/ka/kanidm/1_5.nix { }; - kanidmWithSecretProvisioning = kanidmWithSecretProvisioning_1_4; + kanidmWithSecretProvisioning = kanidmWithSecretProvisioning_1_5; kanidmWithSecretProvisioning_1_3 = callPackage ../by-name/ka/kanidm/1_3.nix { enableSecretProvisioning = true;