diff options
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/extended_dn.c | 4 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/kludge_acl.c | 12 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/naming_fsmo.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/objectclass.c | 14 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/objectguid.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/partition.c | 246 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 201 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/pdc_fsmo.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/proxy.c | 8 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 24 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_fsmo.c | 4 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/simple_ldap_map.c | 68 |
13 files changed, 413 insertions, 176 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn.c b/source4/dsdb/samdb/ldb_modules/extended_dn.c index 88a8887056..a0602d9281 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn.c @@ -424,7 +424,7 @@ static int extended_search(struct ldb_module *module, struct ldb_request *req) valstr = str; } else { DATA_BLOB binary; - binary = strhex_to_data_blob(str); + binary = strhex_to_data_blob(NULL, str); if (!binary.data) { ldb_oom(module->ldb); return LDB_ERR_OPERATIONS_ERROR; @@ -471,7 +471,7 @@ static int extended_search(struct ldb_module *module, struct ldb_request *req) valstr = str; } else { DATA_BLOB binary; - binary = strhex_to_data_blob(str); + binary = strhex_to_data_blob(NULL, str); if (!binary.data) { ldb_oom(module->ldb); return LDB_ERR_OPERATIONS_ERROR; diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c index 6e6da5581d..6acbf45afd 100644 --- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c +++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c @@ -141,7 +141,7 @@ static int kludge_acl_allowedAttributes(struct ldb_context *ldb, struct ldb_mess ldb_msg_add_string(msg, attrName, attr_list[i]); } talloc_free(mem_ctx); - return 0; + return LDB_SUCCESS; } /* read all objectClasses */ @@ -201,7 +201,7 @@ static int kludge_acl_childClasses(struct ldb_context *ldb, struct ldb_message * } } - return 0; + return LDB_SUCCESS; } @@ -250,14 +250,14 @@ static int kludge_acl_callback(struct ldb_request *req, struct ldb_reply *ares) case SECURITY_SYSTEM: if (ac->allowedAttributesEffective) { ret = kludge_acl_allowedAttributes(ac->module->ldb, ares->message, - "allowedClassesAttributesEffective"); + "allowedAttributesEffective"); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } } if (ac->allowedChildClassesEffective) { ret = kludge_acl_childClasses(ac->module->ldb, ares->message, - "allowedClassesChildClassesEffective"); + "allowedChildClassesEffective"); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } @@ -267,14 +267,14 @@ static int kludge_acl_callback(struct ldb_request *req, struct ldb_reply *ares) case SECURITY_ADMINISTRATOR: if (ac->allowedAttributesEffective) { ret = kludge_acl_allowedAttributes(ac->module->ldb, ares->message, - "allowedClassesAttributesEffective"); + "allowedAttributesEffective"); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } } if (ac->allowedChildClassesEffective) { ret = kludge_acl_childClasses(ac->module->ldb, ares->message, - "allowedClassesChildClassesEffective"); + "allowedChildClassesEffective"); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } diff --git a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c index 70f3e8ddfd..d90c2547a6 100644 --- a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c @@ -29,7 +29,7 @@ #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" static int naming_fsmo_init(struct ldb_module *module) { diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 2c242d47c6..7d00851792 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -38,7 +38,7 @@ #include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "dsdb/samdb/samdb.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_security.h" #include "libcli/security/security.h" @@ -382,11 +382,17 @@ static int fix_attributes(struct ldb_context *ldb, const struct dsdb_schema *sch int i; for (i=0; i < msg->num_elements; i++) { const struct dsdb_attribute *attribute = dsdb_attribute_by_lDAPDisplayName(schema, msg->elements[i].name); + /* Add in a very special case for 'clearTextPassword', + * which is used for internal processing only, and is + * not presented in the schema */ if (!attribute) { - ldb_asprintf_errstring(ldb, "attribute %s is not a valid attribute in schema", msg->elements[i].name); - return LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE; + if (strcasecmp(msg->elements[i].name, "clearTextPassword") != 0) { + ldb_asprintf_errstring(ldb, "attribute %s is not a valid attribute in schema", msg->elements[i].name); + return LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE; + } + } else { + msg->elements[i].name = attribute->lDAPDisplayName; } - msg->elements[i].name = attribute->lDAPDisplayName; } return LDB_SUCCESS; diff --git a/source4/dsdb/samdb/ldb_modules/objectguid.c b/source4/dsdb/samdb/ldb_modules/objectguid.c index 054905992d..3d725686e7 100644 --- a/source4/dsdb/samdb/ldb_modules/objectguid.c +++ b/source4/dsdb/samdb/ldb_modules/objectguid.c @@ -194,7 +194,7 @@ static int objectguid_add(struct ldb_module *module, struct ldb_request *req) } /* Get a sequence number from the backend */ - /* FIXME: ldb_sequence_number is still SYNC now, when this changes, + /* FIXME: ldb_sequence_number is a semi-async call, * make sure this function is split and a callback is used */ ret = ldb_sequence_number(module->ldb, LDB_SEQ_NEXT, &seq_num); if (ret == LDB_SUCCESS) { diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index b452b66d56..b4a7a47a23 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -115,10 +115,6 @@ int partition_request(struct ldb_module *module, struct ldb_request *request) PARTITION_FIND_OP(module, extended); ret = module->ops->extended(module, request); break; - case LDB_SEQUENCE_NUMBER: - PARTITION_FIND_OP(module, sequence_number); - ret = module->ops->sequence_number(module, request); - break; default: PARTITION_FIND_OP(module, request); ret = module->ops->request(module, request); @@ -716,9 +712,8 @@ static int partition_del_trans(struct ldb_module *module) return ret2; } -/* NOTE: ldb_sequence_number is still a completely SYNCHRONOUS call - * implemented only in ldb_rdb. It does not require ldb_wait() to be - * called after a request is made */ + +/* FIXME: This function is still semi-async */ static int partition_sequence_number(struct ldb_module *module, struct ldb_request *req) { int i, ret; @@ -727,113 +722,241 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque uint64_t timestamp = 0; struct partition_private_data *data = talloc_get_type(module->private_data, struct partition_private_data); + struct ldb_seqnum_request *seq; + struct ldb_seqnum_result *seqr; + struct ldb_request *treq; + struct ldb_seqnum_request *tseq; + struct ldb_seqnum_result *tseqr; + struct ldb_extended *ext; + struct ldb_result *res; - switch (req->op.seq_num.type) { + seq = talloc_get_type(req->op.extended.data, struct ldb_seqnum_request); + + switch (seq->type) { case LDB_SEQ_NEXT: case LDB_SEQ_HIGHEST_SEQ: - ret = ldb_next_request(module, req); - if (ret != LDB_SUCCESS) { - return ret; + res = talloc_zero(req, struct ldb_result); + if (res == NULL) { + return LDB_ERR_OPERATIONS_ERROR; } - if (req->op.seq_num.flags & LDB_SEQ_TIMESTAMP_SEQUENCE) { - timestamp_sequence = req->op.seq_num.seq_num; - } else { - seq_number = seq_number + req->op.seq_num.seq_num; + tseq = talloc_zero(res, struct ldb_seqnum_request); + if (tseq == NULL) { + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; + } + tseq->type = seq->type; + + ret = ldb_build_extended_req(&treq, module->ldb, res, + LDB_EXTENDED_SEQUENCE_NUMBER, + tseq, + NULL, + res, + ldb_extended_default_callback, + NULL); + ret = ldb_next_request(module, treq); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(treq->handle, LDB_WAIT_ALL); } - - /* gross hack part1 */ - ret = ldb_request_add_control(req, - DSDB_CONTROL_CURRENT_PARTITION_OID, - false, NULL); if (ret != LDB_SUCCESS) { + talloc_free(res); return ret; } + seqr = talloc_get_type(res->extended->data, + struct ldb_seqnum_result); + if (seqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) { + timestamp_sequence = seqr->seq_num; + } else { + seq_number += seqr->seq_num; + } + talloc_free(res); - /* Look at base DN */ - /* Figure out which partition it is under */ /* Skip the lot if 'data' isn't here yet (initialistion) */ for (i=0; data && data->partitions && data->partitions[i]; i++) { - /* gross hack part2 */ - int j; - for (j=0; req->controls[j]; j++) { - if (strcmp(req->controls[j]->oid, DSDB_CONTROL_CURRENT_PARTITION_OID) == 0) { - req->controls[j]->data = data->partitions[i]; - break; - } + res = talloc_zero(req, struct ldb_result); + if (res == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + tseq = talloc_zero(res, struct ldb_seqnum_request); + if (tseq == NULL) { + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; + } + tseq->type = seq->type; + + ret = ldb_build_extended_req(&treq, module->ldb, res, + LDB_EXTENDED_SEQUENCE_NUMBER, + tseq, + NULL, + res, + ldb_extended_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; } - ret = partition_request(data->partitions[i]->module, req); + ret = ldb_request_add_control(treq, + DSDB_CONTROL_CURRENT_PARTITION_OID, + false, data->partitions[i]); if (ret != LDB_SUCCESS) { + talloc_free(res); return ret; } - if (req->op.seq_num.flags & LDB_SEQ_TIMESTAMP_SEQUENCE) { - timestamp_sequence = MAX(timestamp_sequence, req->op.seq_num.seq_num); + + ret = partition_request(data->partitions[i]->module, treq); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; + } + ret = ldb_wait(treq->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; + } + tseqr = talloc_get_type(res->extended->data, + struct ldb_seqnum_result); + if (tseqr->flags & LDB_SEQ_TIMESTAMP_SEQUENCE) { + timestamp_sequence = MAX(timestamp_sequence, + tseqr->seq_num); } else { - seq_number = seq_number + req->op.seq_num.seq_num; + seq_number += tseqr->seq_num; } + talloc_free(res); } - /* fall though */ + /* fall through */ case LDB_SEQ_HIGHEST_TIMESTAMP: - { - struct ldb_request *date_req = talloc(req, struct ldb_request); - if (!date_req) { + + res = talloc_zero(req, struct ldb_result); + if (res == NULL) { return LDB_ERR_OPERATIONS_ERROR; } - *date_req = *req; - date_req->op.seq_num.flags = LDB_SEQ_HIGHEST_TIMESTAMP; - ret = ldb_next_request(module, date_req); + tseq = talloc_zero(res, struct ldb_seqnum_request); + if (tseq == NULL) { + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; + } + tseq->type = LDB_SEQ_HIGHEST_TIMESTAMP; + + ret = ldb_build_extended_req(&treq, module->ldb, res, + LDB_EXTENDED_SEQUENCE_NUMBER, + tseq, + NULL, + res, + ldb_extended_default_callback, + NULL); if (ret != LDB_SUCCESS) { + talloc_free(res); return ret; } - timestamp = date_req->op.seq_num.seq_num; - /* Look at base DN */ - /* Figure out which partition it is under */ + ret = ldb_next_request(module, treq); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; + } + ret = ldb_wait(treq->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; + } + + tseqr = talloc_get_type(res->extended->data, + struct ldb_seqnum_result); + timestamp = tseqr->seq_num; + + talloc_free(res); + /* Skip the lot if 'data' isn't here yet (initialistion) */ for (i=0; data && data->partitions && data->partitions[i]; i++) { - ret = partition_request(data->partitions[i]->module, req); + res = talloc_zero(req, struct ldb_result); + if (res == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + tseq = talloc_zero(res, struct ldb_seqnum_request); + if (tseq == NULL) { + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; + } + tseq->type = LDB_SEQ_HIGHEST_TIMESTAMP; + + ret = ldb_build_extended_req(&treq, module->ldb, res, + LDB_EXTENDED_SEQUENCE_NUMBER, + tseq, + NULL, + res, + ldb_extended_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; + } + + ret = partition_request(data->partitions[i]->module, treq); if (ret != LDB_SUCCESS) { + talloc_free(res); return ret; } - timestamp = MAX(timestamp, date_req->op.seq_num.seq_num); + ret = ldb_wait(treq->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + talloc_free(res); + return ret; + } + + tseqr = talloc_get_type(res->extended->data, + struct ldb_seqnum_result); + timestamp = MAX(timestamp, tseqr->seq_num); + + talloc_free(res); } + break; } + + ext = talloc_zero(req, struct ldb_extended); + if (!ext) { + return LDB_ERR_OPERATIONS_ERROR; } + seqr = talloc_zero(ext, struct ldb_seqnum_result); + if (seqr == NULL) { + talloc_free(ext); + return LDB_ERR_OPERATIONS_ERROR; + } + ext->oid = LDB_EXTENDED_SEQUENCE_NUMBER; + ext->data = seqr; - switch (req->op.seq_num.flags) { + switch (seq->type) { case LDB_SEQ_NEXT: case LDB_SEQ_HIGHEST_SEQ: - req->op.seq_num.flags = 0; - /* Has someone above set a timebase sequence? */ if (timestamp_sequence) { - req->op.seq_num.seq_num = (((unsigned long long)timestamp << 24) | (seq_number & 0xFFFFFF)); + seqr->seq_num = (((unsigned long long)timestamp << 24) | (seq_number & 0xFFFFFF)); } else { - req->op.seq_num.seq_num = seq_number; + seqr->seq_num = seq_number; } - if (timestamp_sequence > req->op.seq_num.seq_num) { - req->op.seq_num.seq_num = timestamp_sequence; - req->op.seq_num.flags |= LDB_SEQ_TIMESTAMP_SEQUENCE; + if (timestamp_sequence > seqr->seq_num) { + seqr->seq_num = timestamp_sequence; + seqr->flags |= LDB_SEQ_TIMESTAMP_SEQUENCE; } - req->op.seq_num.flags |= LDB_SEQ_GLOBAL_SEQUENCE; + seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE; break; case LDB_SEQ_HIGHEST_TIMESTAMP: - req->op.seq_num.seq_num = timestamp; + seqr->seq_num = timestamp; break; } - switch (req->op.seq_num.flags) { - case LDB_SEQ_NEXT: - req->op.seq_num.seq_num++; + if (seq->type == LDB_SEQ_NEXT) { + seqr->seq_num++; } - return LDB_SUCCESS; + + /* send request done */ + return ldb_module_done(req, NULL, ext, LDB_SUCCESS); } static int partition_extended_replicated_objects(struct ldb_module *module, struct ldb_request *req) @@ -906,6 +1029,10 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req return ldb_next_request(module, req); } + if (strcmp(req->op.extended.oid, LDB_EXTENDED_SEQUENCE_NUMBER) == 0) { + return partition_sequence_number(module, req); + } + if (strcmp(req->op.extended.oid, DSDB_EXTENDED_REPLICATED_OBJECTS_OID) == 0) { return partition_extended_replicated_objects(module, req); } @@ -1204,7 +1331,6 @@ _PUBLIC_ const struct ldb_module_ops ldb_partition_module_ops = { .del = partition_delete, .rename = partition_rename, .extended = partition_extended, - .sequence_number = partition_sequence_number, .start_transaction = partition_start_trans, .end_transaction = partition_end_trans, .del_transaction = partition_del_trans, diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index e36de3c5c4..5ed7f1fbad 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -109,7 +109,8 @@ struct setup_password_fields_io { /* new credentials */ struct { - const char *cleartext; + const struct ldb_val *cleartext_utf8; + const struct ldb_val *cleartext_utf16; struct samr_Password *nt_hash; struct samr_Password *lm_hash; } n; @@ -144,6 +145,9 @@ struct setup_password_fields_io { } g; }; +/* Get the NT hash, and fill it in as an entry in the password history, + and specify it into io->g.nt_hash */ + static int setup_nt_fields(struct setup_password_fields_io *io) { uint32_t i; @@ -181,6 +185,9 @@ static int setup_nt_fields(struct setup_password_fields_io *io) return LDB_SUCCESS; } +/* Get the LANMAN hash, and fill it in as an entry in the password history, + and specify it into io->g.lm_hash */ + static int setup_lm_fields(struct setup_password_fields_io *io) { uint32_t i; @@ -220,6 +227,10 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) Principal *salt_principal; krb5_salt salt; krb5_keyblock key; + krb5_data cleartext_data; + + cleartext_data.data = io->n.cleartext_utf8->data; + cleartext_data.length = io->n.cleartext_utf8->length; /* Many, many thanks to lukeh@padl.com for this * algorithm, described in his Nov 10 2004 mail to @@ -314,11 +325,11 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) * 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); + krb5_ret = krb5_string_to_key_data_salt(io->smb_krb5_context->krb5_context, + ENCTYPE_AES256_CTS_HMAC_SHA1_96, + cleartext_data, + salt, + &key); if (krb5_ret) { ldb_asprintf_errstring(io->ac->module->ldb, "setup_kerberos_keys: " @@ -339,11 +350,11 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) * 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); + krb5_ret = krb5_string_to_key_data_salt(io->smb_krb5_context->krb5_context, + ENCTYPE_AES128_CTS_HMAC_SHA1_96, + cleartext_data, + salt, + &key); if (krb5_ret) { ldb_asprintf_errstring(io->ac->module->ldb, "setup_kerberos_keys: " @@ -364,11 +375,11 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) * 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_DES_CBC_MD5, - io->n.cleartext, - salt, - &key); + krb5_ret = krb5_string_to_key_data_salt(io->smb_krb5_context->krb5_context, + ENCTYPE_DES_CBC_MD5, + cleartext_data, + salt, + &key); if (krb5_ret) { ldb_asprintf_errstring(io->ac->module->ldb, "setup_kerberos_keys: " @@ -389,11 +400,11 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) * 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_CRC, - io->n.cleartext, - salt, - &key); + krb5_ret = krb5_string_to_key_data_salt(io->smb_krb5_context->krb5_context, + ENCTYPE_DES_CBC_CRC, + cleartext_data, + salt, + &key); if (krb5_ret) { ldb_asprintf_errstring(io->ac->module->ldb, "setup_kerberos_keys: " @@ -471,12 +482,11 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io, if (old_scp) { DATA_BLOB blob; - blob = strhex_to_data_blob(old_scp->data); + blob = strhex_to_data_blob(io->ac, 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, @@ -585,12 +595,11 @@ static int setup_primary_kerberos_newer(struct setup_password_fields_io *io, if (old_scp) { DATA_BLOB blob; - blob = strhex_to_data_blob(old_scp->data); + blob = strhex_to_data_blob(io->ac, 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, @@ -648,7 +657,6 @@ static int setup_primary_wdigest(struct setup_password_fields_io *io, DATA_BLOB dns_domain; DATA_BLOB dns_domain_l; DATA_BLOB dns_domain_u; - DATA_BLOB cleartext; DATA_BLOB digest; DATA_BLOB delim; DATA_BLOB backslash; @@ -929,8 +937,6 @@ static int setup_primary_wdigest(struct setup_password_fields_io *io, dns_domain_l = data_blob_string_const(io->domain->dns_domain); dns_domain_u = data_blob_string_const(io->domain->realm); - cleartext = data_blob_string_const(io->n.cleartext); - digest = data_blob_string_const("Digest"); delim = data_blob_string_const(":"); @@ -956,7 +962,7 @@ static int setup_primary_wdigest(struct setup_password_fields_io *io, MD5Update(&md5, wdigest[i].realm->data, wdigest[i].realm->length); } MD5Update(&md5, delim.data, delim.length); - MD5Update(&md5, cleartext.data, cleartext.length); + MD5Update(&md5, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length); MD5Final(pdb->hashes[i].hash, &md5); } @@ -1011,7 +1017,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) ZERO_STRUCT(zero16); ZERO_STRUCT(names); - if (!io->n.cleartext) { + if (!io->n.cleartext_utf8) { /* * when we don't have a cleartext password * we can't setup a supplementalCredential value @@ -1193,7 +1199,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io) if (pc) { *nc = "CLEARTEXT"; - pcb.cleartext = io->n.cleartext; + pcb.cleartext = *io->n.cleartext_utf16; ndr_err = ndr_push_struct_blob(&pcb_blob, io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), @@ -1285,58 +1291,97 @@ static int setup_password_fields(struct setup_password_fields_io *io) { bool ok; int ret; - + ssize_t converted_pw_len; + /* * refuse the change if someone want to change the cleartext * and supply his own hashes at the same time... */ - if (io->n.cleartext && (io->n.nt_hash || io->n.lm_hash)) { + if ((io->n.cleartext_utf8 || io->n.cleartext_utf16) && (io->n.nt_hash || io->n.lm_hash)) { ldb_asprintf_errstring(io->ac->module->ldb, "setup_password_fields: " "it's only allowed to set the cleartext password or the password hashes"); return LDB_ERR_UNWILLING_TO_PERFORM; } - - if (io->n.cleartext) { - struct samr_Password *hash; - - hash = talloc(io->ac, struct samr_Password); - if (!hash) { + + if (io->n.cleartext_utf8 && io->n.cleartext_utf16) { + ldb_asprintf_errstring(io->ac->module->ldb, + "setup_password_fields: " + "it's only allowed to set the cleartext password as userPassword or clearTextPasssword, not both at once"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + if (io->n.cleartext_utf8) { + char **cleartext_utf16_str; + struct ldb_val *cleartext_utf16_blob; + io->n.cleartext_utf16 = cleartext_utf16_blob = talloc(io->ac, struct ldb_val); + if (!io->n.cleartext_utf16) { ldb_oom(io->ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } - - /* compute the new nt hash */ - ok = E_md4hash(io->n.cleartext, hash->hash); - if (ok) { - io->n.nt_hash = hash; - } else { + converted_pw_len = convert_string_talloc(io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), + CH_UTF8, CH_UTF16, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length, + (void **)&cleartext_utf16_str); + if (converted_pw_len == -1) { ldb_asprintf_errstring(io->ac->module->ldb, "setup_password_fields: " - "failed to generate nthash from cleartext password"); + "failed to generate UTF16 password from cleartext UTF8 password"); + return LDB_ERR_OPERATIONS_ERROR; + } + *cleartext_utf16_blob = data_blob_const(cleartext_utf16_str, converted_pw_len); + } else if (io->n.cleartext_utf16) { + char *cleartext_utf8_str; + struct ldb_val *cleartext_utf8_blob; + io->n.cleartext_utf8 = cleartext_utf8_blob = talloc(io->ac, struct ldb_val); + if (!io->n.cleartext_utf8) { + ldb_oom(io->ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } + converted_pw_len = convert_string_talloc(io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), + CH_UTF16, CH_UTF8, io->n.cleartext_utf16->data, io->n.cleartext_utf16->length, + (void **)&cleartext_utf8_str); + if (converted_pw_len == -1) { + /* We can't bail out entirely, as these unconvertable passwords are frustratingly valid */ + io->n.cleartext_utf8 = NULL; + talloc_free(cleartext_utf8_blob); + } + *cleartext_utf8_blob = data_blob_const(cleartext_utf8_str, converted_pw_len); } - - if (io->n.cleartext) { - struct samr_Password *hash; - - hash = talloc(io->ac, struct samr_Password); - if (!hash) { + if (io->n.cleartext_utf16) { + struct samr_Password *nt_hash; + nt_hash = talloc(io->ac, struct samr_Password); + if (!nt_hash) { ldb_oom(io->ac->module->ldb); return LDB_ERR_OPERATIONS_ERROR; } + io->n.nt_hash = nt_hash; - /* compute the new lm hash */ - ok = E_deshash(io->n.cleartext, hash->hash); - if (ok) { - io->n.lm_hash = hash; - } else { - talloc_free(hash->hash); - } + /* compute the new nt hash */ + mdfour(nt_hash->hash, io->n.cleartext_utf16->data, io->n.cleartext_utf16->length); } - if (io->n.cleartext) { + if (io->n.cleartext_utf8) { + struct samr_Password *lm_hash; + char *cleartext_unix; + converted_pw_len = convert_string_talloc(io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), + CH_UTF8, CH_UNIX, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length, + (void **)&cleartext_unix); + if (converted_pw_len != -1) { + lm_hash = talloc(io->ac, struct samr_Password); + if (!lm_hash) { + ldb_oom(io->ac->module->ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* compute the new lm hash. */ + ok = E_deshash((char *)cleartext_unix, lm_hash->hash); + if (ok) { + io->n.lm_hash = lm_hash; + } else { + talloc_free(lm_hash->hash); + } + } + ret = setup_kerberos_keys(io); if (ret != 0) { return ret; @@ -1560,6 +1605,7 @@ static int password_hash_add(struct ldb_module *module, struct ldb_request *req) { struct ph_context *ac; struct ldb_message_element *sambaAttr; + struct ldb_message_element *clearTextPasswordAttr; struct ldb_message_element *ntAttr; struct ldb_message_element *lmAttr; int ret; @@ -1591,6 +1637,7 @@ static int password_hash_add(struct ldb_module *module, struct ldb_request *req) * or LM hashes, then we don't need to make any changes. */ sambaAttr = ldb_msg_find_element(req->op.mod.message, "userPassword"); + clearTextPasswordAttr = ldb_msg_find_element(req->op.mod.message, "clearTextPassword"); ntAttr = ldb_msg_find_element(req->op.mod.message, "unicodePwd"); lmAttr = ldb_msg_find_element(req->op.mod.message, "dBCSPwd"); @@ -1611,6 +1658,10 @@ static int password_hash_add(struct ldb_module *module, struct ldb_request *req) ldb_set_errstring(module->ldb, "mupltiple values for userPassword not allowed!\n"); return LDB_ERR_CONSTRAINT_VIOLATION; } + if (clearTextPasswordAttr && clearTextPasswordAttr->num_values > 1) { + ldb_set_errstring(module->ldb, "mupltiple values for clearTextPassword not allowed!\n"); + return LDB_ERR_CONSTRAINT_VIOLATION; + } if (ntAttr && (ntAttr->num_values > 1)) { ldb_set_errstring(module->ldb, "mupltiple values for unicodePwd not allowed!\n"); @@ -1626,6 +1677,11 @@ static int password_hash_add(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_CONSTRAINT_VIOLATION; } + if (clearTextPasswordAttr && clearTextPasswordAttr->num_values == 0) { + ldb_set_errstring(module->ldb, "clearTextPassword must have a value!\n"); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + if (ntAttr && (ntAttr->num_values == 0)) { ldb_set_errstring(module->ldb, "unicodePwd must have a value!\n"); return LDB_ERR_CONSTRAINT_VIOLATION; @@ -1687,12 +1743,14 @@ static int password_hash_add_do_add(struct ph_context *ac) { io.u.user_principal_name = samdb_result_string(msg, "userPrincipalName", NULL); io.u.is_computer = ldb_msg_check_string_attribute(msg, "objectClass", "computer"); - io.n.cleartext = samdb_result_string(msg, "userPassword", NULL); + io.n.cleartext_utf8 = ldb_msg_find_ldb_val(msg, "userPassword"); + io.n.cleartext_utf16 = ldb_msg_find_ldb_val(msg, "clearTextPassword"); io.n.nt_hash = samdb_result_hash(io.ac, msg, "unicodePwd"); io.n.lm_hash = samdb_result_hash(io.ac, msg, "dBCSPwd"); /* remove attributes */ - if (io.n.cleartext) ldb_msg_remove_attr(msg, "userPassword"); + if (io.n.cleartext_utf8) ldb_msg_remove_attr(msg, "userPassword"); + if (io.n.cleartext_utf16) ldb_msg_remove_attr(msg, "clearTextPassword"); if (io.n.nt_hash) ldb_msg_remove_attr(msg, "unicodePwd"); if (io.n.lm_hash) ldb_msg_remove_attr(msg, "dBCSPwd"); ldb_msg_remove_attr(msg, "pwdLastSet"); @@ -1772,6 +1830,7 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r { struct ph_context *ac; struct ldb_message_element *sambaAttr; + struct ldb_message_element *clearTextAttr; struct ldb_message_element *ntAttr; struct ldb_message_element *lmAttr; struct ldb_message *msg; @@ -1802,13 +1861,16 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r } sambaAttr = ldb_msg_find_element(req->op.mod.message, "userPassword"); + clearTextAttr = ldb_msg_find_element(req->op.mod.message, "clearTextPassword"); ntAttr = ldb_msg_find_element(req->op.mod.message, "unicodePwd"); lmAttr = ldb_msg_find_element(req->op.mod.message, "dBCSPwd"); - /* If no part of this touches the userPassword OR unicodePwd and/or dBCSPwd, then we don't - * need to make any changes. For password changes/set there should - * be a 'delete' or a 'modify' on this attribute. */ - if ((!sambaAttr) && (!ntAttr) && (!lmAttr)) { + /* If no part of this touches the userPassword OR + * clearTextPassword OR unicodePwd and/or dBCSPwd, then we + * don't need to make any changes. For password changes/set + * there should be a 'delete' or a 'modify' on this + * attribute. */ + if ((!sambaAttr) && (!clearTextAttr) && (!ntAttr) && (!lmAttr)) { return ldb_next_request(module, req); } @@ -1817,6 +1879,9 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r if (sambaAttr && (sambaAttr->num_values > 1)) { return LDB_ERR_CONSTRAINT_VIOLATION; } + if (clearTextAttr && (clearTextAttr->num_values > 1)) { + return LDB_ERR_CONSTRAINT_VIOLATION; + } if (ntAttr && (ntAttr->num_values > 1)) { return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -1839,6 +1904,7 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r /* - remove any modification to the password from the first commit * we will make the real modification later */ if (sambaAttr) ldb_msg_remove_attr(msg, "userPassword"); + if (clearTextAttr) ldb_msg_remove_attr(msg, "clearTextPassword"); if (ntAttr) ldb_msg_remove_attr(msg, "unicodePwd"); if (lmAttr) ldb_msg_remove_attr(msg, "dBCSPwd"); @@ -2028,7 +2094,8 @@ static int password_hash_mod_do_mod(struct ph_context *ac) { io.u.user_principal_name = samdb_result_string(searched_msg, "userPrincipalName", NULL); io.u.is_computer = ldb_msg_check_string_attribute(searched_msg, "objectClass", "computer"); - io.n.cleartext = samdb_result_string(orig_msg, "userPassword", NULL); + io.n.cleartext_utf8 = ldb_msg_find_ldb_val(orig_msg, "userPassword"); + io.n.cleartext_utf16 = ldb_msg_find_ldb_val(orig_msg, "clearTextPassword"); io.n.nt_hash = samdb_result_hash(io.ac, orig_msg, "unicodePwd"); io.n.lm_hash = samdb_result_hash(io.ac, orig_msg, "dBCSPwd"); diff --git a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c index a5e7031a26..198b667358 100644 --- a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c @@ -28,7 +28,7 @@ #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" static int pdc_fsmo_init(struct ldb_module *module) { diff --git a/source4/dsdb/samdb/ldb_modules/proxy.c b/source4/dsdb/samdb/ldb_modules/proxy.c index 18b0649dda..2ff42297b7 100644 --- a/source4/dsdb/samdb/ldb_modules/proxy.c +++ b/source4/dsdb/samdb/ldb_modules/proxy.c @@ -73,7 +73,7 @@ static int load_proxy_info(struct ldb_module *module) /* see if we have already loaded it */ if (proxy->upstream != NULL) { - return 0; + return LDB_SUCCESS; } dn = ldb_dn_new(proxy, module->ldb, "@PROXYINFO"); @@ -152,7 +152,7 @@ static int load_proxy_info(struct ldb_module *module) talloc_free(res); - return 0; + return LDB_SUCCESS; failed: talloc_free(res); @@ -160,7 +160,7 @@ failed: talloc_free(proxy->newdn); talloc_free(proxy->upstream); proxy->upstream = NULL; - return -1; + return LDB_ERR_OPERATIONS_ERROR; } @@ -317,7 +317,7 @@ static int proxy_search_bytree(struct ldb_module *module, struct ldb_request *re goto passthru; } - if (load_proxy_info(module) != 0) { + if (load_proxy_info(module) != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 13a979b6f8..f30748c85c 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -90,16 +90,16 @@ static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) char *s; if (ldb_msg_find_element(msg, attr) != NULL) { - return 0; + return LDB_SUCCESS; } s = ldb_timestring(msg, t); if (s == NULL) { - return -1; + return LDB_ERR_OPERATIONS_ERROR; } - if (ldb_msg_add_string(msg, attr, s) != 0) { - return -1; + if (ldb_msg_add_string(msg, attr, s) != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; } el = ldb_msg_find_element(msg, attr); @@ -107,7 +107,7 @@ static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) is ignored */ el->flags = LDB_FLAG_MOD_REPLACE; - return 0; + return LDB_SUCCESS; } /* @@ -118,11 +118,11 @@ static int add_uint64_element(struct ldb_message *msg, const char *attr, uint64_ struct ldb_message_element *el; if (ldb_msg_find_element(msg, attr) != NULL) { - return 0; + return LDB_SUCCESS; } - if (ldb_msg_add_fmt(msg, attr, "%llu", (unsigned long long)v) != 0) { - return -1; + if (ldb_msg_add_fmt(msg, attr, "%llu", (unsigned long long)v) != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; } el = ldb_msg_find_element(msg, attr); @@ -130,7 +130,7 @@ static int add_uint64_element(struct ldb_message *msg, const char *attr, uint64_ is ignored */ el->flags = LDB_FLAG_MOD_REPLACE; - return 0; + return LDB_SUCCESS; } static int replmd_replPropertyMetaData1_attid_sort(const struct replPropertyMetaData1 *m1, @@ -270,7 +270,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req) ac->schema = schema; - if (ldb_msg_find_element(req->op.add.message, "objectGUID")) { + if (ldb_msg_find_element(req->op.add.message, "objectGUID") != NULL) { ldb_debug_set(module->ldb, LDB_DEBUG_ERROR, "replmd_add: it's not allowed to add an object with objectGUID\n"); return LDB_ERR_UNWILLING_TO_PERFORM; @@ -495,7 +495,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) * - calculate the new replPropertyMetaData attribute */ - if (add_time_element(msg, "whenChanged", t) != 0) { + if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) { talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } @@ -503,7 +503,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) /* Get a sequence number from the backend */ ret = ldb_sequence_number(module->ldb, LDB_SEQ_NEXT, &seq_num); if (ret == LDB_SUCCESS) { - if (add_uint64_element(msg, "uSNChanged", seq_num) != 0) { + if (add_uint64_element(msg, "uSNChanged", seq_num) != LDB_SUCCESS) { talloc_free(ac); return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index a71ffff618..f6e735df79 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -41,7 +41,7 @@ #include "dsdb/samdb/samdb.h" #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_security.h" -#include "util/util_ldb.h" +#include "../lib/util/util_ldb.h" #include "ldb_wrap.h" struct samldb_ctx; diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index 56d24a2962..0266654811 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -29,7 +29,7 @@ #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" -#include "lib/util/dlinklist.h" +#include "../lib/util/dlinklist.h" #include "param/param.h" static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg, @@ -319,7 +319,7 @@ static int generate_dITContentRules(struct ldb_context *ldb, struct ldb_message } } } - return 0; + return LDB_SUCCESS; } diff --git a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c index d15e85ad41..c353914e2c 100644 --- a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c +++ b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c @@ -603,10 +603,18 @@ static int nsuniqueid_init(struct ldb_module *module) return ldb_next_init(module); } -static int get_seq(struct ldb_request *req, - struct ldb_reply *ares) +static int get_seq_callback(struct ldb_request *req, + struct ldb_reply *ares) { unsigned long long *seq = (unsigned long long *)req->context; + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, ares->error); + } + if (ares->type == LDB_REPLY_ENTRY) { struct ldb_message_element *el = ldb_msg_find_element(ares->message, "contextCSN"); if (el) { @@ -618,6 +626,7 @@ static int get_seq(struct ldb_request *req, return ldb_request_done(req, LDB_SUCCESS); } + talloc_free(ares); return LDB_SUCCESS; } @@ -626,7 +635,7 @@ static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque int ret; struct map_private *map_private; struct entryuuid_private *entryuuid_private; - unsigned long long seq = 0; + unsigned long long seq_num = 0; struct ldb_request *search_req; const struct ldb_control *partition_ctrl; @@ -636,6 +645,12 @@ static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque "contextCSN", NULL }; + struct ldb_seqnum_request *seq; + struct ldb_seqnum_result *seqr; + struct ldb_extended *ext; + + seq = talloc_get_type(req->op.extended.data, struct ldb_seqnum_request); + map_private = talloc_get_type(module->private_data, struct map_private); entryuuid_private = talloc_get_type(map_private->caller_private, struct entryuuid_private); @@ -655,7 +670,7 @@ static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque ret = ldb_build_search_req(&search_req, module->ldb, req, partition->dn, LDB_SCOPE_BASE, NULL, contextCSN_attr, NULL, - &seq, get_seq, + &seq_num, get_seq_callback, NULL); if (ret != LDB_SUCCESS) { return ret; @@ -672,36 +687,59 @@ static int entryuuid_sequence_number(struct ldb_module *module, struct ldb_reque return ret; } - switch (req->op.seq_num.type) { + ext = talloc_zero(req, struct ldb_extended); + if (!ext) { + return LDB_ERR_OPERATIONS_ERROR; + } + seqr = talloc_zero(req, struct ldb_seqnum_result); + if (seqr == NULL) { + talloc_free(ext); + return LDB_ERR_OPERATIONS_ERROR; + } + ext->oid = LDB_EXTENDED_SEQUENCE_NUMBER; + ext->data = seqr; + + switch (seq->type) { case LDB_SEQ_HIGHEST_SEQ: - req->op.seq_num.seq_num = seq; + seqr->seq_num = seq_num; break; case LDB_SEQ_NEXT: - req->op.seq_num.seq_num = seq; - req->op.seq_num.seq_num++; + seqr->seq_num = seq_num; + seqr->seq_num++; break; case LDB_SEQ_HIGHEST_TIMESTAMP: { - req->op.seq_num.seq_num = (seq >> 24); + seqr->seq_num = (seq_num >> 24); break; } } - req->op.seq_num.flags = 0; - req->op.seq_num.flags |= LDB_SEQ_TIMESTAMP_SEQUENCE; - req->op.seq_num.flags |= LDB_SEQ_GLOBAL_SEQUENCE; - return LDB_SUCCESS; + seqr->flags = 0; + seqr->flags |= LDB_SEQ_TIMESTAMP_SEQUENCE; + seqr->flags |= LDB_SEQ_GLOBAL_SEQUENCE; + + /* send request done */ + return ldb_module_done(req, NULL, ext, LDB_SUCCESS); +} + +static int entryuuid_extended(struct ldb_module *module, struct ldb_request *req) +{ + if (strcmp(req->op.extended.oid, LDB_EXTENDED_SEQUENCE_NUMBER) == 0) { + return entryuuid_sequence_number(module, req); + } + + return ldb_next_request(module, req); } _PUBLIC_ const struct ldb_module_ops ldb_entryuuid_module_ops = { .name = "entryuuid", .init_context = entryuuid_init, - .sequence_number = entryuuid_sequence_number, + .extended = entryuuid_extended, LDB_MAP_OPS }; _PUBLIC_ const struct ldb_module_ops ldb_nsuniqueid_module_ops = { .name = "nsuniqueid", .init_context = nsuniqueid_init, - .sequence_number = entryuuid_sequence_number, + .extended = entryuuid_extended, LDB_MAP_OPS }; |