summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 59dc2ec928..489985a22f 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -514,12 +514,14 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
if( !allow_add_guid ) {
ldb_debug_set(ldb, LDB_DEBUG_ERROR,
"replmd_add: it's not allowed to add an object with objectGUID\n");
+ talloc_free(ac);
return LDB_ERR_UNWILLING_TO_PERFORM;
} else {
NTSTATUS status = GUID_from_data_blob(guid_blob,&guid);
if ( !NT_STATUS_IS_OK(status)) {
ldb_debug_set(ldb, LDB_DEBUG_ERROR,
"replmd_add: Unable to parse as a GUID the attribute objectGUID\n");
+ talloc_free(ac);
return LDB_ERR_UNWILLING_TO_PERFORM;
}
/* we remove this attribute as it can be a string and will not be treated
@@ -534,15 +536,16 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
/* Get a sequence number from the backend */
ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, &seq_num);
if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
return ret;
}
-
/* get our invocationId */
our_invocation_id = samdb_ntds_invocation_id(ldb);
if (!our_invocation_id) {
ldb_debug_set(ldb, LDB_DEBUG_ERROR,
"replmd_add: unable to find invocationId\n");
+ talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -550,6 +553,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
msg = ldb_msg_copy_shallow(ac, req->op.add.message);
if (msg == NULL) {
ldb_oom(ldb);
+ talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -557,6 +561,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
unix_to_nt_time(&now, t);
time_str = ldb_timestring(msg, t);
if (!time_str) {
+ ldb_oom(ldb);
+ talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
if (remove_current_guid) {
@@ -576,7 +582,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
ret = ldb_msg_add_fmt(msg, "instanceType", "%u", INSTANCE_TYPE_WRITE);
if (ret != LDB_SUCCESS) {
ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ talloc_free(ac);
+ return ret;
}
}
@@ -586,7 +593,8 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
ret = ldb_msg_add_string(msg, "whenCreated", time_str);
if (ret != LDB_SUCCESS) {
ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
+ talloc_free(ac);
+ return ret;
}
/* build the replication meta_data */
@@ -598,6 +606,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
nmd.ctr.ctr1.count);
if (!nmd.ctr.ctr1.array) {
ldb_oom(ldb);
+ talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -613,6 +622,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
ldb_debug_set(ldb, LDB_DEBUG_ERROR,
"replmd_add: attribute '%s' not defined in schema\n",
e->name);
+ talloc_free(ac);
return LDB_ERR_NO_SUCH_ATTRIBUTE;
}
@@ -640,6 +650,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
*/
ret = replmd_replPropertyMetaDataCtr1_sort(&nmd.ctr.ctr1, schema, msg->dn);
if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
return ret;
}
@@ -650,6 +661,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
(ndr_push_flags_fn_t)ndr_push_GUID);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
ldb_oom(ldb);
+ talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
ndr_err = ndr_push_struct_blob(&nmd_value, msg,
@@ -658,6 +670,7 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
(ndr_push_flags_fn_t)ndr_push_replPropertyMetaDataBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
ldb_oom(ldb);
+ talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -667,26 +680,31 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
ret = ldb_msg_add_value(msg, "objectGUID", &guid_value, NULL);
if (ret != LDB_SUCCESS) {
ldb_oom(ldb);
+ talloc_free(ac);
return ret;
}
ret = ldb_msg_add_string(msg, "whenChanged", time_str);
if (ret != LDB_SUCCESS) {
ldb_oom(ldb);
+ talloc_free(ac);
return ret;
}
ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNCreated", seq_num);
if (ret != LDB_SUCCESS) {
ldb_oom(ldb);
+ talloc_free(ac);
return ret;
}
ret = samdb_msg_add_uint64(ldb, msg, msg, "uSNChanged", seq_num);
if (ret != LDB_SUCCESS) {
ldb_oom(ldb);
+ talloc_free(ac);
return ret;
}
ret = ldb_msg_add_value(msg, "replPropertyMetaData", &nmd_value, NULL);
if (ret != LDB_SUCCESS) {
ldb_oom(ldb);
+ talloc_free(ac);
return ret;
}
@@ -701,16 +719,19 @@ static int replmd_add(struct ldb_module *module, struct ldb_request *req)
ac, replmd_op_callback,
req);
if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
return ret;
}
ret = replmd_notify(module, msg->dn, seq_num);
if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
return ret;
}
/* if a control is there remove if from the modified request */
if (control && !save_controls(control, down_req, &saved_controls)) {
+ talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -818,7 +839,7 @@ static int replmd_update_rpmd(struct ldb_module *module,
/* search for the existing replPropertyMetaDataBlob */
ret = dsdb_search_dn_with_deleted(ldb, msg, &res, msg->dn, attrs);
- if (ret != LDB_SUCCESS || res->count < 1) {
+ if (ret != LDB_SUCCESS || res->count != 1) {
DEBUG(0,(__location__ ": Object %s failed to find replPropertyMetaData\n",
ldb_dn_get_linearized(msg->dn)));
return LDB_ERR_OPERATIONS_ERROR;
@@ -913,9 +934,10 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
const struct dsdb_schema *schema;
struct ldb_request *down_req;
struct ldb_message *msg;
- int ret;
+ struct ldb_result *res;
time_t t = time(NULL);
uint64_t seq_num = 0;
+ int ret;
/* do not manipulate our control entries */
if (ldb_dn_is_special(req->op.mod.message->dn)) {
@@ -944,13 +966,12 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
/* we have to copy the message as the caller might have it as a const */
msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
if (msg == NULL) {
+ ldb_oom(ldb);
talloc_free(ac);
return LDB_ERR_OPERATIONS_ERROR;
}
/* TODO:
- * - get the whole old object
- * - if the old object doesn't exist report an error
* - give an error when a readonly attribute should
* be modified
* - merge the changed into the old object
@@ -959,8 +980,15 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
* attribute was changed
*/
+ ret = dsdb_search_dn_with_deleted(ldb, msg, &res, msg->dn, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
+ return ret;
+ }
+
ret = replmd_update_rpmd(module, msg, &seq_num);
if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
return ret;
}
@@ -974,6 +1002,7 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
ac, replmd_op_callback,
req);
if (ret != LDB_SUCCESS) {
+ talloc_free(ac);
return ret;
}
talloc_steal(down_req, msg);
@@ -983,12 +1012,12 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req)
if (seq_num != 0) {
if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) {
talloc_free(ac);
- return LDB_ERR_OPERATIONS_ERROR;
+ return ret;
}
if (add_uint64_element(msg, "uSNChanged", seq_num) != LDB_SUCCESS) {
talloc_free(ac);
- return LDB_ERR_OPERATIONS_ERROR;
+ return ret;
}
}