Finish removal of iconv_convenience in public API's.
[bbaumbach/samba-autobuild/.git] / source4 / dsdb / samdb / ldb_modules / schema_load.c
index 5dd8fb78c9fc950308a268e007d1418b8c864aa1..4df6f1e38a43d26446cf6bf4211e7a536e1879fe 100644 (file)
@@ -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;
        }
-       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;
 }
 
 
@@ -150,7 +215,6 @@ static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_
        }
 
        ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
-                                          lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
                                           schema_res, a_res, c_res, schema, &error_string);
        if (ret != LDB_SUCCESS) {
                ldb_asprintf_errstring(ldb, 
@@ -216,7 +280,7 @@ static int schema_load_init(struct ldb_module *module)
                return LDB_SUCCESS;
        }
 
-       schema_dn = samdb_schema_dn(ldb);
+       schema_dn = ldb_get_schema_basedn(ldb);
        if (!schema_dn) {
                ldb_reset_err_string(ldb);
                ldb_debug(ldb, LDB_DEBUG_WARNING,
@@ -226,10 +290,8 @@ static int schema_load_init(struct ldb_module *module)
 
        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",
-                                      ldb_errstring(ldb));
-               return ret;
+               /* Ignore the error and just reload the DB more often */
+               current_usn = 0;
        }
 
        return dsdb_schema_from_db(module, schema_dn, current_usn, &schema);