diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 80 | ||||
-rw-r--r-- | source4/kdc/hdb-ldb.c | 36 | ||||
-rw-r--r-- | source4/librpc/idl/drsblobs.idl | 24 |
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( |