summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c80
-rw-r--r--source4/kdc/hdb-ldb.c36
-rw-r--r--source4/librpc/idl/drsblobs.idl24
3 files changed, 84 insertions, 56 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index a31486fdda..861e17e4d0 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -221,9 +221,10 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
krb5_salt salt;
krb5_keyblock key;
uint32_t k=0;
+ struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3;
struct supplementalCredentialsPackage *old_scp = NULL;
struct package_PrimaryKerberosBlob _old_pkb;
- struct package_PrimaryKerberosBlob *old_pkb = NULL;
+ struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL;
uint32_t i;
NTSTATUS status;
@@ -305,16 +306,16 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
return LDB_ERR_OPERATIONS_ERROR;
}
/* create a talloc copy */
- pkb->salt.string = talloc_strndup(io->ac,
+ pkb3->salt.string = talloc_strndup(io->ac,
salt.saltvalue.data,
salt.saltvalue.length);
krb5_free_salt(io->smb_krb5_context->krb5_context, salt);
- if (!pkb->salt.string) {
+ if (!pkb3->salt.string) {
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- salt.saltvalue.data = discard_const(pkb->salt.string);
- salt.saltvalue.length = strlen(pkb->salt.string);
+ salt.saltvalue.data = discard_const(pkb3->salt.string);
+ salt.saltvalue.length = strlen(pkb3->salt.string);
/*
* prepare generation of keys
@@ -323,16 +324,16 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
* ENCTYPE_DES_CBC_MD5
* ENCTYPE_DES_CBC_CRC
*
- * NOTE: update num_keys1 when you add another enctype!
+ * NOTE: update num_keys when you add another enctype!
*/
- pkb->num_keys1 = 0;
- pkb->keys1 = talloc_array(io->ac, struct package_PrimaryKerberosKey, 3);
- if (!pkb->keys1) {
+ pkb3->num_keys = 3;
+ pkb3->keys = talloc_array(io->ac, struct package_PrimaryKerberosKey, pkb3->num_keys);
+ if (!pkb3->keys) {
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- pkb->unknown3_1 = talloc_zero_array(io->ac, uint64_t, pkb->num_keys1);
- if (!pkb->unknown3_1) {
+ pkb3->unknown3 = talloc_zero_array(io->ac, uint64_t, pkb3->num_keys);
+ if (!pkb3->unknown3) {
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -357,18 +358,18 @@ if (lp_parm_bool(-1, "password_hash", "create_aes_key", false)) {
io->n.cleartext,
salt,
&key);
- pkb->keys1[k].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
- pkb->keys1[k].value = talloc(pkb->keys1, DATA_BLOB);
- if (!pkb->keys1[k].value) {
+ pkb3->keys[k].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
+ pkb3->keys[k].value = talloc(pkb3->keys, DATA_BLOB);
+ if (!pkb3->keys[k].value) {
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- *pkb->keys1[k].value = data_blob_talloc(pkb->keys1[k].value,
+ *pkb3->keys[k].value = data_blob_talloc(pkb3->keys[k].value,
key.keyvalue.data,
key.keyvalue.length);
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
- if (!pkb->keys1[k].value->data) {
+ if (!pkb3->keys[k].value->data) {
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -384,18 +385,18 @@ if (lp_parm_bool(-1, "password_hash", "create_aes_key", false)) {
io->n.cleartext,
salt,
&key);
- pkb->keys1[k].keytype = ENCTYPE_DES_CBC_MD5;
- pkb->keys1[k].value = talloc(pkb->keys1, DATA_BLOB);
- if (!pkb->keys1[k].value) {
+ pkb3->keys[k].keytype = ENCTYPE_DES_CBC_MD5;
+ pkb3->keys[k].value = talloc(pkb3->keys, DATA_BLOB);
+ if (!pkb3->keys[k].value) {
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- *pkb->keys1[k].value = data_blob_talloc(pkb->keys1[k].value,
+ *pkb3->keys[k].value = data_blob_talloc(pkb3->keys[k].value,
key.keyvalue.data,
key.keyvalue.length);
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
- if (!pkb->keys1[k].value->data) {
+ if (!pkb3->keys[k].value->data) {
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -410,30 +411,30 @@ if (lp_parm_bool(-1, "password_hash", "create_aes_key", false)) {
io->n.cleartext,
salt,
&key);
- pkb->keys1[k].keytype = ENCTYPE_DES_CBC_CRC;
- pkb->keys1[k].value = talloc(pkb->keys1, DATA_BLOB);
- if (!pkb->keys1[k].value) {
+ pkb3->keys[k].keytype = ENCTYPE_DES_CBC_CRC;
+ pkb3->keys[k].value = talloc(pkb3->keys, DATA_BLOB);
+ if (!pkb3->keys[k].value) {
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- *pkb->keys1[k].value = data_blob_talloc(pkb->keys1[k].value,
+ *pkb3->keys[k].value = data_blob_talloc(pkb3->keys[k].value,
key.keyvalue.data,
key.keyvalue.length);
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
- if (!pkb->keys1[k].value->data) {
+ if (!pkb3->keys[k].value->data) {
ldb_oom(io->ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
k++;
/* fix up key number */
- pkb->num_keys1 = k;
+ pkb3->num_keys = k;
/* initialize the old keys to zero */
- pkb->num_keys2 = 0;
- pkb->keys2 = NULL;
- pkb->unknown3_2 = NULL;
+ pkb3->num_old_keys = 0;
+ pkb3->old_keys = NULL;
+ pkb3->unknown3_old = NULL;
/* if there're no old keys, then we're done */
if (!old_scb) {
@@ -477,18 +478,27 @@ if (lp_parm_bool(-1, "password_hash", "create_aes_key", false)) {
nt_errstr(status));
return LDB_ERR_OPERATIONS_ERROR;
}
- old_pkb = &_old_pkb;
+
+ if (_old_pkb.version != 3) {
+ ldb_asprintf_errstring(io->ac->module->ldb,
+ "setup_primary_kerberos: "
+ "package_PrimaryKerberosBlob version[%u] expected[3]",
+ _old_pkb.version);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ old_pkb3 = &_old_pkb.ctr.ctr3;
}
/* if we didn't found the old keys we're done */
- if (!old_pkb) {
+ if (!old_pkb3) {
return LDB_SUCCESS;
}
/* fill in the old keys */
- pkb->num_keys2 = old_pkb->num_keys1;
- pkb->keys2 = old_pkb->keys1;
- pkb->unknown3_2 = old_pkb->unknown3_1;
+ pkb3->num_old_keys = old_pkb3->num_keys;
+ pkb3->old_keys = old_pkb3->keys;
+ pkb3->unknown3_old = old_pkb3->unknown3;
return LDB_SUCCESS;
}
diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c
index ffab44c8e9..11ae2a0064 100644
--- a/source4/kdc/hdb-ldb.c
+++ b/source4/kdc/hdb-ldb.c
@@ -214,7 +214,7 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
struct supplementalCredentialsBlob scb;
struct supplementalCredentialsPackage *scp = NULL;
struct package_PrimaryKerberosBlob _pkb;
- struct package_PrimaryKerberosBlob *pkb = NULL;
+ struct package_PrimaryKerberosCtr3 *pkb3 = NULL;
uint32_t i;
uint32_t allocated_keys = 0;
@@ -275,12 +275,22 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
status = ndr_pull_struct_blob(&blob, mem_ctx, &_pkb,
(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
if (!NT_STATUS_IS_OK(status)) {
+ krb5_set_error_string(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+ krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
ret = EINVAL;
goto out;
}
- pkb = &_pkb;
- allocated_keys += pkb->num_keys1;
+ if (_pkb.version != 3) {
+ krb5_set_error_string(context, "LDB_message2entry_keys: could not parse PrimaryKerberos not version 3");
+ krb5_warnx(context, "LDB_message2entry_keys: could not parse PrimaryKerberos not version 3");
+ ret = EINVAL;
+ goto out;
+ }
+
+ pkb3 = &_pkb.ctr.ctr3;
+
+ allocated_keys += pkb3->num_keys;
}
if (allocated_keys == 0) {
@@ -316,15 +326,15 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
entry_ex->entry.keys.len++;
}
- if (pkb) {
- for (i=0; i < pkb->num_keys1; i++) {
+ if (pkb3) {
+ for (i=0; i < pkb3->num_keys; i++) {
bool use = true;
Key key;
- if (!pkb->keys1[i].value) continue;
+ if (!pkb3->keys[i].value) continue;
if (userAccountControl & UF_USE_DES_KEY_ONLY) {
- switch (pkb->keys1[i].keytype) {
+ switch (pkb3->keys[i].keytype) {
case ENCTYPE_DES_CBC_CRC:
case ENCTYPE_DES_CBC_MD5:
break;
@@ -338,10 +348,10 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
key.mkvno = 0;
- if (pkb->salt.string) {
+ if (pkb3->salt.string) {
DATA_BLOB salt;
- salt = data_blob_string_const(pkb->salt.string);
+ salt = data_blob_string_const(pkb3->salt.string);
key.salt = calloc(1, sizeof(*key.salt));
if (key.salt == NULL) {
@@ -360,9 +370,9 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
}
ret = krb5_keyblock_init(context,
- pkb->keys1[i].keytype,
- pkb->keys1[i].value->data,
- pkb->keys1[i].value->length,
+ pkb3->keys[i].keytype,
+ pkb3->keys[i].value->data,
+ pkb3->keys[i].value->length,
&key.key);
if (ret) {
if (key.salt) {
@@ -380,7 +390,7 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
out:
if (ret != 0) {
- entry_ex->entry.keys.len = 0;
+ entry_ex->entry.keys.len = 0;
}
if (entry_ex->entry.keys.len == 0 && entry_ex->entry.keys.val) {
free(entry_ex->entry.keys.val);
diff --git a/source4/librpc/idl/drsblobs.idl b/source4/librpc/idl/drsblobs.idl
index ec2e2163f1..3b912548a2 100644
--- a/source4/librpc/idl/drsblobs.idl
+++ b/source4/librpc/idl/drsblobs.idl
@@ -270,17 +270,25 @@ interface drsblobs {
[value(0)] uint32 unknown2;
} package_PrimaryKerberosKey;
- typedef [public] struct {
- [value(3)] uint32 version;
- uint16 num_keys1;
- uint16 num_keys2;
+ typedef struct {
+ uint16 num_keys;
+ uint16 num_old_keys;
package_PrimaryKerberosString salt;
[value(0)] uint32 unknown1;
[value(0)] uint32 unknown2;
- package_PrimaryKerberosKey keys1[num_keys1];
- package_PrimaryKerberosKey keys2[num_keys2];
- udlong unknown3_1[num_keys1];
- udlong unknown3_2[num_keys2];
+ package_PrimaryKerberosKey keys[num_keys];
+ package_PrimaryKerberosKey old_keys[num_old_keys];
+ udlong unknown3[num_keys];
+ udlong unknown3_old[num_old_keys];
+ } package_PrimaryKerberosCtr3;
+
+ typedef [nodiscriminant] union {
+ [case(3)] package_PrimaryKerberosCtr3 ctr3;
+ } package_PrimaryKerberosCtr;
+
+ typedef [public] struct {
+ [value(3)] uint32 version;
+ [switch_is(version)] package_PrimaryKerberosCtr ctr;
} package_PrimaryKerberosBlob;
void decode_PrimaryKerberos(