Revert "WRONG!!! sq dsdb/repl: we need to replicate the whole schema before we can...
authorStefan Metzmacher <metze@samba.org>
Wed, 13 Mar 2019 10:47:43 +0000 (11:47 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 29 Mar 2019 14:46:35 +0000 (15:46 +0100)
This reverts commit aac2f83a9220915005586d78c71601e533ff2618.

source4/dsdb/repl/drepl_out_helpers.c

index 4717a4e129843bc00d19160e17f74c50e1c35fb7..0e0313a28cfea7aed7624606d5bbda520420e323 100644 (file)
@@ -245,6 +245,8 @@ struct dreplsrv_op_pull_source_schema_cycle {
        size_t object_count;
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
        struct drsuapi_DsReplicaObjectListItemEx *last_object;
+       uint32_t linked_attributes_count;
+       struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
 };
 
 struct dreplsrv_op_pull_source_state {
@@ -884,20 +886,6 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
                struct drsuapi_DsReplicaObjectListItemEx **ptr = NULL;
                struct drsuapi_DsReplicaObjectListItemEx *l = NULL;
 
-               /*
-                * The Schema NC only allows objects of class
-                * attributeSchema, classSchema, subSchema and dMD.
-                *
-                * And all are immutable!
-                *
-                * It implies we'll never see linked attributes
-                */
-               if (linked_attributes_count != 0) {
-                       nt_status = werror_to_ntstatus(WERR_BAD_NET_RESP);
-                       tevent_req_nterror(req, nt_status);
-                       return;
-               }
-
                was_schema = true;
                sc = state->schema_cycle;
 
@@ -919,6 +907,47 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
                        }
                }
 
+               if (sc->linked_attributes_count == 0) {
+                       sc->linked_attributes = talloc_move(sc, &linked_attributes);
+                       sc->linked_attributes_count = linked_attributes_count;
+                       linked_attributes_count = 0;
+               } else if (linked_attributes_count > 0) {
+                       struct drsuapi_DsReplicaLinkedAttribute *new_las = NULL;
+                       struct drsuapi_DsReplicaLinkedAttribute *tmp_las = NULL;
+                       uint64_t new_count;
+                       uint64_t add_size;
+                       uint32_t add_idx;
+
+                       new_count = sc->linked_attributes_count;
+                       new_count += linked_attributes_count;
+                       if (new_count > UINT32_MAX) {
+                               nt_status = werror_to_ntstatus(WERR_BAD_NET_RESP);
+                               tevent_req_nterror(req, nt_status);
+                               return;
+                       }
+                       add_size = linked_attributes_count;
+                       add_size *= sizeof(linked_attributes[0]);
+                       if (add_size > SIZE_MAX) {
+                               nt_status = werror_to_ntstatus(WERR_BAD_NET_RESP);
+                               tevent_req_nterror(req, nt_status);
+                               return;
+                       }
+                       add_idx = sc->linked_attributes_count;
+
+                       tmp_las = talloc_realloc(sc,
+                                                sc->linked_attributes,
+                                                struct drsuapi_DsReplicaLinkedAttribute,
+                                                new_count);
+                       if (tevent_req_nomem(tmp_las, req)) {
+                               return;
+                       }
+                       new_las = talloc_move(tmp_las, &linked_attributes);
+                       memcpy(&tmp_las[add_idx], new_las, add_size);
+                       sc->linked_attributes = tmp_las;
+                       sc->linked_attributes_count = new_count;
+                       linked_attributes_count = 0;
+               }
+
                if (more_data) {
                        /* we don't need this structure anymore */
                        TALLOC_FREE(r);
@@ -945,6 +974,8 @@ static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req
        if (sc != NULL) {
                first_object = talloc_move(r, &sc->first_object);
                object_count = sc->object_count;
+               linked_attributes = talloc_move(r, &sc->linked_attributes);
+               linked_attributes_count = sc->linked_attributes_count;
                TALLOC_FREE(sc);
 
                if (first_object != NULL) {