diff options
-rw-r--r-- | source4/kdc/hdb-ldb.c | 40 | ||||
-rw-r--r-- | source4/librpc/idl/drsblobs.idl | 90 |
2 files changed, 84 insertions, 46 deletions
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); diff --git a/source4/librpc/idl/drsblobs.idl b/source4/librpc/idl/drsblobs.idl index adfc010237..401f5e40bb 100644 --- a/source4/librpc/idl/drsblobs.idl +++ b/source4/librpc/idl/drsblobs.idl @@ -1,6 +1,6 @@ #include "idl_types.h" -import "drsuapi.idl", "misc.idl"; +import "drsuapi.idl", "misc.idl", "samr.idl"; [ uuid("12345778-1234-abcd-0001-00000001"), @@ -359,19 +359,6 @@ interface drsblobs { typedef struct { NTTIME time1; uint32 unknown1; - /* - * the secret value is encoded as UTF16 if it's a string - * but krb5 trusts have random bytes here, so converting to UTF16 - * mayfail... - * - * TODO: We should try handle the case of a random buffer in all places - * we deal with cleartext passwords from windows - * - * so we don't use this: - * - * uint32 value_len; - * [charset(UTF16)] uint8 value[value_len]; - */ DATA_BLOB value; [flag(NDR_ALIGN4)] DATA_BLOB _pad; } trustAuthInOutSecret1; @@ -380,41 +367,66 @@ interface drsblobs { [relative] trustAuthInOutSecret1 *value1; [relative] trustAuthInOutSecret1 *value2; } trustAuthInOutCtr1; + + typedef [v1_enum] enum { + TRUST_AUTH_TYPE_NONE = 0, + TRUST_AUTH_TYPE_NT4OWF = 1, + TRUST_AUTH_TYPE_CLEAR = 2, + TRUST_AUTH_TYPE_VERSION = 3 + } trustAuthType; typedef struct { - NTTIME time1; - uint32 unknown1; - DATA_BLOB value; - NTTIME time2; - uint32 unknown2; - uint32 unknown3; - uint32 unknown4; - [flag(NDR_ALIGN4)] DATA_BLOB _pad; - } trustAuthInOutSecret2V1; + [value(0)] uint32 size; + } AuthInfoNone; typedef struct { - NTTIME time1; - uint32 unknown1; - DATA_BLOB value; - NTTIME time2; - uint32 unknown2; - uint32 unknown3; - [flag(NDR_ALIGN4)] DATA_BLOB _pad; - } trustAuthInOutSecret2V2; + [value(16)] uint32 size; + samr_Password password; + } AuthInfoNT4Owf; + + typedef struct { + uint32 size; + [charset(UTF16)] uint8 password[size]; + } AuthInfoClear; typedef struct { - [relative] trustAuthInOutSecret2V1 *value1; - [relative] trustAuthInOutSecret2V2 *value2; - } trustAuthInOutCtr2; + [value(4)] uint32 size; + uint32 version; + } AuthInfoVersion; typedef [nodiscriminant] union { - [case(1)] trustAuthInOutCtr1 ctr1; - [case(2)] trustAuthInOutCtr2 ctr2; - } trustAuthInOutCtr; + [case(TRUST_AUTH_TYPE_NONE)] AuthInfoNone none; + [case(TRUST_AUTH_TYPE_NT4OWF)] AuthInfoNT4Owf nt4owf; + [case(TRUST_AUTH_TYPE_CLEAR)] AuthInfoClear clear; + [case(TRUST_AUTH_TYPE_VERSION)] AuthInfoVersion version; + } AuthInfo; + + typedef struct { + NTTIME LastUpdateTime; + trustAuthType AuthType; + + /* + * the secret value is encoded as UTF16 if it's a string + * but depending the AuthType, it might also be krb5 trusts have random bytes here, so converting to UTF16 + * mayfail... + * + * TODO: We should try handle the case of a random buffer in all places + * we deal with cleartext passwords from windows + * + * so we don't use this: + * + * uint32 value_len; + * [charset(UTF16)] uint8 value[value_len]; + */ + [switch_is(AuthType)] AuthInfo AuthInfo; + [flag(NDR_ALIGN4)] DATA_BLOB _pad; + } AuthenticationInformation; typedef [public] struct { - uint32 version; - [switch_is(version)] trustAuthInOutCtr ctr; + uint32 count; + [relative] AuthenticationInformation *authinfo[count]; + [relative] AuthenticationInformation *previous_authinfo[count]; + } trustAuthInOutBlob; void decode_trustAuthInOut( |