From: Christoph Heiss <c.heiss@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup 09/12] realm sync: add sync job for AD realms
Date: Tue, 8 Aug 2023 14:22:11 +0200 [thread overview]
Message-ID: <20230808122239.1025524-10-c.heiss@proxmox.com> (raw)
In-Reply-To: <20230808122239.1025524-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>
---
pbs-api-types/src/lib.rs | 4 +++
src/api2/access/domain.rs | 16 ++++++++-
src/server/realm_sync_job.rs | 69 ++++++++++++++++++++++++++++++++----
3 files changed, 82 insertions(+), 7 deletions(-)
diff --git a/pbs-api-types/src/lib.rs b/pbs-api-types/src/lib.rs
index c622484e..3f86803f 100644
--- a/pbs-api-types/src/lib.rs
+++ b/pbs-api-types/src/lib.rs
@@ -513,6 +513,8 @@ pub enum RealmType {
OpenId,
/// An LDAP realm
Ldap,
+ /// An Active Directory (AD) realm
+ Ad,
}
impl fmt::Display for RealmType {
@@ -523,6 +525,7 @@ impl fmt::Display for RealmType {
Pbs => write!(f, "PBS"),
OpenId => write!(f, "OpenID"),
Ldap => write!(f, "LDAP"),
+ Ad => write!(f, "AD"),
}
}
}
@@ -537,6 +540,7 @@ impl std::str::FromStr for RealmType {
"pbs" => Ok(Pbs),
"openid" => Ok(OpenId),
"ldap" => Ok(Ldap),
+ "ad" => Ok(Ad),
_ => Err(format_err!("unknown realm type {realm_type}")),
}
}
diff --git a/src/api2/access/domain.rs b/src/api2/access/domain.rs
index 31aa62bc..027597fa 100644
--- a/src/api2/access/domain.rs
+++ b/src/api2/access/domain.rs
@@ -7,7 +7,8 @@ use proxmox_router::{Permission, Router, RpcEnvironment, RpcEnvironmentType, Sub
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 section_type.parse();
+ }
+ }
+
+ Err(format_err!("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-08 12:23 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-08 12:22 [pbs-devel] [PATCH proxmox/proxmox-backup/pwt 0/12] add Active Directory realm support Christoph Heiss
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox 01/12] ldap: add method for retrieving root DSE attributes Christoph Heiss
2023-08-11 10:29 ` Wolfgang Bumiller
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox 02/12] auth-api: implement `Display` for `Realm{, Ref}` Christoph Heiss
2023-08-11 10:32 ` Wolfgang Bumiller
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-backup 03/12] api-types: implement `LdapMode` -> `ConnectionMode` conversion Christoph Heiss
2023-08-11 10:36 ` Wolfgang Bumiller
2023-08-14 9:40 ` Christoph Heiss
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-backup 04/12] auth: factor out CA store and cert lookup into own function Christoph Heiss
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-backup 05/12] api-types: implement `Display`, `FromStr` for `RealmType` Christoph Heiss
2023-08-11 10:58 ` Wolfgang Bumiller
2023-08-14 9:40 ` Christoph Heiss
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-backup 06/12] realm sync: generic-ify `LdapSyncSettings` and `GeneralSyncSettings` Christoph Heiss
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-backup 07/12] api: access: add routes for managing AD realms Christoph Heiss
2023-08-09 10:12 ` Lukas Wagner
2023-08-09 10:54 ` Christoph Heiss
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-backup 08/12] config: domains: add new "ad" section type for " Christoph Heiss
2023-08-08 12:22 ` Christoph Heiss [this message]
2023-08-09 10:12 ` [pbs-devel] [PATCH proxmox-backup 09/12] realm sync: add sync job " Lukas Wagner
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-backup 10/12] manager: add subcommand for managing " Christoph Heiss
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-backup 11/12] docs: user-management: add section about AD realm support Christoph Heiss
2023-08-09 10:12 ` Lukas Wagner
2023-08-08 12:22 ` [pbs-devel] [PATCH proxmox-widget-toolkit 12/12] window: add Active Directory auth panel Christoph Heiss
2023-08-09 10:13 ` Lukas Wagner
2023-08-09 10:57 ` 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=20230808122239.1025524-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.