summaryrefslogtreecommitdiff
path: root/source4/kdc/hdb-ldb.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-07-24 14:26:30 +1000
committerAndrew Tridgell <tridge@samba.org>2008-07-24 14:26:30 +1000
commit66f09a7fd121cf7857b45dabc4fcaf32ae543552 (patch)
treef3dceee89ab41e1a3dc78849c9b57839000c77d3 /source4/kdc/hdb-ldb.c
parent2ecda9fde4aa00aecd6df6ebeb162d173853d146 (diff)
parent05583308fe8278f1bc0c815e23cf5e470a81e12f (diff)
downloadsamba-66f09a7fd121cf7857b45dabc4fcaf32ae543552.tar.gz
samba-66f09a7fd121cf7857b45dabc4fcaf32ae543552.tar.bz2
samba-66f09a7fd121cf7857b45dabc4fcaf32ae543552.zip
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
(This used to be commit 24309dbf4d9622fcfafa29ef98bc0459fdaa814b)
Diffstat (limited to 'source4/kdc/hdb-ldb.c')
-rw-r--r--source4/kdc/hdb-ldb.c139
1 files changed, 122 insertions, 17 deletions
diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c
index 70e578ee0d..9960085b1a 100644
--- a/source4/kdc/hdb-ldb.c
+++ b/source4/kdc/hdb-ldb.c
@@ -190,9 +190,12 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
struct samr_Password *hash;
const struct ldb_val *sc_val;
struct supplementalCredentialsBlob scb;
- struct supplementalCredentialsPackage *scp = NULL;
+ struct supplementalCredentialsPackage *scpk = NULL;
+ struct supplementalCredentialsPackage *scpkn = NULL;
struct package_PrimaryKerberosBlob _pkb;
struct package_PrimaryKerberosCtr3 *pkb3 = NULL;
+ struct package_PrimaryKerberosNewerBlob _pknb;
+ struct package_PrimaryKerberosNewerCtr4 *pkb4 = NULL;
uint32_t i;
uint32_t allocated_keys = 0;
@@ -221,35 +224,75 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
goto out;
}
+ if (scb.sub.signature != SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
+ NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
+ ret = EINVAL;
+ goto out;
+ }
+
for (i=0; i < scb.sub.num_packages; i++) {
- if (scb.sub.packages[i].unknown1 != 0x00000001) {
- continue;
+ if (strcmp("Primary:Kerberos-Newer-Keys", scb.sub.packages[i].name) == 0) {
+ scpkn = &scb.sub.packages[i];
+ if (!scpkn->data || !scpkn->data[0]) {
+ scpkn = NULL;
+ continue;
+ }
+ break;
+ } else if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) == 0) {
+ scpk = &scb.sub.packages[i];
+ if (!scpk->data || !scpk->data[0]) {
+ scpk = NULL;
+ }
+ /*
+ * we don't break here in hope to find
+ * a Kerberos-Newer-Keys package
+ */
}
+ }
+ }
+ /* Primary:Kerberos-Newer-Keys element of supplementalCredentials */
+ if (scpkn) {
+ DATA_BLOB blob;
- if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) != 0) {
- continue;
- }
+ blob = strhex_to_data_blob(scpkn->data);
+ if (!blob.data) {
+ ret = ENOMEM;
+ goto out;
+ }
+ talloc_steal(mem_ctx, blob.data);
- if (!scb.sub.packages[i].data || !scb.sub.packages[i].data[0]) {
- continue;
- }
+ /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
+ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pknb,
+ (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosNewerBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ krb5_set_error_string(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosNewerBlob");
+ krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosNewerBlob");
+ ret = EINVAL;
+ goto out;
+ }
- scp = &scb.sub.packages[i];
- break;
+ if (_pknb.version != 4) {
+ krb5_set_error_string(context, "LDB_message2entry_keys: could not parse PrimaryKerberosNewer not version 4");
+ krb5_warnx(context, "LDB_message2entry_keys: could not parse PrimaryKerberosNewer not version 4");
+ ret = EINVAL;
+ goto out;
}
- }
- /* Primary:Kerberos element of supplementalCredentials */
- if (scp) {
+
+ pkb4 = &_pknb.ctr.ctr4;
+
+ allocated_keys += pkb4->num_keys;
+ } else if (scpk) {
+ /* Fallback to Primary:Kerberos element of supplementalCredentials */
DATA_BLOB blob;
- blob = strhex_to_data_blob(scp->data);
+ blob = strhex_to_data_blob(scpk->data);
if (!blob.data) {
ret = ENOMEM;
goto out;
}
talloc_steal(mem_ctx, blob.data);
- /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
+ /* we cannot use ndr_pull_struct_blob_all() here, as w2k and w2k3 add padding bytes */
ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb,
(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -304,7 +347,68 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
entry_ex->entry.keys.len++;
}
- if (pkb3) {
+ if (pkb4) {
+ for (i=0; i < pkb4->num_keys; i++) {
+ bool use = true;
+ Key key;
+
+ if (!pkb4->keys[i].value) continue;
+
+ if (userAccountControl & UF_USE_DES_KEY_ONLY) {
+ switch (pkb4->keys[i].keytype) {
+ case ENCTYPE_DES_CBC_CRC:
+ case ENCTYPE_DES_CBC_MD5:
+ break;
+ default:
+ use = false;
+ break;
+ }
+ }
+
+ if (!use) continue;
+
+ key.mkvno = 0;
+ key.salt = NULL;
+
+ if (pkb4->salt.string) {
+ DATA_BLOB salt;
+
+ salt = data_blob_string_const(pkb4->salt.string);
+
+ key.salt = calloc(1, sizeof(*key.salt));
+ if (key.salt == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ key.salt->type = hdb_pw_salt;
+
+ ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length);
+ if (ret) {
+ free(key.salt);
+ key.salt = NULL;
+ goto out;
+ }
+ }
+
+ ret = krb5_keyblock_init(context,
+ pkb4->keys[i].keytype,
+ pkb4->keys[i].value->data,
+ pkb4->keys[i].value->length,
+ &key.key);
+ if (ret) {
+ if (key.salt) {
+ free_Salt(key.salt);
+ free(key.salt);
+ key.salt = NULL;
+ }
+ goto out;
+ }
+
+ entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+ entry_ex->entry.keys.len++;
+ }
+ } else if (pkb3) {
for (i=0; i < pkb3->num_keys; i++) {
bool use = true;
Key key;
@@ -325,6 +429,7 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
if (!use) continue;
key.mkvno = 0;
+ key.salt = NULL;
if (pkb3->salt.string) {
DATA_BLOB salt;