summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Sutton <josephsutton@catalyst.net.nz>2023-03-28 15:10:50 +1300
committerAndrew Bartlett <abartlet@samba.org>2023-05-18 01:58:24 +0000
commit6ee5c80ea9610adf4e4624d2e1953e3fc3e91b71 (patch)
tree5c7c0295e1306c8afb16ef0c2fef10e37abec5cd
parent420fae5dcbe886b7e66928e88d031c8569aacd5c (diff)
downloadsamba-master.tar.gz
s4:kdc: Add support for constructed claims (for authentication silos)HEADmaster
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> Autobuild-Date(master): Thu May 18 01:58:24 UTC 2023 on atb-devel-224
-rw-r--r--selftest/knownfail.d/constructed-claims1
-rw-r--r--source4/kdc/ad_claims.c183
-rw-r--r--source4/kdc/wscript_build2
3 files changed, 184 insertions, 2 deletions
diff --git a/selftest/knownfail.d/constructed-claims b/selftest/knownfail.d/constructed-claims
deleted file mode 100644
index b4966d723cd..00000000000
--- a/selftest/knownfail.d/constructed-claims
+++ /dev/null
@@ -1 +0,0 @@
-^samba.tests.krb5.claims_tests.samba.tests.krb5.claims_tests.ClaimsTests.test_auth_silo_claim.ad_dc
diff --git a/source4/kdc/ad_claims.c b/source4/kdc/ad_claims.c
index f00d3e07d0f..8cc8d75472d 100644
--- a/source4/kdc/ad_claims.c
+++ b/source4/kdc/ad_claims.c
@@ -22,6 +22,7 @@
#include "lib/util/debug.h"
#include "lib/util/samba_util.h"
#include "source4/kdc/ad_claims.h"
+#include "source4/kdc/authn_policy_util.h"
#include "ldb_module.h"
#include "libcli/security/security.h"
#include "libcli/util/werror.h"
@@ -548,6 +549,96 @@ static int claim_applies_to_class(TALLOC_CTX *mem_ctx,
return LDB_SUCCESS;
}
+struct assigned_silo {
+ const char *name;
+ bool is_initialised;
+ bool is_assigned;
+};
+
+static struct assigned_silo new_assigned_silo(void)
+{
+ return (struct assigned_silo) {
+ .name = NULL,
+ .is_initialised = false,
+ .is_assigned = false,
+ };
+}
+
+static bool silo_is_maybe_assigned(struct assigned_silo silo)
+{
+ return !silo.is_initialised || silo.is_assigned;
+}
+
+static int get_assigned_silo(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ const struct ldb_message *principal,
+ struct assigned_silo *assigned_silo)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ int ret;
+
+ const struct ldb_message *silo_msg = NULL;
+ static const char * const silo_attrs[] = {
+ "msDS-AuthNPolicySiloEnforced",
+ "msDS-AuthNPolicySiloMembers",
+ "name",
+ NULL
+ };
+
+ bool is_silo_enforced = false;
+ const char *silo_name = NULL;
+
+ if (assigned_silo->is_initialised) {
+ return LDB_SUCCESS;
+ }
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return ldb_oom(ldb);
+ }
+
+ if (!authn_policy_silos_and_policies_in_effect(ldb)) {
+ /* No assigned silo. */
+ assigned_silo->is_assigned = false;
+ assigned_silo->is_initialised = true;
+
+ talloc_free(tmp_ctx);
+ return LDB_SUCCESS;
+ }
+
+ /* Check whether the user is assigned to an enforced silo. */
+ ret = authn_policy_get_assigned_silo(ldb,
+ tmp_ctx,
+ principal,
+ silo_attrs,
+ &silo_msg,
+ &is_silo_enforced);
+ if (ret) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ if (silo_msg == NULL || !is_silo_enforced) {
+ /* No assigned silo. */
+ assigned_silo->is_assigned = false;
+ assigned_silo->is_initialised = true;
+
+ talloc_free(tmp_ctx);
+ return LDB_SUCCESS;
+ }
+
+ /* The user does belong to a silo, so return the name of the silo. */
+ silo_name = ldb_msg_find_attr_as_string(silo_msg,
+ "name",
+ NULL);
+ assigned_silo->name = talloc_steal(mem_ctx, silo_name);
+ assigned_silo->is_assigned = true;
+ assigned_silo->is_initialised = true;
+
+ talloc_free(tmp_ctx);
+ return LDB_SUCCESS;
+}
+
static inline struct ldb_val talloc_steal_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_val val)
{
val.data = talloc_steal(mem_ctx, val.data);
@@ -723,6 +814,8 @@ static int get_all_claims(struct ldb_context *ldb,
struct CLAIMS_ARRAY *ad_sourced_constructed = NULL;
+ struct assigned_silo assigned_silo = new_assigned_silo();
+
*claims_blob = data_blob_null;
tmp_ctx = talloc_new(mem_ctx);
@@ -801,6 +894,7 @@ static int get_all_claims(struct ldb_context *ldb,
const char *claim_source_type = NULL;
const struct ldb_val *claim_attribute_source = NULL;
+ const char *claim_source = NULL;
/*
* Does this claim apply to the most specific objectClass of the
@@ -842,6 +936,10 @@ static int get_all_claims(struct ldb_context *ldb,
claim_attribute_source = ldb_msg_find_ldb_val(res->msgs[i],
"msDS-ClaimAttributeSource");
+ claim_source = ldb_msg_find_attr_as_string(res->msgs[i],
+ "msDS-ClaimSource",
+ NULL);
+
if (strcasecmp(claim_source_type, "AD") == 0) {
struct ldb_dn *claim_attribute_source_dn = NULL;
const struct ldb_val *claim_attribute_source_rdn = NULL;
@@ -916,6 +1014,91 @@ static int get_all_claims(struct ldb_context *ldb,
.attribute = attribute,
.claim_type = claim_value_type,
};
+ } else if (silo_is_maybe_assigned(assigned_silo)
+ && strcasecmp(claim_source_type, "Constructed") == 0)
+ {
+ const struct ldb_val *name = NULL;
+ struct CLAIM_STRING *claim = NULL;
+ struct CLAIM_ENTRY *claim_entry = NULL;
+ const char *claim_value = NULL;
+
+ if (claim_attribute_source != NULL) {
+ continue;
+ }
+
+ if (claim_source != NULL) {
+ continue;
+ }
+
+ name = ldb_msg_find_ldb_val(res->msgs[i], "name");
+ if (name == NULL || name->data == NULL) {
+ continue;
+ }
+ /* Does the claim ID match exactly in case? */
+ if (strcmp((const char *)name->data, "ad://ext/AuthenticationSilo") != 0) {
+ continue;
+ }
+
+ ret = get_assigned_silo(ldb, tmp_ctx, principal, &assigned_silo);
+ if (ret) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ if (!assigned_silo.is_assigned) {
+ continue;
+ }
+
+ if (ad_sourced_constructed == NULL) {
+ claims_set.claims_arrays = talloc_realloc(tmp_ctx,
+ claims_set.claims_arrays,
+ struct CLAIMS_ARRAY,
+ claims_set.claims_array_count + 1);
+ if (claims_set.claims_arrays == NULL) {
+ talloc_free(tmp_ctx);
+ return ldb_oom(ldb);
+ }
+
+ ad_sourced_constructed = &claims_set.claims_arrays[claims_set.claims_array_count++];
+ *ad_sourced_constructed = (struct CLAIMS_ARRAY) {
+ .claims_source_type = CLAIMS_SOURCE_TYPE_AD,
+ };
+ }
+
+ /* Add the claim to the array. */
+ ad_sourced_constructed->claim_entries = talloc_realloc(
+ tmp_ctx,
+ ad_sourced_constructed->claim_entries,
+ struct CLAIM_ENTRY,
+ ad_sourced_constructed->claims_count + 1);
+ if (ad_sourced_constructed->claim_entries == NULL) {
+ talloc_free(tmp_ctx);
+ return ldb_oom(ldb);
+ }
+
+ claim_entry = &ad_sourced_constructed->claim_entries[ad_sourced_constructed->claims_count++];
+
+ /* Fill in the claim details and return the claim. */
+ claim_entry->id = "ad://ext/AuthenticationSilo";
+ claim_entry->type = CLAIM_TYPE_STRING;
+
+ claim = &claim_entry->values.claim_string;
+
+ claim->value_count = 1;
+ claim->values = talloc_array(ad_sourced_constructed->claim_entries,
+ const char *,
+ claim->value_count);
+ if (claim->values == NULL) {
+ talloc_free(tmp_ctx);
+ return ldb_oom(ldb);
+ }
+
+ claim_value = talloc_strdup(claim->values, assigned_silo.name);
+ if (claim_value == NULL) {
+ talloc_free(tmp_ctx);
+ return ldb_oom(ldb);
+ }
+
+ claim->values[0] = claim_value;
}
}
diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build
index 5c713d82ecb..c869f952b98 100644
--- a/source4/kdc/wscript_build
+++ b/source4/kdc/wscript_build
@@ -141,7 +141,7 @@ bld.SAMBA_LIBRARY('db-glue',
bld.SAMBA_LIBRARY('ad_claims',
source='ad_claims.c',
- deps='ldb samba-util samdb dsdb-module',
+ deps='ldb samba-util samdb dsdb-module authn_policy_util',
private_library=True,
)