summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/kdc/hdb-ldb.c40
-rw-r--r--source4/librpc/idl/drsblobs.idl90
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(