Fix up-to-dateness vector creation.
authorAnatoliy Atanasov <anatoliy.atanasov@postpath.com>
Thu, 10 Sep 2009 09:41:48 +0000 (12:41 +0300)
committerAndrew Tridgell <tridge@samba.org>
Sat, 12 Sep 2009 01:15:26 +0000 (11:15 +1000)
source4/rpc_server/drsuapi/getncchanges.c

index 3b908fffbcbaf9610411e83a4013cd3294d846cb..338888610527c9fa895c95323bc98582d23be055 100644 (file)
@@ -150,6 +150,71 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
        return WERR_OK;
 }
 
+static int replmd_drsuapi_DsReplicaCursor2_compare(const struct drsuapi_DsReplicaCursor2 *c1,
+                                                  const struct drsuapi_DsReplicaCursor2 *c2)
+{
+       return GUID_compare(&c1->source_dsa_invocation_id, &c2->source_dsa_invocation_id);
+}
+
+static WERROR get_nc_changes_udv(struct drsuapi_DsReplicaCursor2CtrEx *udv,
+                                struct ldb_message *msg,
+                                struct ldb_context *sam_ctx)
+{
+       uint32_t it_value;
+
+       it_value = ldb_msg_find_attr_as_uint(msg, "instanceType", 0);
+       if ((it_value & INSTANCE_TYPE_IS_NC_HEAD) == INSTANCE_TYPE_IS_NC_HEAD) {
+               const struct ldb_val *ouv_value;
+               struct drsuapi_DsReplicaCursor2 *tmp_cursor;
+               uint64_t highest_commited_usn;
+               NTTIME now;
+               time_t t = time(NULL);
+
+               int ret = ldb_sequence_number(sam_ctx, LDB_SEQ_HIGHEST_SEQ, &highest_commited_usn);
+               if (ret != LDB_SUCCESS) {
+                       return WERR_DS_DRA_INTERNAL_ERROR;
+               }
+               tmp_cursor = talloc(udv, struct drsuapi_DsReplicaCursor2);
+               tmp_cursor->source_dsa_invocation_id = *(samdb_ntds_invocation_id(sam_ctx));
+               tmp_cursor->highest_usn = highest_commited_usn;
+               unix_to_nt_time(&now, t);
+               tmp_cursor->last_sync_success = now;
+
+               ouv_value = ldb_msg_find_ldb_val(msg, "replUpToDateVector");
+               if (ouv_value) {
+                       struct replUpToDateVectorBlob ouv;
+                       enum ndr_err_code ndr_err;
+
+                       ndr_err = ndr_pull_struct_blob(ouv_value, udv,
+                                                      lp_iconv_convenience(ldb_get_opaque(sam_ctx, "loadparm")), &ouv,
+                                                      (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               return WERR_DS_DRA_INTERNAL_ERROR;
+                       }
+                       if (ouv.version != 2) {
+                               return WERR_DS_DRA_INTERNAL_ERROR;
+                       }
+
+                       udv->count = ouv.ctr.ctr2.count + 1;
+                       udv->cursors = talloc_steal(udv, ouv.ctr.ctr2.cursors);
+                       udv->cursors = talloc_realloc(udv, udv->cursors, struct drsuapi_DsReplicaCursor2, udv->count);
+                       if (!udv->cursors) {
+                               return WERR_DS_DRA_INTERNAL_ERROR;
+                       }
+                       udv->cursors[udv->count - 1] = *tmp_cursor;
+
+                       qsort(udv->cursors, udv->count,
+                             sizeof(struct drsuapi_DsReplicaCursor2),
+                             (comparison_fn_t)replmd_drsuapi_DsReplicaCursor2_compare);
+               } else {
+                       udv->count = 1;
+                       udv->cursors = talloc_steal(udv, tmp_cursor);
+               }
+       }
+
+       return WERR_OK;
+}
+
 /* 
   drsuapi_DsGetNCChanges
 */
@@ -164,8 +229,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
        int i;
        struct dsdb_schema *schema;
        struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
-       time_t t = time(NULL);
-       NTTIME now;
        struct drsuapi_DsReplicaObjectListItemEx *currentObject;
        NTSTATUS status;
        DATA_BLOB session_key;
@@ -244,6 +307,11 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
        r->out.ctr->ctr6.old_highwatermark = r->in.req->req8.highwatermark;
        r->out.ctr->ctr6.new_highwatermark = r->in.req->req8.highwatermark;
 
+       r->out.ctr->ctr6.uptodateness_vector = talloc(mem_ctx, struct drsuapi_DsReplicaCursor2CtrEx);
+       r->out.ctr->ctr6.uptodateness_vector->version = 2;
+       r->out.ctr->ctr6.uptodateness_vector->reserved1 = 0;
+       r->out.ctr->ctr6.uptodateness_vector->reserved2 = 0;
+
        r->out.ctr->ctr6.first_object = talloc(mem_ctx, struct drsuapi_DsReplicaObjectListItemEx);
        currentObject = r->out.ctr->ctr6.first_object;
 
@@ -263,6 +331,12 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
                        r->out.ctr->ctr6.first_object = NULL;
                        return werr;
                }
+
+               werr = get_nc_changes_udv(r->out.ctr->ctr6.uptodateness_vector, site_res->msgs[i], sam_ctx);
+               if (!W_ERROR_IS_OK(werr)) {
+                        return werr;
+               }
+
                if (i == (site_res->count-1)) {
                        break;
                }
@@ -270,18 +344,5 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
                currentObject = currentObject->next_object;
        }
 
-       r->out.ctr->ctr6.uptodateness_vector = talloc(mem_ctx, struct drsuapi_DsReplicaCursor2CtrEx);
-
-       r->out.ctr->ctr6.uptodateness_vector->version = 2;
-       r->out.ctr->ctr6.uptodateness_vector->count = 1;
-       r->out.ctr->ctr6.uptodateness_vector->reserved1 = 0;
-       r->out.ctr->ctr6.uptodateness_vector->reserved2 = 0;
-       r->out.ctr->ctr6.uptodateness_vector->cursors = talloc(mem_ctx, struct drsuapi_DsReplicaCursor2);
-
-       r->out.ctr->ctr6.uptodateness_vector->cursors[0].source_dsa_invocation_id = *(samdb_ntds_invocation_id(sam_ctx));
-       r->out.ctr->ctr6.uptodateness_vector->cursors[0].highest_usn = r->out.ctr->ctr6.new_highwatermark.highest_usn;
-       unix_to_nt_time(&now, t);
-       r->out.ctr->ctr6.uptodateness_vector->cursors[0].last_sync_success = now;
-
        return WERR_OK;
 }