From: Christoph Heiss <c.heiss@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup v2 09/15] realm sync: add sync job for AD realms
Date: Wed, 16 Aug 2023 16:47:39 +0200 [thread overview]
Message-ID: <20230816144746.1265108-10-c.heiss@proxmox.com> (raw)
In-Reply-To: <20230816144746.1265108-1-c.heiss@proxmox.com>
Basically just a thin wrapper over the existing LDAP-based realm sync
job, which retrieves the appropriate config and sets the correct user
attributes.
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Changes v1 -> v2:
* Implement `Display` + `FromStr` for `RealmType` using the
serde_plain crate by deriving them. Previously a separate patch, but
now folded into this as it was reduced to a two-liner due to this
change.
* Fix clippy deref warning
pbs-api-types/src/lib.rs | 5 +++
src/api2/access/domain.rs | 18 ++++++++--
src/server/realm_sync_job.rs | 69 ++++++++++++++++++++++++++++++++----
3 files changed, 84 insertions(+), 8 deletions(-)
diff --git a/pbs-api-types/src/lib.rs b/pbs-api-types/src/lib.rs
index d2bce842..b1ac3c9d 100644
--- a/pbs-api-types/src/lib.rs
+++ b/pbs-api-types/src/lib.rs
@@ -509,8 +509,13 @@ pub enum RealmType {
OpenId,
/// An LDAP realm
Ldap,
+ /// An Active Directory (AD) realm
+ Ad,
}
+serde_plain::derive_display_from_serialize!(RealmType);
+serde_plain::derive_fromstr_from_deserialize!(RealmType);
+
#[api(
properties: {
realm: {
diff --git a/src/api2/access/domain.rs b/src/api2/access/domain.rs
index 31aa62bc..8f8eebda 100644
--- a/src/api2/access/domain.rs
+++ b/src/api2/access/domain.rs
@@ -1,13 +1,14 @@
//! List Authentication domains/realms
-use anyhow::{format_err, Error};
+use anyhow::{bail, format_err, Error};
use serde_json::{json, Value};
use proxmox_router::{Permission, Router, RpcEnvironment, RpcEnvironmentType, SubdirMap};
use proxmox_schema::api;
use pbs_api_types::{
- Authid, BasicRealmInfo, Realm, PRIV_PERMISSIONS_MODIFY, REMOVE_VANISHED_SCHEMA, UPID_SCHEMA,
+ Authid, BasicRealmInfo, Realm, RealmRef, RealmType, PRIV_PERMISSIONS_MODIFY,
+ REMOVE_VANISHED_SCHEMA, UPID_SCHEMA,
};
use crate::server::jobstate::Job;
@@ -102,6 +103,7 @@ pub fn sync_realm(
let upid_str = crate::server::do_realm_sync_job(
job,
realm.clone(),
+ realm_type_from_name(&realm)?,
&auth_id,
None,
to_stdout,
@@ -120,6 +122,18 @@ pub fn sync_realm(
Ok(json!(upid_str))
}
+fn realm_type_from_name(realm: &RealmRef) -> Result<RealmType, Error> {
+ let config = pbs_config::domains::config()?.0;
+
+ for (name, (section_type, _)) in config.sections.iter() {
+ if name == realm.as_str() {
+ return Ok(section_type.parse()?);
+ }
+ }
+
+ bail!("unable to find realm {realm}")
+}
+
const SYNC_ROUTER: Router = Router::new().post(&API_METHOD_SYNC_REALM);
const SYNC_SUBDIRS: SubdirMap = &[("sync", &SYNC_ROUTER)];
diff --git a/src/server/realm_sync_job.rs b/src/server/realm_sync_job.rs
index 5a7bcf0b..de8124d7 100644
--- a/src/server/realm_sync_job.rs
+++ b/src/server/realm_sync_job.rs
@@ -10,9 +10,9 @@ use proxmox_sys::{task_log, task_warn};
use std::{collections::HashSet, sync::Arc};
use pbs_api_types::{
- ApiToken, Authid, LdapRealmConfig, Realm, RemoveVanished, SyncAttributes as LdapSyncAttributes,
- SyncDefaultsOptions, User, Userid, EMAIL_SCHEMA, FIRST_NAME_SCHEMA, LAST_NAME_SCHEMA,
- REMOVE_VANISHED_ARRAY, USER_CLASSES_ARRAY,
+ AdRealmConfig, ApiToken, Authid, LdapRealmConfig, Realm, RealmType, RemoveVanished,
+ SyncAttributes as LdapSyncAttributes, SyncDefaultsOptions, User, Userid, EMAIL_SCHEMA,
+ FIRST_NAME_SCHEMA, LAST_NAME_SCHEMA, REMOVE_VANISHED_ARRAY, USER_CLASSES_ARRAY,
};
use crate::{auth, server::jobstate::Job};
@@ -22,6 +22,7 @@ use crate::{auth, server::jobstate::Job};
pub fn do_realm_sync_job(
mut job: Job,
realm: Realm,
+ realm_type: RealmType,
auth_id: &Authid,
_schedule: Option<String>,
to_stdout: bool,
@@ -46,8 +47,19 @@ pub fn do_realm_sync_job(
};
async move {
- let sync_job = LdapRealmSyncJob::new(worker, realm, &override_settings, dry_run)?;
- sync_job.sync().await
+ match realm_type {
+ RealmType::Ldap => {
+ LdapRealmSyncJob::new(worker, realm, &override_settings, dry_run)?
+ .sync()
+ .await
+ }
+ RealmType::Ad => {
+ AdRealmSyncJob::new(worker, realm, &override_settings, dry_run)?
+ .sync()
+ .await
+ }
+ _ => bail!("cannot sync realm {realm} of type {realm_type}"),
+ }
}
},
)?;
@@ -55,6 +67,51 @@ pub fn do_realm_sync_job(
Ok(upid_str)
}
+/// Implementation for syncing Active Directory realms. Merely a thin wrapper over
+/// `LdapRealmSyncJob`, as AD is just LDAP with some special requirements.
+struct AdRealmSyncJob(LdapRealmSyncJob);
+
+impl AdRealmSyncJob {
+ fn new(
+ worker: Arc<WorkerTask>,
+ realm: Realm,
+ override_settings: &GeneralSyncSettingsOverride,
+ dry_run: bool,
+ ) -> Result<Self, Error> {
+ let (domains, _digest) = pbs_config::domains::config()?;
+ let config = if let Ok(config) = domains.lookup::<AdRealmConfig>("ad", realm.as_str()) {
+ config
+ } else {
+ bail!("unknown Active Directory realm '{}'", realm.as_str());
+ };
+
+ let sync_settings = GeneralSyncSettings::default()
+ .apply_config(config.sync_defaults_options.as_deref())?
+ .apply_override(override_settings)?;
+ let sync_attributes = LdapSyncSettings::new(
+ "sAMAccountName",
+ config.sync_attributes.as_deref(),
+ config.user_classes.as_deref(),
+ config.filter.as_deref(),
+ )?;
+
+ let ldap_config = auth::AdAuthenticator::api_type_to_config(&config)?;
+
+ Ok(Self(LdapRealmSyncJob {
+ worker,
+ realm,
+ general_sync_settings: sync_settings,
+ ldap_sync_settings: sync_attributes,
+ ldap_config,
+ dry_run,
+ }))
+ }
+
+ async fn sync(&self) -> Result<(), Error> {
+ self.0.sync().await
+ }
+}
+
/// Implemenation for syncing LDAP realms
struct LdapRealmSyncJob {
worker: Arc<WorkerTask>,
@@ -77,7 +134,7 @@ impl LdapRealmSyncJob {
let config = if let Ok(config) = domains.lookup::<LdapRealmConfig>("ldap", realm.as_str()) {
config
} else {
- bail!("unknown realm '{}'", realm.as_str());
+ bail!("unknown LDAP realm '{}'", realm.as_str());
};
let sync_settings = GeneralSyncSettings::default()
--
2.41.0
next prev parent reply other threads:[~2023-08-16 14:49 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-16 14:47 [pbs-devel] [PATCH proxmox/proxmox-backup/pwt v2 0/15] add Active Directory realm support Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox v2 01/15] ldap: avoid superfluous allocation when calling .search() Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox v2 02/15] ldap: add method for retrieving root DSE attributes Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox v2 03/15] auth-api: implement `Display` for `Realm{, Ref}` Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox-backup v2 04/15] api-types: factor out `LdapMode` -> `ConnectionMode` conversion into own fn Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox-backup v2 05/15] auth: factor out CA store and cert lookup " Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox-backup v2 06/15] realm sync: generic-ify `LdapSyncSettings` and `GeneralSyncSettings` Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox-backup v2 07/15] api: access: add routes for managing AD realms Christoph Heiss
2023-11-28 8:23 ` Fabian Grünbichler
2023-12-12 12:19 ` Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox-backup v2 08/15] config: domains: add new "ad" section type for " Christoph Heiss
2023-08-16 14:47 ` Christoph Heiss [this message]
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox-backup v2 10/15] manager: add subcommand for managing " Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox-backup v2 11/15] docs: user-management: add section about AD realm support Christoph Heiss
2023-11-28 8:33 ` Fabian Grünbichler
2023-12-12 12:20 ` Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [PATCH proxmox-widget-toolkit v2 12/15] window: add Active Directory auth panel Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [RFC PATCH proxmox v2 13/15] section-config: add method to retrieve case-insensitive entries Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [RFC PATCH proxmox-backup v2 14/15] api: add case-insensitive support for Active Directory realms Christoph Heiss
2023-11-27 9:57 ` Lukas Wagner
2023-12-12 12:19 ` Christoph Heiss
2023-08-16 14:47 ` [pbs-devel] [RFC PATCH proxmox-widget-toolkit v2 15/15] window: ldap auth edit: add case-sensitive checkbox for AD realms Christoph Heiss
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230816144746.1265108-10-c.heiss@proxmox.com \
--to=c.heiss@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.