summaryrefslogtreecommitdiff
path: root/source4/kdc/hdb-samba4.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-07-18 10:15:55 +1000
committerAndrew Bartlett <abartlet@samba.org>2009-07-20 14:21:18 +1000
commit09135ee5a09a8b6aabf88c1bdf9280065c8b35e7 (patch)
tree03e3040546129e2c74ae634f1a64e3662202d6dd /source4/kdc/hdb-samba4.c
parent2fc5331e5c23e3f448b53fa7838e478772d0caed (diff)
downloadsamba-09135ee5a09a8b6aabf88c1bdf9280065c8b35e7.tar.gz
samba-09135ee5a09a8b6aabf88c1bdf9280065c8b35e7.tar.bz2
samba-09135ee5a09a8b6aabf88c1bdf9280065c8b35e7.zip
s4:kdc Add in a simple check for constrained delegation to self
To do this properly, we must use the PAC, but for now this is enough to check that we are delegating to another name on the same host (which must be safe). (Windows 7 does this a lot, also noted in bug 6273) Andrew Bartlett
Diffstat (limited to 'source4/kdc/hdb-samba4.c')
-rw-r--r--source4/kdc/hdb-samba4.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index 435282a0c1..cadbe33af6 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -1422,6 +1422,75 @@ static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db)
return 0;
}
+krb5_error_code hdb_samba4_check_constrained_delegation(krb5_context context, HDB *db,
+ hdb_entry_ex *entry,
+ krb5_const_principal target_principal)
+{
+ struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
+ struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb_ctx, "loadparm"),
+ struct loadparm_context);
+ krb5_error_code ret;
+ krb5_principal enterprise_prinicpal = NULL;
+ struct ldb_dn *realm_dn;
+ struct ldb_message *msg;
+ struct dom_sid *orig_sid;
+ struct dom_sid *target_sid;
+ struct hdb_ldb_private *p = talloc_get_type(entry->ctx, struct hdb_ldb_private);
+ const char *delegation_check_attrs[] = {
+ "objectSid", NULL
+ };
+
+ TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_check_constrained_delegation");
+
+ if (!mem_ctx) {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!");
+ return ret;
+ }
+
+ if (target_principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
+ /* Need to reparse the enterprise principal to find the real target */
+ if (target_principal->name.name_string.len != 1) {
+ ret = KRB5_PARSE_MALFORMED;
+ krb5_set_error_message(context, ret, "hdb_samba4_check_constrained_delegation: request for delegation to enterprise principal with wrong (%d) number of components",
+ target_principal->name.name_string.len);
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ ret = krb5_parse_name(context, target_principal->name.name_string.val[0],
+ &enterprise_prinicpal);
+ if (ret) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ target_principal = enterprise_prinicpal;
+ }
+
+ ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, target_principal,
+ delegation_check_attrs, &realm_dn, &msg);
+
+ krb5_free_principal(context, enterprise_prinicpal);
+
+ if (ret != 0) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ orig_sid = samdb_result_dom_sid(mem_ctx, p->msg, "objectSid");
+ target_sid = samdb_result_dom_sid(mem_ctx, msg, "objectSid");
+
+ /* Allow delegation to the same principal, even if by a different
+ * name. The easy and safe way to prove this is by SID
+ * comparison */
+ if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) {
+ talloc_free(mem_ctx);
+ return KRB5KDC_ERR_BADOPTION;
+ }
+
+ talloc_free(mem_ctx);
+ return ret;
+}
+
/* This interface is to be called by the KDC, which is expecting Samba
* calling conventions. It is also called by a wrapper
* (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb
@@ -1486,7 +1555,7 @@ NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx,
(*db)->hdb_destroy = hdb_samba4_destroy;
(*db)->hdb_auth_status = NULL;
- (*db)->hdb_check_constrained_delegation = NULL;
+ (*db)->hdb_check_constrained_delegation = hdb_samba4_check_constrained_delegation;
return NT_STATUS_OK;
}