From 7fba6c649ba36ca5b76dcfed7b773567c9933077 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 22 Jul 2008 15:35:23 +0200 Subject: Change occurrences of the u1 member of DsBindInfo* to pid after idl change. Michael (This used to be commit b91bbc5fe4a47e5823be6be5f2f203f1f14105de) --- source4/dsdb/repl/drepl_out_helpers.c | 2 +- source4/dsdb/repl/drepl_service.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 281e5691e2..0700867543 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -142,7 +142,7 @@ static void dreplsrv_out_drsuapi_bind_recv(struct rpc_request *req) info24 = &st->bind_r.out.bind_info->info.info24; st->drsuapi->remote_info28.supported_extensions = info24->supported_extensions; st->drsuapi->remote_info28.site_guid = info24->site_guid; - st->drsuapi->remote_info28.u1 = info24->u1; + st->drsuapi->remote_info28.pid = info24->pid; st->drsuapi->remote_info28.repl_epoch = 0; break; } diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c index e485c50a47..3611258ca5 100644 --- a/source4/dsdb/repl/drepl_service.c +++ b/source4/dsdb/repl/drepl_service.c @@ -104,7 +104,7 @@ static WERROR dreplsrv_connect_samdb(struct dreplsrv_service *service, struct lo /* TODO: fill in site_guid */ bind_info28->site_guid = GUID_zero(); /* TODO: find out how this is really triggered! */ - bind_info28->u1 = 0; + bind_info28->pid = 0; bind_info28->repl_epoch = 0; return WERR_OK; -- cgit From bcb0db3634680fdaf1d037545fafe7509ed72ad9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Jul 2008 18:31:45 +0200 Subject: password_hash: don't add zero padding as w2k8 also don't add it metze (This used to be commit 26e9169d454349795ad0bc64d7f65059541ab89e) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 3e442b6341..2dddb26550 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -925,16 +925,6 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) nt_errstr(status)); return LDB_ERR_OPERATIONS_ERROR; } - /* - * TODO: - * - * This is ugly, but we want to generate the same blob as - * w2k and w2k3...we should handle this in the idl - */ - if (!data_blob_append(io->ac, &pkb_blob, zero16, sizeof(zero16))) { - ldb_oom(io->ac->module->ldb); - return LDB_ERR_OPERATIONS_ERROR; - } pkb_hexstr = data_blob_hex_string(io->ac, &pkb_blob); if (!pkb_hexstr) { ldb_oom(io->ac->module->ldb); -- cgit From 69d3f0e602893875118878a4b11c2a65f9d4090c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jul 2008 12:00:42 +0200 Subject: password_hash: ignore reserved value, but still set it like windows does metze (This used to be commit 5b860572686167d0291161f6597f143e538e2f3a) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 2dddb26550..e149009948 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -446,10 +446,6 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, } for (i=0; i < old_scb->sub.num_packages; i++) { - if (old_scb->sub.packages[i].unknown1 != 0x00000001) { - continue; - } - if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) { continue; } @@ -931,7 +927,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) return LDB_ERR_OPERATIONS_ERROR; } pk->name = "Primary:Kerberos"; - pk->unknown1 = 1; + pk->reserved = 1; pk->data = pkb_hexstr; /* @@ -962,7 +958,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) return LDB_ERR_OPERATIONS_ERROR; } pd->name = "Primary:WDigest"; - pd->unknown1 = 1; + pd->reserved = 1; pd->data = pdb_hexstr; /* @@ -991,7 +987,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) return LDB_ERR_OPERATIONS_ERROR; } pc->name = "Primary:CLEARTEXT"; - pc->unknown1 = 1; + pc->reserved = 1; pc->data = pcb_hexstr; } @@ -1016,7 +1012,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) return LDB_ERR_OPERATIONS_ERROR; } pp->name = "Packages"; - pp->unknown1 = 2; + pp->reserved = 2; pp->data = pb_hexstr; /* -- cgit From fbea02accfa8f92d84d0f2cb17847dac1519aa87 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jul 2008 13:31:14 +0200 Subject: password_hash: check the SUPPLEMENTAL_CREDENTIALS_SIGNATURE metze (This used to be commit 19b8c8e37bafab050ab61266c35006efada2947c) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index e149009948..59ec18e546 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -876,7 +876,9 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) /* if there's an old supplementaCredentials blob then parse it */ if (io->o.supplemental) { - ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), &_old_scb, + ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac, + lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), + &_old_scb, (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); @@ -887,7 +889,14 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) return LDB_ERR_OPERATIONS_ERROR; } - old_scb = &_old_scb; + if (_old_scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) { + old_scb = &_old_scb; + } else { + ldb_debug(io->ac->module->ldb, LDB_DEBUG_ERROR, + "setup_supplemental_field: " + "supplementalCredentialsBlob signature[0x%04X] expected[0x%04X]", + _old_scb.sub.signature, SUPPLEMENTAL_CREDENTIALS_SIGNATURE); + } } if (io->domain->store_cleartext && -- cgit From e0f04e36ad415d7396fea7d43eb1d0db53d53a69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jul 2008 10:05:43 +0200 Subject: password_hash: fix callers after idl change for package_PrimaryKerberos metze (This used to be commit 1bf552856f3a930c4716ceb73d9ba9adf7502d3d) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 59ec18e546..5bbae2c164 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -336,11 +336,6 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, ldb_oom(io->ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } - 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; - } if (lp_parm_bool(ldb_get_opaque(io->ac->module->ldb, "loadparm"), NULL, "password_hash", "create_aes_key", false)) { /* @@ -438,7 +433,6 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, /* initialize the old keys to zero */ 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) { @@ -499,7 +493,6 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, /* fill in the old keys */ pkb3->num_old_keys = old_pkb3->num_keys; pkb3->old_keys = old_pkb3->keys; - pkb3->unknown3_old = old_pkb3->unknown3; return LDB_SUCCESS; } -- cgit From b783b28d70d787d7524e8afd54c24ef6f3f8bf54 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Jul 2008 18:32:49 +0200 Subject: password_hash: simplify the logic if we have cleartext we always generate the hashes metze (This used to be commit 5edff84429ef0d03b47a438e18861d26c97e17b6) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 5bbae2c164..8dd4e1e76b 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -1071,7 +1071,7 @@ static int setup_password_fields(struct setup_password_fields_io *io) return LDB_ERR_UNWILLING_TO_PERFORM; } - if (io->n.cleartext && !io->n.nt_hash) { + if (io->n.cleartext) { struct samr_Password *hash; hash = talloc(io->ac, struct samr_Password); @@ -1092,7 +1092,7 @@ static int setup_password_fields(struct setup_password_fields_io *io) } } - if (io->n.cleartext && !io->n.lm_hash) { + if (io->n.cleartext) { struct samr_Password *hash; hash = talloc(io->ac, struct samr_Password); -- cgit From 12ac4c5666d56dc806a613584fa72e7c2f29c34e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Jul 2008 18:27:36 +0200 Subject: password_hash: split the generation of krb5 keys into a different function metze (This used to be commit 4ad73a0bf8952783d3d9a7339c0c4fd8ca28981a) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 161 +++++++++++-------------- 1 file changed, 69 insertions(+), 92 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 8dd4e1e76b..9996e89cc6 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -140,6 +140,9 @@ struct setup_password_fields_io { struct samr_Password *nt_history; uint32_t lm_history_len; struct samr_Password *lm_history; + const char *salt; + DATA_BLOB des_md5; + DATA_BLOB des_crc; struct ldb_val supplemental; NTTIME last_set; uint32_t kvno; @@ -216,21 +219,12 @@ static int setup_lm_fields(struct setup_password_fields_io *io) return LDB_SUCCESS; } -static int setup_primary_kerberos(struct setup_password_fields_io *io, - const struct supplementalCredentialsBlob *old_scb, - struct package_PrimaryKerberosBlob *pkb) +static int setup_kerberos_keys(struct setup_password_fields_io *io) { krb5_error_code krb5_ret; Principal *salt_principal; 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_PrimaryKerberosCtr3 *old_pkb3 = NULL; - uint32_t i; - enum ndr_err_code ndr_err; /* Many, many thanks to lukeh@padl.com for this * algorithm, described in his Nov 10 2004 mail to @@ -290,7 +284,7 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, } if (krb5_ret) { ldb_asprintf_errstring(io->ac->module->ldb, - "setup_primary_kerberos: " + "setup_kerberos_keys: " "generation of a salting principal failed: %s", smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac)); return LDB_ERR_OPERATIONS_ERROR; @@ -304,131 +298,107 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal); if (krb5_ret) { ldb_asprintf_errstring(io->ac->module->ldb, - "setup_primary_kerberos: " + "setup_kerberos_keys: " "generation of krb5_salt failed: %s", smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac)); return LDB_ERR_OPERATIONS_ERROR; } /* create a talloc copy */ - pkb3->salt.string = talloc_strndup(io->ac, - salt.saltvalue.data, - salt.saltvalue.length); + io->g.salt = talloc_strndup(io->ac, + salt.saltvalue.data, + salt.saltvalue.length); krb5_free_salt(io->smb_krb5_context->krb5_context, salt); - if (!pkb3->salt.string) { - ldb_oom(io->ac->module->ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - salt.saltvalue.data = discard_const(pkb3->salt.string); - salt.saltvalue.length = strlen(pkb3->salt.string); - - /* - * prepare generation of keys - * - * ENCTYPE_AES256_CTS_HMAC_SHA1_96 (disabled by default) - * ENCTYPE_DES_CBC_MD5 - * ENCTYPE_DES_CBC_CRC - * - * NOTE: update num_keys when you add another enctype! - */ - pkb3->num_keys = 3; - pkb3->keys = talloc_array(io->ac, struct package_PrimaryKerberosKey, pkb3->num_keys); - if (!pkb3->keys) { + if (!io->g.salt) { ldb_oom(io->ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } + salt.saltvalue.data = discard_const(io->g.salt); + salt.saltvalue.length = strlen(io->g.salt); - if (lp_parm_bool(ldb_get_opaque(io->ac->module->ldb, "loadparm"), NULL, "password_hash", "create_aes_key", false)) { - /* - * TODO: - * - * w2k and w2k3 doesn't support AES, so we'll not include - * the AES key here yet. - * - * Also we don't have an example supplementalCredentials blob - * from Windows Longhorn Server with AES support - * - */ /* - * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of + * create ENCTYPE_DES_CBC_MD5 key out of * the salt and the cleartext password */ krb5_ret = krb5_string_to_key_salt(io->smb_krb5_context->krb5_context, - ENCTYPE_AES256_CTS_HMAC_SHA1_96, + ENCTYPE_DES_CBC_MD5, io->n.cleartext, salt, &key); - 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); + if (krb5_ret) { + ldb_asprintf_errstring(io->ac->module->ldb, + "setup_kerberos_keys: " + "generation of a des-cbc-md5 key failed: %s", + smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac)); return LDB_ERR_OPERATIONS_ERROR; } - *pkb3->keys[k].value = data_blob_talloc(pkb3->keys[k].value, - key.keyvalue.data, - key.keyvalue.length); + io->g.des_md5 = data_blob_talloc(io->ac, + key.keyvalue.data, + key.keyvalue.length); krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key); - if (!pkb3->keys[k].value->data) { + if (!io->g.des_md5.data) { ldb_oom(io->ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } - k++; -} /* - * create ENCTYPE_DES_CBC_MD5 key out of + * create ENCTYPE_DES_CBC_CRC key out of * the salt and the cleartext password */ krb5_ret = krb5_string_to_key_salt(io->smb_krb5_context->krb5_context, - ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, io->n.cleartext, salt, &key); - 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); + if (krb5_ret) { + ldb_asprintf_errstring(io->ac->module->ldb, + "setup_kerberos_keys: " + "generation of a des-cbc-crc key failed: %s", + smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac)); return LDB_ERR_OPERATIONS_ERROR; } - *pkb3->keys[k].value = data_blob_talloc(pkb3->keys[k].value, - key.keyvalue.data, - key.keyvalue.length); + io->g.des_crc = data_blob_talloc(io->ac, + key.keyvalue.data, + key.keyvalue.length); krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key); - if (!pkb3->keys[k].value->data) { + if (!io->g.des_crc.data) { ldb_oom(io->ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } - k++; + + return LDB_SUCCESS; +} + +static int setup_primary_kerberos(struct setup_password_fields_io *io, + const struct supplementalCredentialsBlob *old_scb, + struct package_PrimaryKerberosBlob *pkb) +{ + struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3; + struct supplementalCredentialsPackage *old_scp = NULL; + struct package_PrimaryKerberosBlob _old_pkb; + struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL; + uint32_t i; + enum ndr_err_code ndr_err; /* - * create ENCTYPE_DES_CBC_CRC key out of - * the salt and the cleartext password + * prepare generation of keys + * + * ENCTYPE_DES_CBC_MD5 + * ENCTYPE_DES_CBC_CRC */ - krb5_ret = krb5_string_to_key_salt(io->smb_krb5_context->krb5_context, - ENCTYPE_DES_CBC_CRC, - io->n.cleartext, - salt, - &key); - 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; - } - *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 (!pkb3->keys[k].value->data) { + pkb3->salt.string = io->g.salt; + pkb3->num_keys = 2; + 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; } - k++; - /* fix up key number */ - pkb3->num_keys = k; + pkb3->keys[0].keytype = ENCTYPE_DES_CBC_MD5; + pkb3->keys[0].value = &io->g.des_md5; + pkb3->keys[1].keytype = ENCTYPE_DES_CBC_CRC; + pkb3->keys[1].value = &io->g.des_crc; /* initialize the old keys to zero */ pkb3->num_old_keys = 0; @@ -1110,6 +1080,13 @@ static int setup_password_fields(struct setup_password_fields_io *io) } } + if (io->n.cleartext) { + ret = setup_kerberos_keys(io); + if (ret != 0) { + return ret; + } + } + ret = setup_nt_fields(io); if (ret != 0) { return ret; -- cgit From b3d6c5ee31bed1a921ddb3387892d7e82808592d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Jul 2008 18:54:21 +0200 Subject: password_hash: order the supplementalCredentials Packages in the same order like windows metze (This used to be commit ca9cd81a1798fb15195566422b3cad7c282fce89) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 68 +++++++++++++++++++++----- 1 file changed, 55 insertions(+), 13 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 9996e89cc6..8d63aed0f5 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -804,30 +804,41 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) struct supplementalCredentialsBlob scb; struct supplementalCredentialsBlob _old_scb; struct supplementalCredentialsBlob *old_scb = NULL; - /* Packages + (Kerberos, WDigest and maybe CLEARTEXT) */ - uint32_t num_packages = 1 + 2; + /* Packages + (Kerberos, WDigest and CLEARTEXT) */ + uint32_t num_names = 0; + const char *names[1+3]; + uint32_t num_packages = 0; struct supplementalCredentialsPackage packages[1+3]; - struct supplementalCredentialsPackage *pp = &packages[0]; - struct supplementalCredentialsPackage *pk = &packages[1]; - struct supplementalCredentialsPackage *pd = &packages[2]; - struct supplementalCredentialsPackage *pc = NULL; + /* Packages */ + struct supplementalCredentialsPackage *pp = NULL; struct package_PackagesBlob pb; DATA_BLOB pb_blob; char *pb_hexstr; + /* Primary:Kerberos */ + const char **nk = NULL; + struct supplementalCredentialsPackage *pk = NULL; struct package_PrimaryKerberosBlob pkb; DATA_BLOB pkb_blob; char *pkb_hexstr; + /* Primary:WDigest */ + const char **nd = NULL; + struct supplementalCredentialsPackage *pd = NULL; struct package_PrimaryWDigestBlob pdb; DATA_BLOB pdb_blob; char *pdb_hexstr; + /* Primary:CLEARTEXT */ + const char **nc = NULL; + struct supplementalCredentialsPackage *pc = NULL; struct package_PrimaryCLEARTEXTBlob pcb; DATA_BLOB pcb_blob; char *pcb_hexstr; int ret; enum ndr_err_code ndr_err; uint8_t zero16[16]; + bool do_cleartext = false; ZERO_STRUCT(zero16); + ZERO_STRUCT(names); if (!io->n.cleartext) { /* @@ -864,17 +875,46 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) if (io->domain->store_cleartext && (io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) { - pc = &packages[3]; - num_packages++; + do_cleartext = true; } - /* Kerberos, WDigest, CLEARTEXT and termination(counted by the Packages element) */ - pb.names = talloc_zero_array(io->ac, const char *, num_packages); + /* + * The ordering is this + * + * Primary:Kerberos + * Primary:WDigest + * Primary:CLEARTEXT (optional) + * + * And the 'Packages' package is insert before the last + * other package. + */ + + /* Primary:Kerberos */ + nk = &names[num_names++]; + pk = &packages[num_packages++]; + + if (!do_cleartext) { + /* Packages */ + pp = &packages[num_packages++]; + } + + /* Primary:WDigest */ + nd = &names[num_names++]; + pd = &packages[num_packages++]; + + if (do_cleartext) { + /* Packages */ + pp = &packages[num_packages++]; + + /* Primary:CLEARTEXT */ + nc = &names[num_names++]; + pc = &packages[num_packages++]; + } /* * setup 'Primary:Kerberos' element */ - pb.names[0] = "Kerberos"; + *nk = "Kerberos"; ret = setup_primary_kerberos(io, old_scb, &pkb); if (ret != LDB_SUCCESS) { @@ -905,7 +945,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) /* * setup 'Primary:WDigest' element */ - pb.names[1] = "WDigest"; + *nd = "WDigest"; ret = setup_primary_wdigest(io, old_scb, &pdb); if (ret != LDB_SUCCESS) { @@ -937,7 +977,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) * setup 'Primary:CLEARTEXT' element */ if (pc) { - pb.names[2] = "CLEARTEXT"; + *nc = "CLEARTEXT"; pcb.cleartext = io->n.cleartext; @@ -966,6 +1006,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) /* * setup 'Packages' element */ + pb.names = names; ndr_err = ndr_push_struct_blob(&pb_blob, io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), &pb, @@ -990,6 +1031,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) /* * setup 'supplementalCredentials' value */ + ZERO_STRUCT(scb); scb.sub.num_packages = num_packages; scb.sub.packages = packages; -- cgit From 34b10077f9ca742b72ad37c86357d0f16ed68ee7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jul 2008 09:35:19 +0200 Subject: password_hash: add generation of the Primary:Kerberos-Newer-Keys blob But it's still of by default until we now what triggers this generation. It could be that the value is always generated but the KDC only uses it when in a specific funtional level, but it could also be that it's only generated in a specific functional level. metze (This used to be commit 08618bbd508ede0bb9e1922fae562cffdca41cbd) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 219 ++++++++++++++++++++++++- 1 file changed, 216 insertions(+), 3 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 8d63aed0f5..413ec12479 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -141,6 +141,8 @@ struct setup_password_fields_io { uint32_t lm_history_len; struct samr_Password *lm_history; const char *salt; + DATA_BLOB aes_256; + DATA_BLOB aes_128; DATA_BLOB des_md5; DATA_BLOB des_crc; struct ldb_val supplemental; @@ -315,6 +317,56 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) salt.saltvalue.data = discard_const(io->g.salt); salt.saltvalue.length = strlen(io->g.salt); + /* + * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of + * the salt and the cleartext password + */ + krb5_ret = krb5_string_to_key_salt(io->smb_krb5_context->krb5_context, + ENCTYPE_AES256_CTS_HMAC_SHA1_96, + io->n.cleartext, + salt, + &key); + if (krb5_ret) { + ldb_asprintf_errstring(io->ac->module->ldb, + "setup_kerberos_keys: " + "generation of a aes256-cts-hmac-sha1-96 key failed: %s", + smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac)); + return LDB_ERR_OPERATIONS_ERROR; + } + io->g.aes_256 = data_blob_talloc(io->ac, + key.keyvalue.data, + key.keyvalue.length); + krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key); + if (!io->g.aes_256.data) { + ldb_oom(io->ac->module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * create ENCTYPE_AES128_CTS_HMAC_SHA1_96 key out of + * the salt and the cleartext password + */ + krb5_ret = krb5_string_to_key_salt(io->smb_krb5_context->krb5_context, + ENCTYPE_AES128_CTS_HMAC_SHA1_96, + io->n.cleartext, + salt, + &key); + if (krb5_ret) { + ldb_asprintf_errstring(io->ac->module->ldb, + "setup_kerberos_keys: " + "generation of a aes128-cts-hmac-sha1-96 key failed: %s", + smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac)); + return LDB_ERR_OPERATIONS_ERROR; + } + io->g.aes_128 = data_blob_talloc(io->ac, + key.keyvalue.data, + key.keyvalue.length); + krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key); + if (!io->g.aes_128.data) { + ldb_oom(io->ac->module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + /* * create ENCTYPE_DES_CBC_MD5 key out of * the salt and the cleartext password @@ -467,6 +519,117 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, return LDB_SUCCESS; } +static int setup_primary_kerberos_newer(struct setup_password_fields_io *io, + const struct supplementalCredentialsBlob *old_scb, + struct package_PrimaryKerberosNewerBlob *pkb) +{ + struct package_PrimaryKerberosNewerCtr4 *pkb4 = &pkb->ctr.ctr4; + struct supplementalCredentialsPackage *old_scp = NULL; + struct package_PrimaryKerberosNewerBlob _old_pkb; + struct package_PrimaryKerberosNewerCtr4 *old_pkb4 = NULL; + uint32_t i; + enum ndr_err_code ndr_err; + + /* + * prepare generation of keys + * + * ENCTYPE_AES256_CTS_HMAC_SHA1_96 + * ENCTYPE_AES128_CTS_HMAC_SHA1_96 + * ENCTYPE_DES_CBC_MD5 + * ENCTYPE_DES_CBC_CRC + */ + pkb4->salt.string = io->g.salt; + pkb4->num_keys = 4; + pkb4->keys = talloc_array(io->ac, + struct package_PrimaryKerberosNewerKey, + pkb4->num_keys); + if (!pkb4->keys) { + ldb_oom(io->ac->module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + pkb4->keys[0].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96; + pkb4->keys[0].value = &io->g.aes_256; + pkb4->keys[1].keytype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; + pkb4->keys[1].value = &io->g.aes_128; + pkb4->keys[2].keytype = ENCTYPE_DES_CBC_MD5; + pkb4->keys[2].value = &io->g.des_md5; + pkb4->keys[3].keytype = ENCTYPE_DES_CBC_CRC; + pkb4->keys[3].value = &io->g.des_crc; + + /* initialize the old keys to zero */ + pkb4->num_old_keys1 = 0; + pkb4->old_keys1 = NULL; + pkb4->num_old_keys2 = 0; + pkb4->old_keys2 = NULL; + + /* if there're no old keys, then we're done */ + if (!old_scb) { + return LDB_SUCCESS; + } + + for (i=0; i < old_scb->sub.num_packages; i++) { + if (strcmp("Primary:Kerberos-Newer-Keys", old_scb->sub.packages[i].name) != 0) { + continue; + } + + if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) { + continue; + } + + old_scp = &old_scb->sub.packages[i]; + break; + } + /* Primary:Kerberos element of supplementalCredentials */ + if (old_scp) { + DATA_BLOB blob; + + blob = strhex_to_data_blob(old_scp->data); + if (!blob.data) { + ldb_oom(io->ac->module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + talloc_steal(io->ac, blob.data); + + /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */ + ndr_err = ndr_pull_struct_blob(&blob, io->ac, + lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), + &_old_pkb, + (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosNewerBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + ldb_asprintf_errstring(io->ac->module->ldb, + "setup_primary_kerberos_newer: " + "failed to pull old package_PrimaryKerberosNewerBlob: %s", + nt_errstr(status)); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (_old_pkb.version != 4) { + ldb_asprintf_errstring(io->ac->module->ldb, + "setup_primary_kerberos: " + "package_PrimaryKerberosNewerBlob version[%u] expected[4]", + _old_pkb.version); + return LDB_ERR_OPERATIONS_ERROR; + } + + old_pkb4 = &_old_pkb.ctr.ctr4; + } + + /* if we didn't found the old keys we're done */ + if (!old_pkb4) { + return LDB_SUCCESS; + } + + /* fill in the old keys */ + pkb4->num_old_keys1 = old_pkb4->num_keys; + pkb4->old_keys1 = old_pkb4->keys; + pkb4->num_old_keys2 = old_pkb4->num_old_keys1; + pkb4->old_keys2 = old_pkb4->old_keys1; + + return LDB_SUCCESS; +} + static int setup_primary_wdigest(struct setup_password_fields_io *io, const struct supplementalCredentialsBlob *old_scb, struct package_PrimaryWDigestBlob *pdb) @@ -804,16 +967,22 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) struct supplementalCredentialsBlob scb; struct supplementalCredentialsBlob _old_scb; struct supplementalCredentialsBlob *old_scb = NULL; - /* Packages + (Kerberos, WDigest and CLEARTEXT) */ + /* Packages + (Kerberos-Newer-Keys, Kerberos, WDigest and CLEARTEXT) */ uint32_t num_names = 0; - const char *names[1+3]; + const char *names[1+4]; uint32_t num_packages = 0; - struct supplementalCredentialsPackage packages[1+3]; + struct supplementalCredentialsPackage packages[1+4]; /* Packages */ struct supplementalCredentialsPackage *pp = NULL; struct package_PackagesBlob pb; DATA_BLOB pb_blob; char *pb_hexstr; + /* Primary:Kerberos-Newer-Keys */ + const char **nkn = NULL; + struct supplementalCredentialsPackage *pkn = NULL; + struct package_PrimaryKerberosNewerBlob pknb; + DATA_BLOB pknb_blob; + char *pknb_hexstr; /* Primary:Kerberos */ const char **nk = NULL; struct supplementalCredentialsPackage *pk = NULL; @@ -835,6 +1004,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) int ret; enum ndr_err_code ndr_err; uint8_t zero16[16]; + bool do_newer_keys = false; bool do_cleartext = false; ZERO_STRUCT(zero16); @@ -873,6 +1043,10 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) } } + /* TODO: do the correct check for this, it maybe depends on the functional level? */ + do_newer_keys = lp_parm_bool(ldb_get_opaque(io->ac->module->ldb, "loadparm"), + NULL, "password_hash", "create_aes_key", false); + if (io->domain->store_cleartext && (io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) { do_cleartext = true; @@ -881,6 +1055,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) /* * The ordering is this * + * Primary:Kerberos-Newer-Keys (optional) * Primary:Kerberos * Primary:WDigest * Primary:CLEARTEXT (optional) @@ -888,6 +1063,11 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) * And the 'Packages' package is insert before the last * other package. */ + if (do_newer_keys) { + /* Primary:Kerberos-Newer-Keys */ + nkn = &names[num_names++]; + pkn = &packages[num_packages++]; + } /* Primary:Kerberos */ nk = &names[num_names++]; @@ -911,6 +1091,39 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) pc = &packages[num_packages++]; } + if (pkn) { + /* + * setup 'Primary:Kerberos-Newer-Keys' element + */ + *nkn = "Kerberos-Newer-Keys"; + + ret = setup_primary_kerberos_newer(io, old_scb, &pknb); + if (ret != LDB_SUCCESS) { + return ret; + } + + ndr_err = ndr_push_struct_blob(&pknb_blob, io->ac, + lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), + &pknb, + (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosNewerBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + ldb_asprintf_errstring(io->ac->module->ldb, + "setup_supplemental_field: " + "failed to push package_PrimaryKerberosNeverBlob: %s", + nt_errstr(status)); + return LDB_ERR_OPERATIONS_ERROR; + } + pknb_hexstr = data_blob_hex_string(io->ac, &pknb_blob); + if (!pknb_hexstr) { + ldb_oom(io->ac->module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + pkn->name = "Primary:Kerberos-Newer-Keys"; + pkn->reserved = 1; + pkn->data = pknb_hexstr; + } + /* * setup 'Primary:Kerberos' element */ -- cgit From f9e61979244d94600261be4898f1091b00406c6f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 23 Jul 2008 14:07:06 +0200 Subject: dsdb: teach dreplsrv_out_drsuapi_bind_recv() knowledge of DsBindInfo48. To make it work against w2k8. Michael (This used to be commit a8aea9274170a2b472c45c97a4904bd299d2a92e) --- source4/dsdb/repl/drepl_out_helpers.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/dsdb') diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index 0700867543..345e3db1ab 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -146,6 +146,15 @@ static void dreplsrv_out_drsuapi_bind_recv(struct rpc_request *req) st->drsuapi->remote_info28.repl_epoch = 0; break; } + case 48: { + struct drsuapi_DsBindInfo48 *info48; + info48 = &st->bind_r.out.bind_info->info.info48; + st->drsuapi->remote_info28.supported_extensions = info48->supported_extensions; + st->drsuapi->remote_info28.site_guid = info48->site_guid; + st->drsuapi->remote_info28.pid = info48->pid; + st->drsuapi->remote_info28.repl_epoch = info48->repl_epoch; + break; + } case 28: st->drsuapi->remote_info28 = st->bind_r.out.bind_info->info.info28; break; -- cgit From db36f37b8f324ca2a45b05800d4abfb72c566447 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 23 Jul 2008 16:23:31 +0200 Subject: libnet_become_dc: send msDS_Behavior_Version == 3 (win2k8) in DsAddEntry instead of version 2 (win2k3). This makes the NET-API-BECOME-DC test work against windows 2003 and 2008. Michael (This used to be commit a7bfa1fb1bc6fb8e412990b7ff4c3ce9bc55099d) --- source4/dsdb/common/flags.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/dsdb') diff --git a/source4/dsdb/common/flags.h b/source4/dsdb/common/flags.h index 36111418e2..e8802fdf9c 100644 --- a/source4/dsdb/common/flags.h +++ b/source4/dsdb/common/flags.h @@ -122,3 +122,4 @@ #define DS_BEHAVIOR_WIN2000 0 #define DS_BEHAVIOR_WIN2003_INTERIM 1 #define DS_BEHAVIOR_WIN2003 2 +#define DS_BEHAVIOR_WIN2008 3 -- cgit From f619e08f8be7c3a20a71b679e73a7b7f57247f82 Mon Sep 17 00:00:00 2001 From: Anatoliy Atanasov Date: Wed, 23 Jul 2008 09:59:17 +0300 Subject: Handle schema reloading request. The ldif for that operation looks like this: dn: changetype: Modify add: schemaUpdateNow schemaUpdateNow: 1 It uses the rootdse's object functional attribute schemaUpdateNow. In rootdse_modify() this command is being recognized and it is send as extended operation with DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID. In the partition module its dispatched to the schema_fsmo module. The request is processed in the schema_fsmo module by schema_fsmo_extended(). (This used to be commit 39f9184ddf215f2b512319211c0a05702218ef87) --- source4/dsdb/samdb/ldb_modules/partition.c | 49 +++++++++++++++++++++ source4/dsdb/samdb/ldb_modules/rootdse.c | 47 ++++++++++++++++++-- source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 64 +++++++++++++++++++++++++++- source4/dsdb/samdb/samdb.h | 2 + 4 files changed, 158 insertions(+), 4 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 22826e4f33..9285d6d0d8 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -699,6 +699,50 @@ static int partition_extended_replicated_objects(struct ldb_module *module, stru return partition_replicate(module, req, ext->partition_dn); } +static int partition_extended_schema_update_now(struct ldb_module *module, struct ldb_request *req) +{ + struct dsdb_control_current_partition *partition; + struct partition_private_data *data; + struct ldb_dn *schema_dn; + struct partition_context *ac; + struct ldb_module *backend; + int ret; + + schema_dn = talloc_get_type(req->op.extended.data, struct ldb_dn); + if (!schema_dn) { + ldb_debug(module->ldb, LDB_DEBUG_FATAL, "partition_extended: invalid extended data\n"); + return LDB_ERR_PROTOCOL_ERROR; + } + + data = talloc_get_type(module->private_data, struct partition_private_data); + if (!data) { + return LDB_ERR_OPERATIONS_ERROR; + } + + partition = find_partition( data, schema_dn ); + if (!partition) { + return ldb_next_request(module, req); + } + + ac = partition_init_handle(req, module); + if (!ac) { + return LDB_ERR_OPERATIONS_ERROR; + } + + backend = make_module_for_next_request(req, module->ldb, partition->module); + if (!backend) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition); + if (ret != LDB_SUCCESS) { + return ret; + } + + return ldb_next_request(backend, req); +} + + /* extended */ static int partition_extended(struct ldb_module *module, struct ldb_request *req) { @@ -708,6 +752,11 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req return partition_extended_replicated_objects(module, req); } + /* forward schemaUpdateNow operation to schema_fsmo module*/ + if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) == 0) { + return partition_extended_schema_update_now( module, req ); + } + /* * as the extended operation has no dn * we need to send it to all partitions diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 75f99a139d..97491a2ae3 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -391,9 +391,50 @@ static int rootdse_init(struct ldb_module *module) return ldb_next_init(module); } +static int rootdse_modify(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_result *ext_res; + int ret; + struct ldb_dn *schema_dn; + struct ldb_message_element *schemaUpdateNowAttr; + + /* + If dn is not "" we should let it pass through + */ + if (!ldb_dn_is_null(req->op.mod.message->dn)) { + return ldb_next_request(module, req); + } + + /* + dn is empty so check for schemaUpdateNow attribute + "The type of modification and values specified in the LDAP modify operation do not matter." MSDN + */ + schemaUpdateNowAttr = ldb_msg_find_element(req->op.mod.message, "schemaUpdateNow"); + if (!schemaUpdateNowAttr) { + return LDB_ERR_OPERATIONS_ERROR; + } + + schema_dn = samdb_schema_dn(module->ldb); + if (!schema_dn) { + ldb_reset_err_string(module->ldb); + ldb_debug(module->ldb, LDB_DEBUG_WARNING, + "rootdse_modify: no schema dn present: (skip ldb_extended call)\n"); + return ldb_next_request(module, req); + } + + ret = ldb_extended(module->ldb, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID, schema_dn, &ext_res); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + talloc_free(ext_res); + return ret; +} + _PUBLIC_ const struct ldb_module_ops ldb_rootdse_module_ops = { .name = "rootdse", - .init_context = rootdse_init, - .search = rootdse_search, - .request = rootdse_request + .init_context = rootdse_init, + .search = rootdse_search, + .request = rootdse_request, + .modify = rootdse_modify }; diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index a397228723..2acc5c0af4 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -148,8 +148,70 @@ static int schema_fsmo_add(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(module, req); } +static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *req) +{ + WERROR status; + struct ldb_dn *schema_dn; + struct dsdb_schema *schema; + char *error_string = NULL; + int ret; + TALLOC_CTX *mem_ctx; + + if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) { + return ldb_next_request(module, req); + } + + schema_dn = samdb_schema_dn(module->ldb); + if (!schema_dn) { + ldb_reset_err_string(module->ldb); + ldb_debug(module->ldb, LDB_DEBUG_WARNING, + "schema_fsmo_extended: no schema dn present: (skip schema loading)\n"); + return ldb_next_request(module, req); + } + + mem_ctx = talloc_new(module); + if (!mem_ctx) { + ldb_oom(module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = dsdb_schema_from_schema_dn(mem_ctx, module->ldb, + lp_iconv_convenience(ldb_get_opaque(module->ldb, "loadparm")), + schema_dn, &schema, &error_string); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + ldb_reset_err_string(module->ldb); + ldb_debug(module->ldb, LDB_DEBUG_WARNING, + "schema_fsmo_extended: no schema head present: (skip schema loading)\n"); + talloc_free(mem_ctx); + return ldb_next_request(module, req); + } + + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(module->ldb, + "schema_fsmo_extended: dsdb_schema load failed: %s", + error_string); + talloc_free(mem_ctx); + return ldb_next_request(module, req); + } + + /* Replace the old schema*/ + ret = dsdb_set_schema(module->ldb, schema); + if (ret != LDB_SUCCESS) { + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "schema_fsmo_extended: dsdb_set_schema() failed: %d:%s", + ret, ldb_strerror(ret)); + talloc_free(mem_ctx); + return ret; + } + + talloc_free(mem_ctx); + return LDB_SUCCESS; +} + _PUBLIC_ const struct ldb_module_ops ldb_schema_fsmo_module_ops = { .name = "schema_fsmo", .init_context = schema_fsmo_init, - .add = schema_fsmo_add + .add = schema_fsmo_add, + .extended = schema_fsmo_extended }; diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index 75aa819ccd..b8a3e16d46 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -90,4 +90,6 @@ struct dsdb_pdc_fsmo { struct ldb_dn *master_dn; }; +#define DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID "1.3.6.1.4.1.7165.4.4.2" + #endif /* __SAMDB_H__ */ -- cgit From 05583308fe8278f1bc0c815e23cf5e470a81e12f Mon Sep 17 00:00:00 2001 From: Anatoliy Atanasov Date: Mon, 21 Jul 2008 17:04:49 +0300 Subject: dsdb_create_prefix_mapping() implementation checks for existing prefix maping in ldb. if one not found it creates a mapping for it and updates the prefixMap schema attribute in ldb. (This used to be commit bbe895db7144b192981fad9ab6bbd3ebacb8d299) --- source4/dsdb/schema/schema_init.c | 293 +++++++++++++++++++++++++++++++++----- 1 file changed, 257 insertions(+), 36 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 71d952b944..2ec5ad34b1 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -267,19 +267,146 @@ WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const } WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32_t *out) +{ + return dsdb_find_prefix_for_oid(schema->num_prefixes, schema->prefixes, in, out); +} + + +WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out) { uint32_t i; for (i=0; i < schema->num_prefixes; i++) { + const char *val; + if (schema->prefixes[i].id != (in & 0xFFFF0000)) { + continue; + } + + val = talloc_asprintf(mem_ctx, "%s%u", + schema->prefixes[i].oid, + in & 0xFFFF); + W_ERROR_HAVE_NO_MEMORY(val); + + *out = val; + return WERR_OK; + } + + return WERR_DS_NO_MSDS_INTID; +} + +/* + * this function is called from within a ldb transaction from the schema_fsmo module + */ +WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *schema, const char *full_oid) +{ + WERROR status; + uint32_t num_prefixes; + struct dsdb_schema_oid_prefix *prefixes; + struct ldb_val ndr_blob; + TALLOC_CTX *mem_ctx; + uint32_t out; + + mem_ctx = talloc_new(ldb); + W_ERROR_HAVE_NO_MEMORY(mem_ctx); + + /* Read prefixes from disk*/ + status = dsdb_read_prefixes_from_ldb( mem_ctx, ldb, &num_prefixes, &prefixes ); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("dsdb_create_prefix_mapping: dsdb_read_prefixes_from_ldb failed\n")); + talloc_free(mem_ctx); + return status; + } + + /* Check if there is a prefix for the oid in the prefixes array*/ + status = dsdb_find_prefix_for_oid( num_prefixes, prefixes, full_oid, &out ); + if (W_ERROR_IS_OK(status)) { + /* prefix found*/ + talloc_free(mem_ctx); + return status; + } + /* Update prefix map in ldb*/ + /* Update the prefixes */ + status = dsdb_prefix_map_update(mem_ctx, &num_prefixes, &prefixes, full_oid); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("dsdb_create_prefix_mapping: dsdb_prefix_map_update failed\n")); + talloc_free(mem_ctx); + return status; + } + /* Convert prefixes in ndr blob*/ + status = dsdb_write_prefixes_to_ndr( mem_ctx, ldb, num_prefixes, prefixes, &ndr_blob ); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("dsdb_create_prefix_mapping: dsdb_write_prefixes_to_ndr failed\n")); + talloc_free(mem_ctx); + return status; + } + + /* Update prefixMap in ldb*/ + status = dsdb_write_prefixes_to_ldb( mem_ctx, ldb, &ndr_blob ); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,("dsdb_create_prefix_mapping: dsdb_write_prefixes_to_ldb failed\n")); + talloc_free(mem_ctx); + return status; + } + + talloc_free(mem_ctx); + return status; +} + +WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struct dsdb_schema_oid_prefix **prefixes, const char *oid) +{ + uint32_t new_num_prefixes, index_new_prefix, new_entry_id; + const char* lastDotOffset; + size_t size; + + new_num_prefixes = *num_prefixes + 1; + index_new_prefix = *num_prefixes; + new_entry_id = (*num_prefixes)<<16; + + /* Extract the prefix from the oid*/ + lastDotOffset = strrchr(oid, '.'); + if (lastDotOffset == NULL) { + DEBUG(0,("dsdb_prefix_map_update: failed to find the last dot\n")); + return WERR_NOT_FOUND; + } + + /* Calculate the size of the remainig string that should be the prefix of it */ + size = strlen(oid) - strlen(lastDotOffset); + if (size <= 0) { + DEBUG(0,("dsdb_prefix_map_update: size of the remaining string invalid\n")); + return WERR_FOOBAR; + } + /* Add one because we need to copy the dot */ + size += 1; + + /* Create a spot in the prefixMap for one more prefix*/ + (*prefixes) = talloc_realloc(mem_ctx, *prefixes, struct dsdb_schema_oid_prefix, new_num_prefixes); + W_ERROR_HAVE_NO_MEMORY(*prefixes); + + /* Add the new prefix entry*/ + (*prefixes)[index_new_prefix].id = new_entry_id; + (*prefixes)[index_new_prefix].oid = talloc_strndup(mem_ctx, oid, size); + (*prefixes)[index_new_prefix].oid_len = strlen((*prefixes)[index_new_prefix].oid); + + /* Increase num_prefixes because new prefix has been added */ + ++(*num_prefixes); + + return WERR_OK; +} + +WERROR dsdb_find_prefix_for_oid(uint32_t num_prefixes, const struct dsdb_schema_oid_prefix *prefixes, const char *in, uint32_t *out) +{ + uint32_t i; + + for (i=0; i < num_prefixes; i++) { const char *val_str; char *end_str; unsigned val; - if (strncmp(schema->prefixes[i].oid, in, schema->prefixes[i].oid_len) != 0) { + if (strncmp(prefixes[i].oid, in, prefixes[i].oid_len) != 0) { continue; } - val_str = in + schema->prefixes[i].oid_len; + val_str = in + prefixes[i].oid_len; end_str = NULL; errno = 0; @@ -305,58 +432,152 @@ WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32 return WERR_INVALID_PARAM; } - *out = schema->prefixes[i].id | val; + *out = prefixes[i].id | val; return WERR_OK; } return WERR_DS_NO_MSDS_INTID; } -WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out) +WERROR dsdb_write_prefixes_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_val *ndr_blob) { + struct ldb_message msg; + struct ldb_dn *schema_dn; + struct ldb_message_element el; + int ret; + + schema_dn = samdb_schema_dn(ldb); + if (!schema_dn) { + DEBUG(0,("dsdb_write_prefixes_to_ldb: no schema dn present\n")); + return WERR_FOOBAR; + } + + el.num_values = 1; + el.values = ndr_blob; + el.flags = LDB_FLAG_MOD_REPLACE; + el.name = talloc_strdup(mem_ctx, "prefixMap"); + + msg.dn = ldb_dn_copy(mem_ctx, schema_dn); + msg.num_elements = 1; + msg.elements = ⪙ + + ret = ldb_modify( ldb, &msg ); + if (ret != 0) { + DEBUG(0,("dsdb_write_prefixes_to_ldb: ldb_modify failed\n")); + return WERR_FOOBAR; + } + + return WERR_OK; +} + +WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes) +{ + struct prefixMapBlob *blob; + enum ndr_err_code ndr_err; uint32_t i; + const struct ldb_val *prefix_val; + struct ldb_dn *schema_dn; + struct ldb_result *schema_res; + int ret; + static const char *schema_attrs[] = { + "prefixMap", + NULL + }; - for (i=0; i < schema->num_prefixes; i++) { - const char *val; - if (schema->prefixes[i].id != (in & 0xFFFF0000)) { - continue; - } + schema_dn = samdb_schema_dn(ldb); + if (!schema_dn) { + DEBUG(0,("dsdb_read_prefixes_from_ldb: no schema dn present\n")); + return WERR_FOOBAR; + } - val = talloc_asprintf(mem_ctx, "%s%u", - schema->prefixes[i].oid, - in & 0xFFFF); - W_ERROR_HAVE_NO_MEMORY(val); + ret = ldb_search(ldb, schema_dn, LDB_SCOPE_BASE,NULL, schema_attrs,&schema_res); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + DEBUG(0,("dsdb_read_prefixes_from_ldb: no prefix map present\n")); + return WERR_FOOBAR; + } else if (ret != LDB_SUCCESS) { + DEBUG(0,("dsdb_read_prefixes_from_ldb: failed to search the schema head\n")); + return WERR_FOOBAR; + } - *out = val; - return WERR_OK; + prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap"); + if (!prefix_val) { + DEBUG(0,("dsdb_read_prefixes_from_ldb: no prefixMap attribute found\n")); + return WERR_FOOBAR; } - return WERR_DS_NO_MSDS_INTID; + blob = talloc(mem_ctx, struct prefixMapBlob); + W_ERROR_HAVE_NO_MEMORY(blob); + + ndr_err = ndr_pull_struct_blob(prefix_val, blob, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + blob, + (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("dsdb_read_prefixes_from_ldb: ndr_pull_struct_blob failed\n")); + talloc_free(blob); + return WERR_FOOBAR; + } + + if (blob->version != PREFIX_MAP_VERSION_DSDB) { + DEBUG(0,("dsdb_read_prefixes_from_ldb: blob->version incorect\n")); + talloc_free(blob); + return WERR_FOOBAR; + } + + *num_prefixes = blob->ctr.dsdb.num_mappings; + *prefixes = talloc_array(mem_ctx, struct dsdb_schema_oid_prefix, *num_prefixes); + if(!(*prefixes)) { + talloc_free(blob); + return WERR_NOMEM; + } + for (i=0; i < blob->ctr.dsdb.num_mappings; i++) { + (*prefixes)[i].id = blob->ctr.dsdb.mappings[i].id_prefix<<16; + (*prefixes)[i].oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid); + (*prefixes)[i].oid = talloc_asprintf_append((*prefixes)[i].oid, "."); + (*prefixes)[i].oid_len = strlen(blob->ctr.dsdb.mappings[i].oid.oid); + } + + talloc_free(blob); + return WERR_OK; } -/* - * this function is called from within a ldb transaction from the schema_fsmo module - */ -WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *schema, const char *full_oid) + +WERROR dsdb_write_prefixes_to_ndr(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t num_prefixes, const struct dsdb_schema_oid_prefix *prefixes, struct ldb_val *out) { - /* - * TODO: - * - (maybe) read the old prefixMap attribute and parse it - * - * - recheck the prefix doesn't exist (because the ldb - * has maybe a more uptodate value than schem->prefixes - * - * - calculate a new mapping for the oid prefix of full_oid - * - store the new prefixMap attribute - * - * - (maybe) update schema->prefixes - * or - * - better find a way to indicate a schema reload, - * so that other processes also notice the schema change - */ - return WERR_NOT_SUPPORTED; + struct prefixMapBlob *blob; + enum ndr_err_code ndr_err; + uint32_t i; + + blob = talloc_zero(mem_ctx, struct prefixMapBlob); + W_ERROR_HAVE_NO_MEMORY(blob); + + blob->version = PREFIX_MAP_VERSION_DSDB; + blob->ctr.dsdb.num_mappings = num_prefixes; + blob->ctr.dsdb.mappings = talloc_realloc(blob, + blob->ctr.dsdb.mappings, + struct drsuapi_DsReplicaOIDMapping, + blob->ctr.dsdb.num_mappings); + if (!blob->ctr.dsdb.mappings) { + return WERR_NOMEM; + } + + for (i=0; i < num_prefixes; i++) { + blob->ctr.dsdb.mappings[i].id_prefix = prefixes[i].id>>16; + blob->ctr.dsdb.mappings[i].oid.oid = talloc_strdup(blob->ctr.dsdb.mappings, prefixes[i].oid); + } + + ndr_err = ndr_push_struct_blob(out, ldb, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + blob, + (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_FOOBAR; + } + + return WERR_OK; } + #define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \ (p)->elem = samdb_result_string(msg, attr, NULL);\ if (strict && (p)->elem == NULL) { \ -- cgit From 0c8fb9361e524639cc35efda2f6a4d48098c76a7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jul 2008 08:22:23 +0200 Subject: password_hash: fix the callers after drsblobs.idl changes metze (This used to be commit fac7c79afae05a88ecc2a63c8eb9f2fd53ab7ce6) --- source4/dsdb/samdb/ldb_modules/password_hash.c | 74 ++++++++++++++------------ 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 413ec12479..69783aefa8 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -437,10 +437,11 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, * ENCTYPE_DES_CBC_MD5 * ENCTYPE_DES_CBC_CRC */ + pkb->version = 3; pkb3->salt.string = io->g.salt; pkb3->num_keys = 2; pkb3->keys = talloc_array(io->ac, - struct package_PrimaryKerberosKey, + struct package_PrimaryKerberosKey3, pkb3->num_keys); if (!pkb3->keys) { ldb_oom(io->ac->module->ldb); @@ -521,12 +522,12 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, static int setup_primary_kerberos_newer(struct setup_password_fields_io *io, const struct supplementalCredentialsBlob *old_scb, - struct package_PrimaryKerberosNewerBlob *pkb) + struct package_PrimaryKerberosBlob *pkb) { - struct package_PrimaryKerberosNewerCtr4 *pkb4 = &pkb->ctr.ctr4; + struct package_PrimaryKerberosCtr4 *pkb4 = &pkb->ctr.ctr4; struct supplementalCredentialsPackage *old_scp = NULL; - struct package_PrimaryKerberosNewerBlob _old_pkb; - struct package_PrimaryKerberosNewerCtr4 *old_pkb4 = NULL; + struct package_PrimaryKerberosBlob _old_pkb; + struct package_PrimaryKerberosCtr4 *old_pkb4 = NULL; uint32_t i; enum ndr_err_code ndr_err; @@ -538,30 +539,37 @@ static int setup_primary_kerberos_newer(struct setup_password_fields_io *io, * ENCTYPE_DES_CBC_MD5 * ENCTYPE_DES_CBC_CRC */ - pkb4->salt.string = io->g.salt; - pkb4->num_keys = 4; - pkb4->keys = talloc_array(io->ac, - struct package_PrimaryKerberosNewerKey, - pkb4->num_keys); + pkb->version = 4; + pkb4->salt.string = io->g.salt; + pkb4->default_iteration_count = 4096; + pkb4->num_keys = 4; + + pkb4->keys = talloc_array(io->ac, + struct package_PrimaryKerberosKey4, + pkb4->num_keys); if (!pkb4->keys) { ldb_oom(io->ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } - pkb4->keys[0].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96; - pkb4->keys[0].value = &io->g.aes_256; - pkb4->keys[1].keytype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; - pkb4->keys[1].value = &io->g.aes_128; - pkb4->keys[2].keytype = ENCTYPE_DES_CBC_MD5; - pkb4->keys[2].value = &io->g.des_md5; - pkb4->keys[3].keytype = ENCTYPE_DES_CBC_CRC; - pkb4->keys[3].value = &io->g.des_crc; + pkb4->keys[0].iteration_count = 4096; + pkb4->keys[0].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96; + pkb4->keys[0].value = &io->g.aes_256; + pkb4->keys[1].iteration_count = 4096; + pkb4->keys[1].keytype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; + pkb4->keys[1].value = &io->g.aes_128; + pkb4->keys[2].iteration_count = 4096; + pkb4->keys[2].keytype = ENCTYPE_DES_CBC_MD5; + pkb4->keys[2].value = &io->g.des_md5; + pkb4->keys[3].iteration_count = 4096; + pkb4->keys[3].keytype = ENCTYPE_DES_CBC_CRC; + pkb4->keys[3].value = &io->g.des_crc; /* initialize the old keys to zero */ - pkb4->num_old_keys1 = 0; - pkb4->old_keys1 = NULL; - pkb4->num_old_keys2 = 0; - pkb4->old_keys2 = NULL; + pkb4->num_old_keys = 0; + pkb4->old_keys = NULL; + pkb4->num_older_keys = 0; + pkb4->older_keys = NULL; /* if there're no old keys, then we're done */ if (!old_scb) { @@ -580,7 +588,7 @@ static int setup_primary_kerberos_newer(struct setup_password_fields_io *io, old_scp = &old_scb->sub.packages[i]; break; } - /* Primary:Kerberos element of supplementalCredentials */ + /* Primary:Kerberos-Newer-Keys element of supplementalCredentials */ if (old_scp) { DATA_BLOB blob; @@ -595,20 +603,20 @@ static int setup_primary_kerberos_newer(struct setup_password_fields_io *io, ndr_err = ndr_pull_struct_blob(&blob, io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), &_old_pkb, - (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosNewerBlob); + (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); ldb_asprintf_errstring(io->ac->module->ldb, "setup_primary_kerberos_newer: " - "failed to pull old package_PrimaryKerberosNewerBlob: %s", + "failed to pull old package_PrimaryKerberosBlob: %s", nt_errstr(status)); return LDB_ERR_OPERATIONS_ERROR; } if (_old_pkb.version != 4) { ldb_asprintf_errstring(io->ac->module->ldb, - "setup_primary_kerberos: " - "package_PrimaryKerberosNewerBlob version[%u] expected[4]", + "setup_primary_kerberos_newer: " + "package_PrimaryKerberosBlob version[%u] expected[4]", _old_pkb.version); return LDB_ERR_OPERATIONS_ERROR; } @@ -622,10 +630,10 @@ static int setup_primary_kerberos_newer(struct setup_password_fields_io *io, } /* fill in the old keys */ - pkb4->num_old_keys1 = old_pkb4->num_keys; - pkb4->old_keys1 = old_pkb4->keys; - pkb4->num_old_keys2 = old_pkb4->num_old_keys1; - pkb4->old_keys2 = old_pkb4->old_keys1; + pkb4->num_old_keys = old_pkb4->num_keys; + pkb4->old_keys = old_pkb4->keys; + pkb4->num_older_keys = old_pkb4->num_old_keys; + pkb4->older_keys = old_pkb4->old_keys; return LDB_SUCCESS; } @@ -980,7 +988,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) /* Primary:Kerberos-Newer-Keys */ const char **nkn = NULL; struct supplementalCredentialsPackage *pkn = NULL; - struct package_PrimaryKerberosNewerBlob pknb; + struct package_PrimaryKerberosBlob pknb; DATA_BLOB pknb_blob; char *pknb_hexstr; /* Primary:Kerberos */ @@ -1105,7 +1113,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) ndr_err = ndr_push_struct_blob(&pknb_blob, io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), &pknb, - (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosNewerBlob); + (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); ldb_asprintf_errstring(io->ac->module->ldb, -- cgit From d65f89f7b9ba749691c04a9c95e3c8eac77c492c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Jul 2008 08:44:00 +1000 Subject: Clarify how we are doing the 'this is a rootdse query' check. (This used to be commit 8dfba3160cc4bc518f3ad8570d104e5baae784ca) --- source4/dsdb/samdb/ldb_modules/rootdse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 75f99a139d..7414d36973 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -263,9 +263,10 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req) struct ldb_request *down_req; int ret; - /* see if its for the rootDSE */ + /* see if its for the rootDSE - only a base search on the "" DN qualifies */ if (req->op.search.scope != LDB_SCOPE_BASE || ( ! ldb_dn_is_null(req->op.search.base))) { + /* Otherwise, pass down to the rest of the stack */ return ldb_next_request(module, req); } -- cgit From 404846d8871d3d420e83a3e48625bb051faf893e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Jul 2008 11:58:24 +1000 Subject: Try to avoid a memory leak if we re-set the global schema However, try also not to pull a schema out from under a running ldb session. Andrew Bartlett (This used to be commit 7cf9b9dd0bb35835a7c6e9897ea99951a33c63c7) --- source4/dsdb/schema/schema_init.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 71d952b944..75457b4bea 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -1534,6 +1534,11 @@ int dsdb_set_global_schema(struct ldb_context *ldb) return ret; } + /* Keep a reference to this schema, just incase the global copy is replaced */ + if (talloc_reference(ldb, global_schema) == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; } @@ -1571,6 +1576,10 @@ void dsdb_make_schema_global(struct ldb_context *ldb) return; } + if (global_schema) { + talloc_unlink(talloc_autofree_context(), schema); + } + talloc_steal(talloc_autofree_context(), schema); global_schema = schema; -- cgit From 118ecc54ba19330b30d207e51611ff5f85b2cdca Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jul 2008 09:53:29 +0200 Subject: dsdb/schema: dsdb_write_prefixes_to_ldb() should do the reverse of dsdb_read_prefixes_to_ldb() metze (This used to be commit 34ea9d4a0b1270a27412bf939d7e897a5d68d0a6) --- source4/dsdb/schema/schema_init.c | 96 ++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 52 deletions(-) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 706c8e24d2..2385f224e8 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -302,7 +302,6 @@ WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *s WERROR status; uint32_t num_prefixes; struct dsdb_schema_oid_prefix *prefixes; - struct ldb_val ndr_blob; TALLOC_CTX *mem_ctx; uint32_t out; @@ -312,7 +311,8 @@ WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *s /* Read prefixes from disk*/ status = dsdb_read_prefixes_from_ldb( mem_ctx, ldb, &num_prefixes, &prefixes ); if (!W_ERROR_IS_OK(status)) { - DEBUG(0,("dsdb_create_prefix_mapping: dsdb_read_prefixes_from_ldb failed\n")); + DEBUG(0,("dsdb_create_prefix_mapping: dsdb_read_prefixes_from_ldb: %s\n", + win_errstr(status))); talloc_free(mem_ctx); return status; } @@ -323,27 +323,28 @@ WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *s /* prefix found*/ talloc_free(mem_ctx); return status; - } - /* Update prefix map in ldb*/ - /* Update the prefixes */ - status = dsdb_prefix_map_update(mem_ctx, &num_prefixes, &prefixes, full_oid); - if (!W_ERROR_IS_OK(status)) { - DEBUG(0,("dsdb_create_prefix_mapping: dsdb_prefix_map_update failed\n")); + } else if (!W_ERROR_EQUAL(WERR_DS_NO_MSDS_INTID, status)) { + /* error */ + DEBUG(0,("dsdb_create_prefix_mapping: dsdb_find_prefix_for_oid: %s\n", + win_errstr(status))); talloc_free(mem_ctx); return status; } - /* Convert prefixes in ndr blob*/ - status = dsdb_write_prefixes_to_ndr( mem_ctx, ldb, num_prefixes, prefixes, &ndr_blob ); + + /* Create the new mapping for the prefix of full_oid */ + status = dsdb_prefix_map_update(mem_ctx, &num_prefixes, &prefixes, full_oid); if (!W_ERROR_IS_OK(status)) { - DEBUG(0,("dsdb_create_prefix_mapping: dsdb_write_prefixes_to_ndr failed\n")); + DEBUG(0,("dsdb_create_prefix_mapping: dsdb_prefix_map_update: %s\n", + win_errstr(status))); talloc_free(mem_ctx); return status; } /* Update prefixMap in ldb*/ - status = dsdb_write_prefixes_to_ldb( mem_ctx, ldb, &ndr_blob ); + status = dsdb_write_prefixes_to_ldb(mem_ctx, ldb, num_prefixes, prefixes); if (!W_ERROR_IS_OK(status)) { - DEBUG(0,("dsdb_create_prefix_mapping: dsdb_write_prefixes_to_ldb failed\n")); + DEBUG(0,("dsdb_create_prefix_mapping: dsdb_write_prefixes_to_ldb: %s\n", + win_errstr(status))); talloc_free(mem_ctx); return status; } @@ -439,11 +440,17 @@ WERROR dsdb_find_prefix_for_oid(uint32_t num_prefixes, const struct dsdb_schema_ return WERR_DS_NO_MSDS_INTID; } -WERROR dsdb_write_prefixes_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_val *ndr_blob) +WERROR dsdb_write_prefixes_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, + uint32_t num_prefixes, + const struct dsdb_schema_oid_prefix *prefixes) { struct ldb_message msg; struct ldb_dn *schema_dn; struct ldb_message_element el; + struct prefixMapBlob pm; + struct ldb_val ndr_blob; + enum ndr_err_code ndr_err; + uint32_t i; int ret; schema_dn = samdb_schema_dn(ldb); @@ -451,9 +458,31 @@ WERROR dsdb_write_prefixes_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, DEBUG(0,("dsdb_write_prefixes_to_ldb: no schema dn present\n")); return WERR_FOOBAR; } + + pm.version = PREFIX_MAP_VERSION_DSDB; + pm.ctr.dsdb.num_mappings = num_prefixes; + pm.ctr.dsdb.mappings = talloc_array(mem_ctx, + struct drsuapi_DsReplicaOIDMapping, + pm.ctr.dsdb.num_mappings); + if (!pm.ctr.dsdb.mappings) { + return WERR_NOMEM; + } + + for (i=0; i < num_prefixes; i++) { + pm.ctr.dsdb.mappings[i].id_prefix = prefixes[i].id>>16; + pm.ctr.dsdb.mappings[i].oid.oid = talloc_strdup(pm.ctr.dsdb.mappings, prefixes[i].oid); + } + + ndr_err = ndr_push_struct_blob(&ndr_blob, ldb, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + &pm, + (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_FOOBAR; + } el.num_values = 1; - el.values = ndr_blob; + el.values = &ndr_blob; el.flags = LDB_FLAG_MOD_REPLACE; el.name = talloc_strdup(mem_ctx, "prefixMap"); @@ -541,43 +570,6 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, return WERR_OK; } - -WERROR dsdb_write_prefixes_to_ndr(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t num_prefixes, const struct dsdb_schema_oid_prefix *prefixes, struct ldb_val *out) -{ - struct prefixMapBlob *blob; - enum ndr_err_code ndr_err; - uint32_t i; - - blob = talloc_zero(mem_ctx, struct prefixMapBlob); - W_ERROR_HAVE_NO_MEMORY(blob); - - blob->version = PREFIX_MAP_VERSION_DSDB; - blob->ctr.dsdb.num_mappings = num_prefixes; - blob->ctr.dsdb.mappings = talloc_realloc(blob, - blob->ctr.dsdb.mappings, - struct drsuapi_DsReplicaOIDMapping, - blob->ctr.dsdb.num_mappings); - if (!blob->ctr.dsdb.mappings) { - return WERR_NOMEM; - } - - for (i=0; i < num_prefixes; i++) { - blob->ctr.dsdb.mappings[i].id_prefix = prefixes[i].id>>16; - blob->ctr.dsdb.mappings[i].oid.oid = talloc_strdup(blob->ctr.dsdb.mappings, prefixes[i].oid); - } - - ndr_err = ndr_push_struct_blob(out, ldb, - lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - blob, - (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return WERR_FOOBAR; - } - - return WERR_OK; -} - - #define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \ (p)->elem = samdb_result_string(msg, attr, NULL);\ if (strict && (p)->elem == NULL) { \ -- cgit From 2385e33095bbf01076b1e591f95e20eba7a7df37 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jul 2008 09:55:53 +0200 Subject: dsdb/schema: make more clear where we create the value for the new prefix mapping metze (This used to be commit c92eb8b776c17f12622837daeb1786862f380269) --- source4/dsdb/schema/schema_init.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/dsdb') diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 2385f224e8..9b8959466d 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -361,6 +361,12 @@ WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struc new_num_prefixes = *num_prefixes + 1; index_new_prefix = *num_prefixes; + + /* + * this is the algorithm we use to create new mappings for now + * + * TODO: find what algorithm windows use + */ new_entry_id = (*num_prefixes)<<16; /* Extract the prefix from the oid*/ -- cgit From c0ad44f354933a3c2eeaa66d8e16bcd2f14924ca Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Jul 2008 10:00:20 +0200 Subject: dsdb: add a comment about the parameter to DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID metze (This used to be commit 2f06fbe06be2e1b77ea013ddba853ce819e58e88) --- source4/dsdb/samdb/samdb.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/dsdb') diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index b8a3e16d46..3e92671fa0 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -90,6 +90,10 @@ struct dsdb_pdc_fsmo { struct ldb_dn *master_dn; }; +/* + * the schema_dn is passed as struct ldb_dn in + * req->op.extended.data + */ #define DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID "1.3.6.1.4.1.7165.4.4.2" #endif /* __SAMDB_H__ */ -- cgit