s4-drs: support DRSUAPI_DRS_ADD_REF flag
authorAndrew Tridgell <tridge@samba.org>
Wed, 14 Oct 2009 09:29:39 +0000 (20:29 +1100)
committerAndrew Tridgell <tridge@samba.org>
Wed, 14 Oct 2009 21:20:37 +0000 (08:20 +1100)
The DRSUAPI_DRS_ADD_REF flag tells the DRS server to run an UpdateRefs
call on behalf of the client after the DsGetNCChanges call. The lack
of support for this option may explain why the repsTo attribute was
not being created for w2k8-r2 replication partners.

source4/rpc_server/drsuapi/getncchanges.c

index 5957038ad2ad51613aae19573cd20b2d11003143..90ddab083c703e45df5a9b870215375770d438d9 100644 (file)
@@ -141,8 +141,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
                   instanceType then don't include it */
                if (md.ctr.ctr1.array[i].local_usn < highest_usn &&
                    md.ctr.ctr1.array[i].attid != DRSUAPI_ATTRIBUTE_instanceType) continue;
+
                /* don't include the rDN */
                if (md.ctr.ctr1.array[i].attid == rdn_sa->attributeID_id) continue;
+
                obj->meta_data_ctr->meta_data[n].originating_change_time = md.ctr.ctr1.array[i].originating_change_time;
                obj->meta_data_ctr->meta_data[n].version = md.ctr.ctr1.array[i].version;
                obj->meta_data_ctr->meta_data[n].originating_invocation_id = md.ctr.ctr1.array[i].originating_invocation_id;
@@ -205,12 +207,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem
                                         sa->lDAPDisplayName, win_errstr(werr)));
                                return werr;
                        }
-                       /* if DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING is set
+                       /* if DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING is set
                         * check if attribute is secret and send a null value
-                        * TODO: check if we can make this in the database layer
                         */
-                       if ((replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING)
-                           == DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING) {
+                       if (replica_flags & DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) {
                                drsuapi_process_secret_attribute(&obj->object.attribute_ctr.attributes[i],
                                                                 &obj->meta_data_ctr->meta_data[i]);
                        }
@@ -551,6 +551,29 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
 
        r->out.ctr->ctr6.nc_object_count = getnc_state->site_res->count;
 
+       /* the client can us to call UpdateRefs on its behalf to
+          re-establish monitoring of the NC */
+       if ((req8->replica_flags & DRSUAPI_DRS_ADD_REF) && 
+           !GUID_all_zero(&req8->destination_dsa_guid)) {
+               struct drsuapi_DsReplicaUpdateRefsRequest1 ureq;
+               ureq.naming_context = ncRoot;
+               ureq.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "%s._msdcs.%s",
+                                                        GUID_string(mem_ctx, &req8->destination_dsa_guid),
+                                                        lp_realm(dce_call->conn->dce_ctx->lp_ctx));
+               if (!ureq.dest_dsa_dns_name) {
+                       return WERR_NOMEM;
+               }
+               ureq.dest_dsa_guid = req8->destination_dsa_guid;
+               ureq.options = DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE |
+                       DRSUAPI_DS_REPLICA_UPDATE_ASYNCHRONOUS_OPERATION |
+                       DRSUAPI_DS_REPLICA_UPDATE_GETCHG_CHECK;
+               werr = drsuapi_UpdateRefs(b_state, mem_ctx, &ureq);
+               if (!W_ERROR_IS_OK(werr)) {
+                       DEBUG(0,(__location__ ": Failed UpdateRefs in DsGetNCChanges - %s\n",
+                                win_errstr(werr)));
+               }
+       }
+
        if (i < getnc_state->site_res->count) {
                r->out.ctr->ctr6.more_data = true;
        } else {
@@ -571,8 +594,9 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
                b_state->getncchanges_state = NULL;
        }
 
-       DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", 
+       DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s gave %u objects\n", 
                 (unsigned long long)(req8->highwatermark.highest_usn+1),
+                req8->replica_flags,
                 ncRoot->dn, r->out.ctr->ctr6.object_count));
 
        return WERR_OK;