summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_load.c93
-rw-r--r--source4/dsdb/schema/schema.h2
2 files changed, 81 insertions, 14 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/schema_load.c b/source4/dsdb/samdb/ldb_modules/schema_load.c
index 5dd8fb78c9..d13b339f60 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_load.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_load.c
@@ -42,6 +42,14 @@ struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct dsdb_s
{
uint64_t current_usn;
int ret;
+ struct ldb_result *res;
+ struct ldb_request *treq;
+ struct ldb_seqnum_request *tseq;
+ struct ldb_seqnum_result *tseqr;
+ struct dsdb_control_current_partition *ctrl;
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
+ struct dsdb_schema *new_schema;
+
struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
if (!private_data) {
/* We can't refresh until the init function has run */
@@ -53,22 +61,79 @@ struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct dsdb_s
return schema;
}
+ res = talloc_zero(schema, struct ldb_result);
+ if (res == NULL) {
+ return NULL;
+ }
+ tseq = talloc_zero(res, struct ldb_seqnum_request);
+ if (tseq == NULL) {
+ talloc_free(res);
+ return NULL;
+ }
+ tseq->type = LDB_SEQ_HIGHEST_SEQ;
+
+ ret = ldb_build_extended_req(&treq, ldb_module_get_ctx(module), res,
+ LDB_EXTENDED_SEQUENCE_NUMBER,
+ tseq,
+ NULL,
+ res,
+ ldb_extended_default_callback,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(res);
+ return NULL;
+ }
+
+ ctrl = talloc(treq, struct dsdb_control_current_partition);
+ if (!ctrl) {
+ talloc_free(res);
+ return NULL;
+ }
+ ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
+ ctrl->dn = schema->base_dn;
+
+ ret = ldb_request_add_control(treq,
+ DSDB_CONTROL_CURRENT_PARTITION_OID,
+ false, ctrl);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(res);
+ return NULL;
+ }
+
+ ret = ldb_next_request(module, treq);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(res);
+ return NULL;
+ }
+ ret = ldb_wait(treq->handle, LDB_WAIT_ALL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(res);
+ return NULL;
+ }
+ tseqr = talloc_get_type(res->extended->data,
+ struct ldb_seqnum_result);
+ if (tseqr->seq_num == schema->reload_seq_number) {
+ talloc_free(res);
+ return schema;
+ }
+
+ schema->reload_seq_number = tseqr->seq_num;
+ talloc_free(res);
+
ret = dsdb_module_load_partition_usn(module, schema->base_dn, &current_usn, NULL);
- if (ret == LDB_SUCCESS && current_usn != schema->loaded_usn) {
- struct ldb_context *ldb = ldb_module_get_ctx(module);
- struct dsdb_schema *new_schema;
-
- ret = dsdb_schema_from_db(module, schema->base_dn, current_usn, &new_schema);
- if (ret != LDB_SUCCESS) {
- return schema;
- }
-
- if (is_global_schema) {
- dsdb_make_schema_global(ldb, new_schema);
- }
- return new_schema;
+ if (ret != LDB_SUCCESS || current_usn == schema->loaded_usn) {
+ return schema;
+ }
+
+ ret = dsdb_schema_from_db(module, schema->base_dn, current_usn, &new_schema);
+ if (ret != LDB_SUCCESS) {
+ return schema;
+ }
+
+ if (is_global_schema) {
+ dsdb_make_schema_global(ldb, new_schema);
}
- return schema;
+ return new_schema;
}
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index b5334c7313..7283744f7d 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -213,6 +213,8 @@ struct dsdb_schema {
struct ldb_module *loaded_from_module;
struct dsdb_schema *(*refresh_fn)(struct ldb_module *module, struct dsdb_schema *schema, bool is_global_schema);
bool refresh_in_progress;
+ /* an 'opaque' sequence number that the reload function may also wish to use */
+ uint64_t reload_seq_number;
};
enum dsdb_attr_list_query {