s4/drs: schema_prefixMap to/from drsuapi_prefixMap conversion implementation
[ira/wip.git] / source4 / dsdb / schema / schema_set.c
index 8b1188a1b5bf57b382b5c2750770eb8c30fd1134..9f22b3233407a4b37651ee95e737ac5d97994709 100644 (file)
@@ -135,11 +135,11 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem
                
                mod_msg = ldb_msg_diff(ldb, res->msgs[0], msg);
                if (mod_msg->num_elements > 0) {
-                       ret = ldb_modify(ldb, mod_msg);
+                       ret = samdb_replace(ldb, mem_ctx, mod_msg);
                }
        }
 
-       if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
+       if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
                /* We might be on a read-only DB */
                ret = LDB_SUCCESS;
        }
@@ -154,7 +154,7 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem
        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                ret = ldb_add(ldb, msg_idx);
        } else if (ret != LDB_SUCCESS) {
-       } else if (res->count != 1) {
+       } else if (res_idx->count != 1) {
                ret = ldb_add(ldb, msg_idx);
        } else {
                ret = LDB_SUCCESS;
@@ -163,10 +163,10 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem
 
                mod_msg = ldb_msg_diff(ldb, res_idx->msgs[0], msg_idx);
                if (mod_msg->num_elements > 0) {
-                       ret = ldb_modify(ldb, mod_msg);
+                       ret = samdb_replace(ldb, mem_ctx, mod_msg);
                }
        }
-       if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
+       if (ret == LDB_ERR_OPERATIONS_ERROR || ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
                /* We might be on a read-only DB */
                ret = LDB_SUCCESS;
        }
@@ -346,7 +346,10 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
                return ret;
        }
 
-       schema_fill_constructed(schema);
+       ret = schema_fill_constructed(schema);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
 
        ret = ldb_set_opaque(ldb, "dsdb_schema", schema);
        if (ret != LDB_SUCCESS) {
@@ -370,34 +373,43 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
 static struct dsdb_schema *global_schema;
 
 /**
- * Make this ldb use the 'global' schema, setup to avoid having multiple copies in this process
+ * Make this ldb use a specified schema, already fully calculated and belonging to another ldb
  */
-int dsdb_set_global_schema(struct ldb_context *ldb)
+int dsdb_reference_schema(struct ldb_context *ldb, struct dsdb_schema *schema,
+                         bool write_attributes)
 {
        int ret;
-       if (!global_schema) {
-               return LDB_SUCCESS;
-       }
-
-       ret = ldb_set_opaque(ldb, "dsdb_schema", global_schema);
+       ret = ldb_set_opaque(ldb, "dsdb_schema", schema);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
 
        /* Set the new attributes based on the new schema */
-       ret = dsdb_schema_set_attributes(ldb, global_schema, false);
+       ret = dsdb_schema_set_attributes(ldb, schema, write_attributes);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
 
-       /* Keep a reference to this schema, just incase the global copy is replaced */
-       if (talloc_reference(ldb, global_schema) == NULL) {
+       /* Keep a reference to this schema, just incase the original copy is replaced */
+       if (talloc_reference(ldb, schema) == NULL) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
        return LDB_SUCCESS;
 }
 
+/**
+ * Make this ldb use the 'global' schema, setup to avoid having multiple copies in this process
+ */
+int dsdb_set_global_schema(struct ldb_context *ldb)
+{
+       if (!global_schema) {
+               return LDB_SUCCESS;
+       }
+
+       return dsdb_reference_schema(ldb, global_schema, false /* Don't write attributes, it's expensive */);
+}
+
 /**
  * Find the schema object for this ldb
  */
@@ -437,7 +449,8 @@ void dsdb_make_schema_global(struct ldb_context *ldb)
        }
 
        /* we want the schema to be around permanently */
-       talloc_reference(talloc_autofree_context(), schema);
+       talloc_reparent(talloc_parent(schema), talloc_autofree_context(), schema);
+
        global_schema = schema;
 
        dsdb_set_global_schema(ldb);
@@ -450,7 +463,7 @@ void dsdb_make_schema_global(struct ldb_context *ldb)
  * schema itself to the directory.
  */
 
-WERROR dsdb_attach_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df)
+WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df)
 {
        struct ldb_ldif *ldif;
        struct ldb_message *msg;
@@ -545,7 +558,7 @@ WERROR dsdb_attach_schema_from_ldif(struct ldb_context *ldb, const char *pf, con
                                goto failed;
                        }
 
-                       DLIST_ADD_END(schema->attributes, sa, struct dsdb_attribute *);
+                       DLIST_ADD(schema->attributes, sa);
                } else if (is_sc) {
                        struct dsdb_class *sc;
 
@@ -559,7 +572,7 @@ WERROR dsdb_attach_schema_from_ldif(struct ldb_context *ldb, const char *pf, con
                                goto failed;
                        }
 
-                       DLIST_ADD_END(schema->classes, sc, struct dsdb_class *);
+                       DLIST_ADD(schema->classes, sc);
                }
        }