[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Mon Mar 22 03:27:12 MDT 2010


The branch, master has been updated
       via  f8019ff... s4:dsdb Add a shortcut sequence number for schema reloads
       via  fe3e1af... s4:dsdb Rework schema loading and add schema reloading
       via  d0b5447... s4:dsdb Move dsdb_save_partition_usn() to be a module helper function
       via  639728a... s4:schema Expand the schema structure
       via  775c5ec... s4:dsdb Remove unused 'dsdb_make_schema_global' call from pyglue
       via  7fc94eb... s4:dsdb Add 'const' to some struct dsdb_schema variables
       via  fc5a507... s4:dsdb Don't load the schema unconditionally
      from  8195832... s3: file_walk_table -> files_forall

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f8019ff793a735563ccedf5581c72e015fd62014
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 22 18:44:51 2010 +1100

    s4:dsdb Add a shortcut sequence number for schema reloads
    
    This uses the ldb sequence number, in a hope to detect an unchanged
    schema quicker.
    
    Andrew Bartlett

commit fe3e1af901c970f738bee92baac5d7d4f5736e17
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 22 16:03:33 2010 +1100

    s4:dsdb Rework schema loading and add schema reloading
    
    This commit reworks Samba4's schema loading code to detect when it
    needs to reload the schema.  This is done by watching the @REPLCHANGED
    special DN.
    
    The reload happens by means of a callback, which is only set when the
    schema is loaded from the ldb - not when loaded from an LDIF file or
    DRS.
    
    We also rework the global schema handling - instead of storing the
    pointer to the global schema in each ldb, we store a flag indicating
    that the global schema should be returned at run time.  This makes it
    much easier to switch to a new global schema.
    
    Andrew Bartlett

commit d0b54476fc9f855d1e482597538a7ec60e04f331
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 22 16:00:39 2010 +1100

    s4:dsdb Move dsdb_save_partition_usn() to be a module helper function
    
    This function should not traverse the module stack again, but instead
    run from this point.  Also add a matching
    dsdb_module_load_partition_usn() and change repl_meta_data to match.
    
    Andrew Bartlett

commit 639728a29873e4cf59dfa149a231eae353f3753a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 22 15:41:51 2010 +1100

    s4:schema Expand the schema structure
    
    We now store the location of the schema in the schema, and provide
    hooks for a future schema reloading mechanism.
    
    Andrew Bartlett

commit 775c5ec1c57b4acf61c1c750c4832f64defcb5b6
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 22 15:20:47 2010 +1100

    s4:dsdb Remove unused 'dsdb_make_schema_global' call from pyglue

commit 7fc94eb9a7034c36943efbe04f4f4cdfb174c50e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 22 15:19:55 2010 +1100

    s4:dsdb Add 'const' to some struct dsdb_schema variables
    
    We don't currently require this, but we may move this way in future.

commit fc5a507a86f37aecb6702d8c2c3bdc462e49f9fd
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 22 15:17:58 2010 +1100

    s4:dsdb Don't load the schema unconditionally
    
    Schema loads now come at a price, so avoid doing them if we don't have
    to (such as when doing an @REPLCHANGED or other special DN based
    search).
    
    Andrew Bartlett

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/common/util.c                       |   88 -------
 source4/dsdb/samdb/ldb_modules/extended_dn_out.c |    7 +-
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c  |   23 +-
 source4/dsdb/samdb/ldb_modules/schema_data.c     |   17 +-
 source4/dsdb/samdb/ldb_modules/schema_load.c     |  296 ++++++++++++++--------
 source4/dsdb/samdb/ldb_modules/util.c            |  175 +++++++++++++
 source4/dsdb/schema/schema.h                     |   11 +
 source4/dsdb/schema/schema_init.c                |    2 +
 source4/dsdb/schema/schema_set.c                 |   80 ++++--
 source4/lib/ldb_wrap.c                           |    5 +-
 source4/scripting/python/pyglue.c                |   17 --
 11 files changed, 469 insertions(+), 252 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 9c29509..b469b06 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2585,94 +2585,6 @@ int dsdb_load_partition_usn(struct ldb_context *ldb, struct ldb_dn *dn,
 	return LDB_SUCCESS;	
 }
 
-/*
-  save uSNHighest and uSNUrgent attributes in the @REPLCHANGED object for a
-  partition
- */
-int dsdb_save_partition_usn(struct ldb_context *ldb, struct ldb_dn *dn,
-				uint64_t uSN, uint64_t urgent_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;
-	
-	/* urgent_uSN is optional so may not be stored */
-	if (urgent_uSN) {
-		ret = ldb_msg_add_fmt(msg, "uSNUrgent", "%llu", (unsigned long long)urgent_uSN);
-		if (ret != LDB_SUCCESS) {
-			talloc_free(msg);
-			return ret;
-		}
-		msg->elements[1].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;
-}
-
 int drsuapi_DsReplicaCursor2_compare(const struct drsuapi_DsReplicaCursor2 *c1,
 						   const struct drsuapi_DsReplicaCursor2 *c2)
 {
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
index b5f4567..f28ad8e 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
@@ -564,6 +564,11 @@ static int extended_dn_out_search(struct ldb_module *module, struct ldb_request
 
 	struct extended_dn_out_private *p = talloc_get_type(ldb_module_get_private(module), struct extended_dn_out_private);
 
+	/* The schema manipulation does not apply to special DNs */
+	if (ldb_dn_is_special(req->op.search.base)) {
+		return ldb_next_request(module, req);
+	}
+
 	/* check if there's an extended dn control */
 	control = ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID);
 	if (control && control->data) {
@@ -743,7 +748,7 @@ static int extended_dn_out_dereference_init(struct ldb_module *module, const cha
 	struct dsdb_openldap_dereference_control *dereference_control;
 	struct dsdb_attribute *cur;
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
-	struct dsdb_schema *schema;
+	const struct dsdb_schema *schema;
 
 	ldb_module_set_private(module, p);
 
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index a7e2a48..8b4e012 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -454,15 +454,14 @@ static int replmd_notify_store(struct ldb_module *module)
 {
 	struct replmd_private *replmd_private =
 		talloc_get_type(ldb_module_get_private(module), struct replmd_private);
-	struct ldb_context *ldb = ldb_module_get_ctx(module);
 
 	while (replmd_private->ncs) {
 		int ret;
 		struct nc_entry *modified_partition = replmd_private->ncs;
 
-		ret = dsdb_save_partition_usn(ldb, modified_partition->dn,
-						modified_partition->mod_usn,
-						modified_partition->mod_usn_urgent);
+		ret = dsdb_module_save_partition_usn(module, modified_partition->dn,
+						     modified_partition->mod_usn,
+						     modified_partition->mod_usn_urgent);
 		if (ret != LDB_SUCCESS) {
 			DEBUG(0,(__location__ ": Failed to save partition uSN for %s\n",
 				 ldb_dn_get_linearized(modified_partition->dn)));
@@ -668,7 +667,7 @@ static int replmd_add_fix_la(struct ldb_module *module, struct ldb_message_eleme
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 
 	/* We will take a reference to the schema in replmd_add_backlink */
-	struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL);
+	const struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL);
 	NTTIME now;
 
 	unix_to_nt_time(&now, t);
@@ -1537,7 +1536,7 @@ static int replmd_update_la_val(TALLOC_CTX *mem_ctx, struct ldb_val *v, struct d
   handle adding a linked attribute
  */
 static int replmd_modify_la_add(struct ldb_module *module,
-				struct dsdb_schema *schema,
+				const struct dsdb_schema *schema,
 				struct ldb_message *msg,
 				struct ldb_message_element *el,
 				struct ldb_message_element *old_el,
@@ -1656,7 +1655,7 @@ static int replmd_modify_la_add(struct ldb_module *module,
   handle deleting all active linked attributes
  */
 static int replmd_modify_la_delete(struct ldb_module *module,
-				   struct dsdb_schema *schema,
+				   const struct dsdb_schema *schema,
 				   struct ldb_message *msg,
 				   struct ldb_message_element *el,
 				   struct ldb_message_element *old_el,
@@ -1775,7 +1774,7 @@ static int replmd_modify_la_delete(struct ldb_module *module,
   handle replacing a linked attribute
  */
 static int replmd_modify_la_replace(struct ldb_module *module,
-				    struct dsdb_schema *schema,
+				    const struct dsdb_schema *schema,
 				    struct ldb_message *msg,
 				    struct ldb_message_element *el,
 				    struct ldb_message_element *old_el,
@@ -1937,7 +1936,7 @@ static int replmd_modify_handle_linked_attribs(struct ldb_module *module,
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	struct ldb_message *old_msg;
 
-	struct dsdb_schema *schema;
+	const struct dsdb_schema *schema;
 	struct GUID old_guid;
 
 	if (seq_num == 0) {
@@ -2235,7 +2234,7 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are
    is deleted
  */
 static int replmd_delete_remove_link(struct ldb_module *module,
-				     struct dsdb_schema *schema,
+				     const struct dsdb_schema *schema,
 				     struct ldb_dn *dn,
 				     struct ldb_message_element *el,
 				     const struct dsdb_attribute *sa)
@@ -2322,7 +2321,7 @@ static int replmd_delete(struct ldb_module *module, struct ldb_request *req)
 	const struct ldb_val *rdn_value, *new_rdn_value;
 	struct GUID guid;
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
-	struct dsdb_schema *schema;
+	const struct dsdb_schema *schema;
 	struct ldb_message *msg, *old_msg;
 	struct ldb_message_element *el;
 	TALLOC_CTX *tmp_ctx;
@@ -3510,7 +3509,7 @@ static int replmd_process_linked_attribute(struct ldb_module *module,
 	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	struct ldb_message *msg;
 	TALLOC_CTX *tmp_ctx = talloc_new(la_entry);
-	struct dsdb_schema *schema = dsdb_get_schema(ldb, tmp_ctx);
+	const struct dsdb_schema *schema = dsdb_get_schema(ldb, tmp_ctx);
 	int ret;
 	const struct dsdb_attribute *attr;
 	struct dsdb_dn *dsdb_dn;
diff --git a/source4/dsdb/samdb/ldb_modules/schema_data.c b/source4/dsdb/samdb/ldb_modules/schema_data.c
index 25f2dce..655b489 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_data.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_data.c
@@ -417,12 +417,17 @@ static int schema_data_search(struct ldb_module *module, struct ldb_request *req
 	int ret;
 	struct schema_data_search_data *search_context;
 	struct ldb_request *down_req;
-	struct dsdb_schema *schema = dsdb_get_schema(ldb, NULL);
+	const struct dsdb_schema *schema;
+	if (!ldb_module_get_private(module)) {
+		/* If there is no module data, there is little we can do */
+		return ldb_next_request(module, req);
+	}
 
-	if (!schema || !ldb_module_get_private(module)) {
-		/* If there is no schema, there is little we can do */
+	/* The schema manipulation does not apply to special DNs */
+	if (ldb_dn_is_special(req->op.search.base)) {
 		return ldb_next_request(module, req);
 	}
+
 	for (i=0; i < ARRAY_SIZE(generated_attrs); i++) {
 		if (ldb_attr_in_list(req->op.search.attrs, generated_attrs[i].attr)) {
 			break;
@@ -434,6 +439,12 @@ static int schema_data_search(struct ldb_module *module, struct ldb_request *req
 		return ldb_next_request(module, req);
 	}
 
+	schema = dsdb_get_schema(ldb, NULL);
+	if (!schema || !ldb_module_get_private(module)) {
+		/* If there is no schema, there is little we can do */
+		return ldb_next_request(module, req);
+	}
+
 	search_context = talloc(req, struct schema_data_search_data);
 	if (!search_context) {
 		ldb_oom(ldb);
diff --git a/source4/dsdb/samdb/ldb_modules/schema_load.c b/source4/dsdb/samdb/ldb_modules/schema_load.c
index 5ea70fb..d13b339 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_load.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_load.c
@@ -5,8 +5,8 @@
    checkings, it also loads the dsdb_schema.
    
    Copyright (C) Stefan Metzmacher <metze at samba.org> 2007
-   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2009
-    
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2009-2010
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
@@ -31,19 +31,123 @@
 #include "param/param.h"
 #include "dsdb/samdb/ldb_modules/util.h"
 
+struct schema_load_private_data {
+	bool in_transaction;
+};
+
+static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_dn, uint64_t current_usn,
+			       struct dsdb_schema **schema);
+
+struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct dsdb_schema *schema, bool is_global_schema)
+{
+	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 */
+		return schema;
+	}
+
+	/* We don't allow a schema reload during a transaction - nobody else can modify our schema behind our backs */
+	if (private_data->in_transaction) {
+		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) {
+		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 new_schema;
+}
+
+
 /*
   Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
 */
 
-static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *module,
-				      struct smb_iconv_convenience *iconv_convenience, 
-				      struct ldb_dn *schema_dn,
-				      struct dsdb_schema **schema) 
+static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_dn, uint64_t current_usn,
+			       struct dsdb_schema **schema)
 {
+	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	TALLOC_CTX *tmp_ctx;
 	char *error_string;
 	int ret;
-	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	struct ldb_result *schema_res;
 	struct ldb_result *a_res;
 	struct ldb_result *c_res;
@@ -55,7 +159,7 @@ static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *mo
 	};
 	unsigned flags;
 
-	tmp_ctx = talloc_new(mem_ctx);
+	tmp_ctx = talloc_new(module);
 	if (!tmp_ctx) {
 		ldb_oom(ldb);
 		return LDB_ERR_OPERATIONS_ERROR;
@@ -71,6 +175,9 @@ static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *mo
 	ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res,
 				    schema_dn, schema_attrs, 0);
 	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+		ldb_reset_err_string(ldb);
+		ldb_debug(ldb, LDB_DEBUG_WARNING,
+			  "schema_load_init: no schema head present: (skip schema loading)\n");
 		goto failed;
 	} else if (ret != LDB_SUCCESS) {
 		ldb_asprintf_errstring(ldb, 
@@ -112,11 +219,31 @@ static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *mo
 					   schema_res, a_res, c_res, schema, &error_string);
 	if (ret != LDB_SUCCESS) {
 		ldb_asprintf_errstring(ldb, 
-						    "dsdb_schema load failed: %s",
-						    error_string);
+				       "dsdb_schema load failed: %s",
+				       error_string);
 		goto failed;
 	}
-	talloc_steal(mem_ctx, *schema);
+
+	(*schema)->refresh_fn = dsdb_schema_refresh;
+	(*schema)->loaded_from_module = module;
+	(*schema)->loaded_usn = current_usn;
+
+	/* dsdb_set_schema() steal schema into the ldb_context */
+	ret = dsdb_set_schema(ldb, (*schema));
+
+	if (ret != LDB_SUCCESS) {
+		ldb_debug_set(ldb, LDB_DEBUG_FATAL,
+			      "schema_load_init: dsdb_set_schema() failed: %d:%s: %s",
+			      ret, ldb_strerror(ret), ldb_errstring(ldb));
+		talloc_free(tmp_ctx);
+		return ret;
+	}
+
+	/* Ensure this module won't go away before the callback */
+	if (talloc_reference(*schema, ldb) == NULL) {
+		ldb_oom(ldb);
+		ret = LDB_ERR_OPERATIONS_ERROR;
+	}
 
 failed:
 	if (flags & LDB_FLG_ENABLE_TRACING) {
@@ -130,18 +257,30 @@ failed:
 
 static int schema_load_init(struct ldb_module *module)
 {
-	struct ldb_context *ldb;
-	TALLOC_CTX *mem_ctx;
-	struct ldb_dn *schema_dn;
+	struct schema_load_private_data *private_data;
 	struct dsdb_schema *schema;
+	struct ldb_context *ldb = ldb_module_get_ctx(module);
 	int ret;
+	uint64_t current_usn;
+	struct ldb_dn *schema_dn;
+
+	private_data = talloc_zero(module, struct schema_load_private_data);
+	if (private_data == NULL) {
+		ldb_oom(ldb);
+		return LDB_ERR_OPERATIONS_ERROR;
+	}
+
+	ldb_module_set_private(module, private_data);
 
 	ret = ldb_next_init(module);
 	if (ret != LDB_SUCCESS) {
 		return ret;
 	}
 
-	ldb = ldb_module_get_ctx(module);
+	if (dsdb_get_schema(ldb, NULL)) {
+		return LDB_SUCCESS;
+	}
+
 	schema_dn = samdb_schema_dn(ldb);
 	if (!schema_dn) {
 		ldb_reset_err_string(ldb);
@@ -150,54 +289,51 @@ static int schema_load_init(struct ldb_module *module)
 		return LDB_SUCCESS;
 	}
 
-	if (dsdb_get_schema(ldb, NULL)) {
-		return LDB_SUCCESS;
+	ret = dsdb_module_load_partition_usn(module, schema_dn, &current_usn, NULL);
+	if (ret != LDB_SUCCESS) {
+		ldb_asprintf_errstring(ldb,
+				       "dsdb_load_partition_usn failed: %s",


-- 
Samba Shared Repository


More information about the samba-cvs mailing list