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 <abart...@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 <abart...@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 <abart...@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 <abart...@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 <abart...@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 <abart...@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 <abart...@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 <me...@samba.org> 2007
-   Copyright (C) Andrew Bartlett <abart...@samba.org> 2009
-    
+   Copyright (C) Andrew Bartlett <abart...@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

Reply via email to