s4-dsdb clarify that failure to load the schema items from DRS is expected
[metze/samba/wip.git] / source4 / dsdb / repl / replicated_objects.c
index 5997073a8a2907867fd3878a733a478acc60394f..f8c151787d7860b2cc4f50e7a827e74264591fd6 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "includes.h"
 #include "dsdb/samdb/samdb.h"
-#include "lib/ldb/include/ldb_errors.h"
+#include <ldb_errors.h>
 #include "../lib/util/dlinklist.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "librpc/gen_ndr/ndr_drsuapi.h"
@@ -61,6 +61,14 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
        struct dsdb_schema *working_schema;
        const struct drsuapi_DsReplicaObjectListItemEx *cur;
        int ret, pass_no;
+       uint32_t ignore_attids[] = {
+                       DRSUAPI_ATTID_auxiliaryClass,
+                       DRSUAPI_ATTID_mayContain,
+                       DRSUAPI_ATTID_mustContain,
+                       DRSUAPI_ATTID_possSuperiors,
+                       DRSUAPI_ATTID_systemPossSuperiors,
+                       DRSUAPI_ATTID_INVALID
+       };
 
        /* make a copy of the iniatial_scheam so we don't mess with it */
        working_schema = dsdb_schema_copy_shallow(mem_ctx, ldb, initial_schema);
@@ -111,10 +119,11 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
                         */
                        werr = dsdb_convert_object_ex(ldb, working_schema, pfm_remote,
                                                      cur, gensec_skey,
+                                                     ignore_attids,
                                                      tmp_ctx, &object);
                        if (!W_ERROR_IS_OK(werr)) {
-                               DEBUG(1,("Warning: Failed to convert schema object %s into ldb msg\n",
-                                        cur->object.identifier->dn));
+                               DEBUG(4,("debug: Failed to convert schema object %s into ldb msg, will try during next loop\n",
+                                         cur->object.identifier->dn));
 
                                failed_obj_count++;
                        } else {
@@ -127,7 +136,7 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
                                                                       working_schema,
                                                                       object.msg);
                                if (!W_ERROR_IS_OK(werr)) {
-                                       DEBUG(1,("Warning: failed to convert object %s into a schema element: %s\n",
+                                       DEBUG(4,("debug: failed to convert object %s into a schema element, will try during next loop: %s\n",
                                                 ldb_dn_get_linearized(object.msg->dn),
                                                 win_errstr(werr)));
                                        failed_obj_count++;
@@ -163,11 +172,26 @@ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb,
        return WERR_OK;
 }
 
+static bool dsdb_attid_in_list(const uint32_t attid_list[], uint32_t attid)
+{
+       const uint32_t *cur;
+       if (!attid_list) {
+               return false;
+       }
+       for (cur = attid_list; *cur != DRSUAPI_ATTID_INVALID; cur++) {
+               if (*cur == attid) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
                              const struct dsdb_schema *schema,
                              const struct dsdb_schema_prefixmap *pfm_remote,
                              const struct drsuapi_DsReplicaObjectListItemEx *in,
                              const DATA_BLOB *gensec_skey,
+                             const uint32_t *ignore_attids,
                              TALLOC_CTX *mem_ctx,
                              struct dsdb_extended_replicated_object *out)
 {
@@ -189,6 +213,7 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
        struct replPropertyMetaData1 *rdn_m = NULL;
        struct dom_sid *sid = NULL;
        uint32_t rid = 0;
+       uint32_t attr_count;
        int ret;
 
        if (!in->object.identifier) {
@@ -243,7 +268,7 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
                                               md->ctr.ctr1.count + 1); /* +1 because of the RDN attribute */
        W_ERROR_HAVE_NO_MEMORY(md->ctr.ctr1.array);
 
-       for (i=0; i < in->meta_data_ctr->count; i++) {
+       for (i=0, attr_count=0; i < in->meta_data_ctr->count; i++, attr_count++) {
                struct drsuapi_DsReplicaAttribute *a;
                struct drsuapi_DsReplicaMetaData *d;
                struct replPropertyMetaData1 *m;
@@ -252,8 +277,13 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
 
                a = &in->object.attribute_ctr.attributes[i];
                d = &in->meta_data_ctr->meta_data[i];
-               m = &md->ctr.ctr1.array[i];
-               e = &msg->elements[i];
+               m = &md->ctr.ctr1.array[attr_count];
+               e = &msg->elements[attr_count];
+
+               if (dsdb_attid_in_list(ignore_attids, a->attid)) {
+                       attr_count--;
+                       continue;
+               }
 
                for (j=0; j<a->value_ctr.num_values; j++) {
                        status = drsuapi_decrypt_attribute(a->value_ctr.values[j].blob, gensec_skey, rid, a);
@@ -278,10 +308,15 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
                if (a->attid == DRSUAPI_ATTID_name) {
                        name_a = a;
                        name_d = d;
-                       rdn_m = &md->ctr.ctr1.array[md->ctr.ctr1.count];
                }
        }
 
+       msg->num_elements = attr_count;
+       md->ctr.ctr1.count = attr_count;
+       if (name_a) {
+               rdn_m = &md->ctr.ctr1.array[md->ctr.ctr1.count];
+       }
+
        if (rdn_m) {
                struct ldb_message_element *el;
                el = ldb_msg_find_element(msg, rdn_attr->lDAPDisplayName);
@@ -412,6 +447,7 @@ WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb,
 
                status = dsdb_convert_object_ex(ldb, schema, pfm_remote,
                                                cur, gensec_skey,
+                                               NULL,
                                                out->objects, &out->objects[i]);
                if (!W_ERROR_IS_OK(status)) {
                        talloc_free(out);
@@ -445,6 +481,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
                                      struct dsdb_extended_replicated_objects *objects,
                                      uint64_t *notify_uSN)
 {
+       WERROR werr;
        struct ldb_result *ext_res;
        struct dsdb_schema *cur_schema = NULL;
        int ret;
@@ -503,6 +540,23 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
        }
        talloc_free(ext_res);
 
+       /* Save our updated prefixMap */
+       if (working_schema) {
+               werr = dsdb_write_prefixes_from_schema_to_ldb(working_schema,
+                                                             ldb,
+                                                             working_schema);
+               if (!W_ERROR_IS_OK(werr)) {
+                       /* restore previous schema */
+                       if (cur_schema ) {
+                               dsdb_reference_schema(ldb, cur_schema, false);
+                               dsdb_make_schema_global(ldb, cur_schema);
+                       }
+                       DEBUG(0,("Failed to save updated prefixMap: %s\n",
+                                win_errstr(werr)));
+                       return werr;
+               }
+       }
+
        ret = ldb_transaction_prepare_commit(ldb);
        if (ret != LDB_SUCCESS) {
                /* restore previous schema */