From 8930a2159d6ec4dd9614b3bf21c03740d9aa8631 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 31 Jul 2008 07:47:01 +1000 Subject: Start implementind domain trusts in our KDC. Andrew Bartlett (This used to be commit 8aba7c36231e58a91fbc6b4fc24c5693353aeef9) --- source4/kdc/hdb-ldb.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'source4/kdc') diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c index 8f8ce3074b..a997eb097c 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-ldb.c @@ -853,7 +853,8 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, { krb5_error_code ret; struct ldb_message **msg = NULL; - struct ldb_message **realm_ref_msg = NULL; + struct ldb_message **realm_ref_msg_1 = NULL; + struct ldb_message **realm_ref_msg_2 = NULL; struct ldb_dn *realm_dn; krb5_principal alloc_principal = NULL; @@ -864,14 +865,18 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, } /* krbtgt case. Either us or a trusted realm */ + if ((LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, - mem_ctx, principal->name.name_string.val[1], &realm_ref_msg) == 0)) { + mem_ctx, principal->realm, &realm_ref_msg_1) == 0) + && (LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, + mem_ctx, principal->name.name_string.val[1], &realm_ref_msg_2) == 0) + && (ldb_dn_cmp(realm_ref_msg_1[0]->dn, realm_ref_msg_1[0]->dn) == 0)) { /* us */ /* Cludge, cludge cludge. If the realm part of krbtgt/realm, * is in our db, then direct the caller at our primary - * krgtgt */ + * krbtgt */ - const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg[0], "dnsRoot", NULL); + const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg_1[0], "dnsRoot", NULL); char *realm_fixed = strupper_talloc(mem_ctx, dnsdomain); if (!realm_fixed) { krb5_set_error_string(context, "strupper_talloc: out of memory"); @@ -891,8 +896,26 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, return ENOMEM; } principal = alloc_principal; - realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL); + realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg_1[0], "nCName", NULL); } else { + enum direction { + INBOUND, + OUTBOUND + } + + struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context *); + /* Either an inbound or outbound trust */ + + if (strcasecmp(lp_realm(lp_ctx), principal->realm) == 0) { + /* look for inbound trust */ + } + + if (strcasecmp(lp_realm(lp_ctx), principal->name.name_string.val[1]) == 0) { + /* look for outbound trust */ + } + + /* Trusted domains are under CN=system */ + /* we should lookup trusted domains */ return HDB_ERR_NOENTRY; } @@ -1022,10 +1045,13 @@ static krb5_error_code LDB_fetch(krb5_context context, HDB *db, if (ret != HDB_ERR_NOENTRY) goto done; } if (flags & HDB_F_GET_SERVER) { - ret = LDB_fetch_server(context, db, mem_ctx, principal, flags, entry_ex); - if (ret != HDB_ERR_NOENTRY) goto done; + /* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */ ret = LDB_fetch_krbtgt(context, db, mem_ctx, principal, flags, entry_ex); if (ret != HDB_ERR_NOENTRY) goto done; + + /* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */ + ret = LDB_fetch_server(context, db, mem_ctx, principal, flags, entry_ex); + if (ret != HDB_ERR_NOENTRY) goto done; } if (flags & HDB_F_GET_KRBTGT) { ret = LDB_fetch_krbtgt(context, db, mem_ctx, principal, flags, entry_ex); -- cgit From 5f873a4d8fbcd2eaeabb452ffba059338ed55dfc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 8 Aug 2008 10:35:57 +1000 Subject: More work towards trusted domain support in the KDC. (This used to be commit c87d732b23ad7de8dc2f824bf11c9310fb4184e1) --- source4/kdc/hdb-ldb.c | 118 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 25 deletions(-) (limited to 'source4/kdc') diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c index a997eb097c..cfde301cd3 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-ldb.c @@ -52,7 +52,7 @@ enum hdb_ldb_ent_type { HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER, - HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_ANY }; + HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_TRUST, HDB_LDB_ENT_TYPE_ANY }; static const char *realm_ref_attrs[] = { "nCName", @@ -60,6 +60,14 @@ static const char *realm_ref_attrs[] = { NULL }; +static const char *trust_attrs[] = { + "trustPartner", + "trustAuthIncoming", + "trustAuthOutgoing", + "whenCreated", + NULL +}; + static KerberosTime ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const char *attr, KerberosTime default_val) { const char *tmp; @@ -745,6 +753,41 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con return 0; } +static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx, + TALLOC_CTX *mem_ctx, + const char *realm, + enum hdb_ldb_ent_type ent_type, + struct ldb_dn *realm_dn, + struct ldb_message ***pmsg) +{ + int lret; + char *filter = NULL; + const char * const *attrs = trust_attrs; + + struct ldb_result *res = NULL; + filter = talloc_asprintf(mem_ctx, "(&(objectClass=trustedDomain)(|(flatname=%s)(trustPartner=%s)))", realm, realm); + + if (!filter) { + krb5_set_error_string(context, "talloc_asprintf: out of memory"); + return ENOMEM; + } + + lret = ldb_search(ldb_ctx, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, filter, attrs, &res); + + if (lret != LDB_SUCCESS) { + DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx))); + return HDB_ERR_NOENTRY; + } else if (res->count == 0 || res->count > 1) { + DEBUG(3, ("Failed find a single entry for %s: got %d\n", filter, res->count)); + talloc_free(res); + return HDB_ERR_NOENTRY; + } + talloc_steal(mem_ctx, res->msgs); + *pmsg = res->msgs; + talloc_free(res); + return 0; +} + static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, const char *realm, @@ -856,6 +899,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, struct ldb_message **realm_ref_msg_1 = NULL; struct ldb_message **realm_ref_msg_2 = NULL; struct ldb_dn *realm_dn; + const char *realm; krb5_principal alloc_principal = NULL; if (principal->name.name_string.len != 2 @@ -870,7 +914,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, mem_ctx, principal->realm, &realm_ref_msg_1) == 0) && (LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, mem_ctx, principal->name.name_string.val[1], &realm_ref_msg_2) == 0) - && (ldb_dn_cmp(realm_ref_msg_1[0]->dn, realm_ref_msg_1[0]->dn) == 0)) { + && (ldb_dn_compare(realm_ref_msg_1[0]->dn, realm_ref_msg_1[0]->dn) == 0)) { /* us */ /* Cludge, cludge cludge. If the realm part of krbtgt/realm, * is in our db, then direct the caller at our primary @@ -897,48 +941,72 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, } principal = alloc_principal; realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg_1[0], "nCName", NULL); + + ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, + mem_ctx, + principal, HDB_LDB_ENT_TYPE_KRBTGT, realm_dn, &msg); + + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: could not find principal in DB"); + krb5_set_error_string(context, "LDB_fetch: could not find principal in DB"); + return ret; + } + + ret = LDB_message2entry(context, db, mem_ctx, + principal, HDB_LDB_ENT_TYPE_KRBTGT, + msg[0], realm_ref_msg_1[0], entry_ex); + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: message2entry failed"); + } + return ret; + } else { - enum direction { + enum { INBOUND, - OUTBOUND - } + OUTBOUND, + UNKNOWN + } direction = UNKNOWN; - struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context *); + struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context); /* Either an inbound or outbound trust */ if (strcasecmp(lp_realm(lp_ctx), principal->realm) == 0) { /* look for inbound trust */ + direction = INBOUND; + realm = principal->name.name_string.val[1]; } if (strcasecmp(lp_realm(lp_ctx), principal->name.name_string.val[1]) == 0) { /* look for outbound trust */ + direction = OUTBOUND; + realm = principal->realm; } /* Trusted domains are under CN=system */ + ret = LDB_lookup_trust(context, (struct ldb_context *)db->hdb_db, + mem_ctx, + realm, HDB_LDB_ENT_TYPE_TRUST, realm_dn, &msg); + + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: could not find principal in DB"); + krb5_set_error_string(context, "LDB_fetch: could not find principal in DB"); + return ret; + } + + ret = LDB_message2entry(context, db, mem_ctx, + principal, HDB_LDB_ENT_TYPE_KRBTGT, + msg[0], realm_ref_msg_1[0], entry_ex); + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: message2entry failed"); + } + return ret; + + /* we should lookup trusted domains */ return HDB_ERR_NOENTRY; } - realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL); - - ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, - mem_ctx, - principal, HDB_LDB_ENT_TYPE_KRBTGT, realm_dn, &msg); - - if (ret != 0) { - krb5_warnx(context, "LDB_fetch: could not find principal in DB"); - krb5_set_error_string(context, "LDB_fetch: could not find principal in DB"); - return ret; - } - - ret = LDB_message2entry(context, db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_KRBTGT, - msg[0], realm_ref_msg[0], entry_ex); - if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); - } - return ret; } static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, -- cgit From fe95409de76cf64bb65dbc9ce1ed2ddf9774a896 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 15 Aug 2008 21:16:20 +1000 Subject: Trusted domains implementation for the KDC. At this stage, only arcfour-hmac-md5 trusts are used, and all trusts are presumed bi-directional. Much more work still to be done. Andrew Bartlett (This used to be commit 3e9f5c28165e66d78c020d10b97b9dc4a0038cd8) --- source4/kdc/hdb-ldb.c | 205 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 193 insertions(+), 12 deletions(-) (limited to 'source4/kdc') diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c index cfde301cd3..95c60e2c78 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-ldb.c @@ -49,11 +49,18 @@ #include "param/param.h" #include "events/events.h" #include "kdc/kdc.h" +#include "lib/crypto/md4.h" enum hdb_ldb_ent_type { HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER, HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_TRUST, HDB_LDB_ENT_TYPE_ANY }; +enum trust_direction { + INBOUND, + OUTBOUND, + UNKNOWN +}; + static const char *realm_ref_attrs[] = { "nCName", "dnsRoot", @@ -65,6 +72,10 @@ static const char *trust_attrs[] = { "trustAuthIncoming", "trustAuthOutgoing", "whenCreated", + "msDS-SupportedEncryptionTypes", + "trustAttributes", + "trustDirection", + "trustType", NULL }; @@ -683,6 +694,182 @@ out: return ret; } +/* + * Construct an hdb_entry from a directory entry. + */ +static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, + struct loadparm_context *lp_ctx, + TALLOC_CTX *mem_ctx, krb5_const_principal principal, + enum trust_direction direction, + struct ldb_message *msg, + hdb_entry_ex *entry_ex) +{ + + const char *dnsdomain; + char *realm; + char *strdup_realm; + DATA_BLOB password_utf16; + struct samr_Password password_hash; + const struct ldb_val *password_val; + struct trustAuthInOutBlob password_blob; + struct hdb_ldb_private *private; + + enum ndr_err_code ndr_err; + int i, ret, trust_direction_flags; + + private = talloc(mem_ctx, struct hdb_ldb_private); + if (!private) { + ret = ENOMEM; + goto out; + } + + private->entry_ex = entry_ex; + private->iconv_convenience = lp_iconv_convenience(lp_ctx); + private->netbios_name = lp_netbios_name(lp_ctx); + + talloc_set_destructor(private, hdb_ldb_destrutor); + + entry_ex->ctx = private; + entry_ex->free_entry = hdb_ldb_free_entry; + + /* use 'whenCreated' */ + entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); + /* use '???' */ + entry_ex->entry.created_by.principal = NULL; + + entry_ex->entry.valid_start = NULL; + + trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0); + + if (direction == INBOUND) { + realm = strupper_talloc(mem_ctx, lp_realm(lp_ctx)); + password_val = ldb_msg_find_ldb_val(msg, "trustAuthIncoming"); + + } else { /* OUTBOUND */ + dnsdomain = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL); + realm = strupper_talloc(mem_ctx, dnsdomain); + password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing"); + } + + ndr_err = ndr_pull_struct_blob_all(password_val, mem_ctx, private->iconv_convenience, &password_blob, + (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + ret = EINVAL; + goto out; + } + + for (i=0; i < password_blob.count; i++) { + if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { + password_utf16 = data_blob_const(password_blob.current->array[i].AuthInfo.clear.password, + password_blob.current->array[i].AuthInfo.clear.size); + /* In the future, generate all sorts of + * hashes, but for now we can't safely convert + * the random strings windows uses into + * utf8 */ + + /* but as it is utf16 already, we can get the NT password/arcfour-hmac-md5 key */ + mdfour(password_hash.hash, password_utf16.data, password_utf16.length); + break; + } else if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_NT4OWF) { + password_hash = password_blob.current->array[i].AuthInfo.nt4owf.password; + break; + } + } + entry_ex->entry.keys.len = 0; + entry_ex->entry.keys.val = NULL; + + if (i < password_blob.count) { + Key key; + /* Must have found a cleartext or MD4 password */ + entry_ex->entry.keys.val = calloc(1, sizeof(Key)); + + key.mkvno = 0; + key.salt = NULL; /* No salt for this enc type */ + + if (entry_ex->entry.keys.val == NULL) { + ret = ENOMEM; + goto out; + } + + ret = krb5_keyblock_init(context, + ENCTYPE_ARCFOUR_HMAC_MD5, + password_hash.hash, sizeof(password_hash.hash), + &key.key); + + entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; + entry_ex->entry.keys.len++; + } + + ret = copy_Principal(principal, entry_ex->entry.principal); + if (ret) { + krb5_clear_error_string(context); + goto out; + } + + /* While we have copied the client principal, tests + * show that Win2k3 returns the 'corrected' realm, not + * the client-specified realm. This code attempts to + * replace the client principal's realm with the one + * we determine from our records */ + + /* this has to be with malloc() */ + strdup_realm = strdup(realm); + if (!strdup_realm) { + ret = ENOMEM; + krb5_clear_error_string(context); + goto out; + } + free(*krb5_princ_realm(context, entry_ex->entry.principal)); + krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm); + + entry_ex->entry.flags = int2HDBFlags(0); + entry_ex->entry.flags.immutable = 1; + entry_ex->entry.flags.invalid = 0; + entry_ex->entry.flags.server = 1; + entry_ex->entry.flags.require_preauth = 1; + + entry_ex->entry.pw_end = NULL; + + entry_ex->entry.max_life = NULL; + + entry_ex->entry.max_renew = NULL; + + entry_ex->entry.generation = NULL; + + entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes))); + if (entry_ex->entry.etypes == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + entry_ex->entry.etypes->len = entry_ex->entry.keys.len; + entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int)); + if (entry_ex->entry.etypes->val == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + for (i=0; i < entry_ex->entry.etypes->len; i++) { + entry_ex->entry.etypes->val[i] = entry_ex->entry.keys.val[i].key.keytype; + } + + + private->msg = talloc_steal(private, msg); + private->realm_ref_msg = NULL; + private->samdb = (struct ldb_context *)db->hdb_db; + +out: + if (ret != 0) { + /* This doesn't free ent itself, that is for the eventual caller to do */ + hdb_free_entry(context, entry_ex); + } else { + talloc_steal(db, entry_ex->ctx); + } + + return ret; + +} + static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, krb5_const_principal principal, @@ -717,8 +904,7 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con switch (ent_type) { case HDB_LDB_ENT_TYPE_CLIENT: - /* Can't happen */ - return EINVAL; + case HDB_LDB_ENT_TYPE_TRUST: case HDB_LDB_ENT_TYPE_ANY: /* Can't happen */ return EINVAL; @@ -756,7 +942,6 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, const char *realm, - enum hdb_ldb_ent_type ent_type, struct ldb_dn *realm_dn, struct ldb_message ***pmsg) { @@ -961,11 +1146,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, return ret; } else { - enum { - INBOUND, - OUTBOUND, - UNKNOWN - } direction = UNKNOWN; + enum trust_direction direction = UNKNOWN; struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context); /* Either an inbound or outbound trust */ @@ -986,7 +1167,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, ret = LDB_lookup_trust(context, (struct ldb_context *)db->hdb_db, mem_ctx, - realm, HDB_LDB_ENT_TYPE_TRUST, realm_dn, &msg); + realm, realm_dn, &msg); if (ret != 0) { krb5_warnx(context, "LDB_fetch: could not find principal in DB"); @@ -994,9 +1175,9 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, return ret; } - ret = LDB_message2entry(context, db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_KRBTGT, - msg[0], realm_ref_msg_1[0], entry_ex); + ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx, + principal, direction, + msg[0], entry_ex); if (ret != 0) { krb5_warnx(context, "LDB_fetch: message2entry failed"); } -- cgit From 7f86b26a35e86139b991d42b61321cbc8fa68416 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 26 Aug 2008 10:27:00 +1000 Subject: Only allow the trust in the correct direction (per the flags). (This used to be commit 2c7195429411d68bc66f4100659c622df4f5a20a) --- source4/kdc/hdb-ldb.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/kdc') diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c index 95c60e2c78..ef3a0bcb8a 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-ldb.c @@ -45,6 +45,7 @@ #include "dsdb/samdb/samdb.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_drsblobs.h" +#include "librpc/gen_ndr/lsa.h" #include "libcli/auth/libcli_auth.h" #include "param/param.h" #include "events/events.h" @@ -56,9 +57,9 @@ enum hdb_ldb_ent_type HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_TRUST, HDB_LDB_ENT_TYPE_ANY }; enum trust_direction { - INBOUND, - OUTBOUND, - UNKNOWN + UNKNOWN = 0, + INBOUND = LSA_TRUST_DIRECTION_INBOUND, + OUTBOUND = LSA_TRUST_DIRECTION_OUTBOUND }; static const char *realm_ref_attrs[] = { @@ -751,6 +752,11 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing"); } + if (!password_val || !(trust_direction_flags & direction)) { + ret = ENOENT; + goto out; + } + ndr_err = ndr_pull_struct_blob_all(password_val, mem_ctx, private->iconv_convenience, &password_blob, (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { -- cgit From d3265b01e5e8b7dea19ac238bafd756165613f0c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Aug 2008 16:12:42 +0200 Subject: kdc: move references to heimdal internals into heimdal_build/kpasswd-glue.h metze (This used to be commit 65057f17b0d9e83f1b775afdeb7ea91ce0e52cd1) --- source4/kdc/kpasswdd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/kdc') diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c index 065777fc66..603332e69e 100644 --- a/source4/kdc/kpasswdd.c +++ b/source4/kdc/kpasswdd.c @@ -40,8 +40,7 @@ /* TODO: remove all SAMBA4_INTERNAL_HEIMDAL stuff from this file */ #ifdef SAMBA4_INTERNAL_HEIMDAL -#include "heimdal/lib/hcrypto/aes.h" -#include "heimdal/lib/krb5/krb5-private.h" +#include "heimdal_build/kpasswdd-glue.h" #endif /* hold information about one kdc socket */ -- cgit From c79dff2e9b7c0c07ae5845ddc3b2c06f7996dfd1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 Aug 2008 16:28:47 +1000 Subject: Heimdal provides Kerberos PAC parsing routines. Use them. This uses Heimdal's PAC parsing code in the: - LOCAL-PAC test - gensec_gssapi server - KDC (where is was already used, the support code refactored from here) In addition, the service and KDC checksums are recorded in the struct auth_serversupplied_info, allowing them to be extracted for validation across NETLOGON. Andrew Bartlett (This used to be commit 418b440a7b8cdb53035045f3981d47b078be6c1e) --- source4/kdc/pac-glue.c | 44 +++++++------------------------------------- 1 file changed, 7 insertions(+), 37 deletions(-) (limited to 'source4/kdc') diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c index bee271eaa9..cbdbb86b1f 100644 --- a/source4/kdc/pac-glue.c +++ b/source4/kdc/pac-glue.c @@ -153,18 +153,12 @@ krb5_error_code samba_kdc_reget_pac(void *priv, krb5_context context, struct hdb_entry_ex *client, struct hdb_entry_ex *server, krb5_pac *pac) { - NTSTATUS nt_status; - enum ndr_err_code ndr_err; krb5_error_code ret; unsigned int userAccountControl; struct hdb_ldb_private *private = talloc_get_type(server->ctx, struct hdb_ldb_private); - krb5_data k5pac_in; - DATA_BLOB pac_in; - union PAC_INFO info; - union netr_Validation validation; struct auth_serversupplied_info *server_info_out; TALLOC_CTX *mem_ctx = talloc_named(private, 0, "samba_get_pac context"); @@ -176,46 +170,22 @@ krb5_error_code samba_kdc_reget_pac(void *priv, krb5_context context, /* The service account may be set not to want the PAC */ userAccountControl = ldb_msg_find_attr_as_uint(private->msg, "userAccountControl", 0); if (userAccountControl & UF_NO_AUTH_DATA_REQUIRED) { + talloc_free(mem_ctx); *pac = NULL; return 0; } - ret = krb5_pac_get_buffer(context, *pac, PAC_TYPE_LOGON_INFO, &k5pac_in); - if (ret != 0) { - return ret; - } + ret = kerberos_pac_to_server_info(mem_ctx, private->iconv_convenience, + *pac, context, &server_info_out); - pac_in = data_blob_talloc(mem_ctx, k5pac_in.data, k5pac_in.length); - krb5_data_free(&k5pac_in); - if (!pac_in.data) { - talloc_free(mem_ctx); - return ENOMEM; - } - - ndr_err = ndr_pull_union_blob(&pac_in, mem_ctx, private->iconv_convenience, &info, - PAC_TYPE_LOGON_INFO, - (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err) || !info.logon_info.info) { - nt_status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("can't parse the PAC LOGON_INFO: %s\n", nt_errstr(nt_status))); - talloc_free(mem_ctx); - return EINVAL; - } + /* We will compleatly regenerate this pac */ + krb5_pac_free(context, *pac); - /* Pull this right into the normal auth sysstem structures */ - validation.sam3 = &info.logon_info.info->info3; - nt_status = make_server_info_netlogon_validation(mem_ctx, - "", - 3, &validation, - &server_info_out); - if (!NT_STATUS_IS_OK(nt_status)) { + if (ret) { talloc_free(mem_ctx); - return ENOMEM; + return ret; } - /* We will compleatly regenerate this pac */ - krb5_pac_free(context, *pac); - ret = make_pac(context, mem_ctx, private->iconv_convenience, server_info_out, pac); talloc_free(mem_ctx); -- cgit