summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb/ldb_modules
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules')
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn.c4
-rw-r--r--source4/dsdb/samdb/ldb_modules/kludge_acl.c12
-rw-r--r--source4/dsdb/samdb/ldb_modules/naming_fsmo.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c14
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectguid.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/partition.c246
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c201
-rw-r--r--source4/dsdb/samdb/ldb_modules/pdc_fsmo.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/proxy.c8
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c24
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c4
-rw-r--r--source4/dsdb/samdb/ldb_modules/simple_ldap_map.c68
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
};