summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-09-13 18:13:17 +1000
committerAndrew Tridgell <tridge@samba.org>2009-09-13 16:40:00 -0700
commit424d1c580a68d8464411de755a07fcadcd882677 (patch)
treeecde088a3d7f2c5cc48f7237129388114b762dd8 /source4/dsdb
parent80c575923f40def2770b7ed2b95f458c605c6ece (diff)
downloadsamba-424d1c580a68d8464411de755a07fcadcd882677.tar.gz
samba-424d1c580a68d8464411de755a07fcadcd882677.tar.bz2
samba-424d1c580a68d8464411de755a07fcadcd882677.zip
s4-dsdb: added dsdb_load_partition_usn and dsdb_save_partition_usn
These are used to load/save the per-partition uSN values managed by the repl_meta_data module
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/common/util.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index b5005444cc..c2636e127f 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2257,3 +2257,149 @@ failed:
}
+/*
+ load the uSNHighest attribute from the @REPLCHANGED object for a
+ partition
+ */
+int dsdb_load_partition_usn(struct ldb_context *ldb, struct ldb_dn *dn, uint64_t *uSN)
+{
+ struct ldb_request *req;
+ int ret;
+ TALLOC_CTX *tmp_ctx = talloc_new(ldb);
+ struct dsdb_control_current_partition *p_ctrl;
+ struct ldb_result *res;
+
+ res = talloc_zero(tmp_ctx, struct ldb_result);
+ if (!res) {
+ talloc_free(tmp_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_search_req(&req, ldb, tmp_ctx,
+ ldb_dn_new(tmp_ctx, ldb, "@REPLCHANGED"),
+ LDB_SCOPE_BASE,
+ NULL, NULL,
+ NULL,
+ res, ldb_search_default_callback,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ p_ctrl = talloc(req, struct dsdb_control_current_partition);
+ if (p_ctrl == NULL) {
+ talloc_free(res);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ p_ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
+ p_ctrl->dn = dn;
+
+
+ ret = ldb_request_add_control(req,
+ DSDB_CONTROL_CURRENT_PARTITION_OID,
+ false, p_ctrl);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ /* Run the new request */
+ ret = ldb_request(ldb, req);
+
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+ }
+
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ if (res->count < 1) {
+ *uSN = 0;
+ } else {
+ *uSN = ldb_msg_find_attr_as_uint64(res->msgs[0], "uSNHighest", 0);
+ }
+
+ talloc_free(tmp_ctx);
+
+ return LDB_SUCCESS;
+}
+
+/*
+ save the uSNHighest attribute in the @REPLCHANGED object for a
+ partition
+ */
+int dsdb_save_partition_usn(struct ldb_context *ldb, struct ldb_dn *dn, uint64_t uSN)
+{
+ struct ldb_request *req;
+ struct ldb_message *msg;
+ struct dsdb_control_current_partition *p_ctrl;
+ int ret;
+
+ msg = ldb_msg_new(ldb);
+ if (msg == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ msg->dn = ldb_dn_new(msg, ldb, "@REPLCHANGED");
+ if (msg->dn == NULL) {
+ talloc_free(msg);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_msg_add_fmt(msg, "uSNHighest", "%llu", (unsigned long long)uSN);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
+ return ret;
+ }
+ msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
+
+
+ p_ctrl = talloc(msg, struct dsdb_control_current_partition);
+ if (p_ctrl == NULL) {
+ talloc_free(msg);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ p_ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
+ p_ctrl->dn = dn;
+
+ ret = ldb_build_mod_req(&req, ldb, msg,
+ msg,
+ NULL,
+ NULL, ldb_op_default_callback,
+ NULL);
+again:
+ if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
+ return ret;
+ }
+
+ ret = ldb_request_add_control(req,
+ DSDB_CONTROL_CURRENT_PARTITION_OID,
+ false, p_ctrl);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(msg);
+ return ret;
+ }
+
+ /* Run the new request */
+ ret = ldb_request(ldb, req);
+
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+ }
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ ret = ldb_build_add_req(&req, ldb, msg,
+ msg,
+ NULL,
+ NULL, ldb_op_default_callback,
+ NULL);
+ goto again;
+ }
+
+ talloc_free(msg);
+
+ return ret;
+}