s3-waf: Add more darwin-specific options
[Samba/gebeck_regimport.git] / source4 / dsdb / repl / drepl_out_helpers.c
blob56e12579876892a12263e50e1e1f910aa981037d
1 /*
2 Unix SMB/CIFS mplementation.
3 DSDB replication service helper function for outgoing traffic
5 Copyright (C) Stefan Metzmacher 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "dsdb/samdb/samdb.h"
24 #include "auth/auth.h"
25 #include "smbd/service.h"
26 #include "lib/events/events.h"
27 #include "lib/messaging/irpc.h"
28 #include "dsdb/repl/drepl_service.h"
29 #include "lib/ldb/include/ldb_errors.h"
30 #include "../lib/util/dlinklist.h"
31 #include "librpc/gen_ndr/ndr_misc.h"
32 #include "librpc/gen_ndr/ndr_drsuapi.h"
33 #include "librpc/gen_ndr/ndr_drsblobs.h"
34 #include "libcli/composite/composite.h"
35 #include "auth/gensec/gensec.h"
36 #include "param/param.h"
37 #include "../lib/util/tevent_ntstatus.h"
39 struct dreplsrv_out_drsuapi_state {
40 struct tevent_context *ev;
42 struct dreplsrv_out_connection *conn;
44 struct dreplsrv_drsuapi_connection *drsuapi;
46 struct drsuapi_DsBindInfoCtr bind_info_ctr;
47 struct drsuapi_DsBind bind_r;
50 static void dreplsrv_out_drsuapi_connect_done(struct composite_context *creq);
52 struct tevent_req *dreplsrv_out_drsuapi_send(TALLOC_CTX *mem_ctx,
53 struct tevent_context *ev,
54 struct dreplsrv_out_connection *conn)
56 struct tevent_req *req;
57 struct dreplsrv_out_drsuapi_state *state;
58 struct composite_context *creq;
60 req = tevent_req_create(mem_ctx, &state,
61 struct dreplsrv_out_drsuapi_state);
62 if (req == NULL) {
63 return NULL;
66 state->ev = ev;
67 state->conn = conn;
68 state->drsuapi = conn->drsuapi;
70 if (state->drsuapi && !state->drsuapi->pipe->conn->dead) {
71 tevent_req_done(req);
72 return tevent_req_post(req, ev);
75 if (state->drsuapi && state->drsuapi->pipe->conn->dead) {
76 talloc_free(state->drsuapi);
77 conn->drsuapi = NULL;
80 state->drsuapi = talloc_zero(state, struct dreplsrv_drsuapi_connection);
81 if (tevent_req_nomem(state->drsuapi, req)) {
82 return tevent_req_post(req, ev);
85 creq = dcerpc_pipe_connect_b_send(state, conn->binding, &ndr_table_drsuapi,
86 conn->service->system_session_info->credentials,
87 ev, conn->service->task->lp_ctx);
88 if (tevent_req_nomem(creq, req)) {
89 return tevent_req_post(req, ev);
91 composite_continue(NULL, creq, dreplsrv_out_drsuapi_connect_done, req);
93 return req;
96 static void dreplsrv_out_drsuapi_bind_done(struct tevent_req *subreq);
98 static void dreplsrv_out_drsuapi_connect_done(struct composite_context *creq)
100 struct tevent_req *req = talloc_get_type(creq->async.private_data,
101 struct tevent_req);
102 struct dreplsrv_out_drsuapi_state *state = tevent_req_data(req,
103 struct dreplsrv_out_drsuapi_state);
104 NTSTATUS status;
105 struct tevent_req *subreq;
107 status = dcerpc_pipe_connect_b_recv(creq,
108 state->drsuapi,
109 &state->drsuapi->pipe);
110 if (tevent_req_nterror(req, status)) {
111 return;
114 state->drsuapi->drsuapi_handle = state->drsuapi->pipe->binding_handle;
116 status = gensec_session_key(state->drsuapi->pipe->conn->security_state.generic_state,
117 &state->drsuapi->gensec_skey);
118 if (tevent_req_nterror(req, status)) {
119 return;
122 state->bind_info_ctr.length = 28;
123 state->bind_info_ctr.info.info28 = state->conn->service->bind_info28;
125 state->bind_r.in.bind_guid = &state->conn->service->ntds_guid;
126 state->bind_r.in.bind_info = &state->bind_info_ctr;
127 state->bind_r.out.bind_handle = &state->drsuapi->bind_handle;
129 subreq = dcerpc_drsuapi_DsBind_r_send(state,
130 state->ev,
131 state->drsuapi->drsuapi_handle,
132 &state->bind_r);
133 if (tevent_req_nomem(subreq, req)) {
134 return;
136 tevent_req_set_callback(subreq, dreplsrv_out_drsuapi_bind_done, req);
139 static void dreplsrv_out_drsuapi_bind_done(struct tevent_req *subreq)
141 struct tevent_req *req = tevent_req_callback_data(subreq,
142 struct tevent_req);
143 struct dreplsrv_out_drsuapi_state *state = tevent_req_data(req,
144 struct dreplsrv_out_drsuapi_state);
145 NTSTATUS status;
147 status = dcerpc_drsuapi_DsBind_r_recv(subreq, state);
148 TALLOC_FREE(subreq);
149 if (tevent_req_nterror(req, status)) {
150 return;
153 if (!W_ERROR_IS_OK(state->bind_r.out.result)) {
154 status = werror_to_ntstatus(state->bind_r.out.result);
155 tevent_req_nterror(req, status);
156 return;
159 ZERO_STRUCT(state->drsuapi->remote_info28);
160 if (state->bind_r.out.bind_info) {
161 struct drsuapi_DsBindInfo28 *info28;
162 info28 = &state->drsuapi->remote_info28;
164 switch (state->bind_r.out.bind_info->length) {
165 case 24: {
166 struct drsuapi_DsBindInfo24 *info24;
167 info24 = &state->bind_r.out.bind_info->info.info24;
169 info28->supported_extensions = info24->supported_extensions;
170 info28->site_guid = info24->site_guid;
171 info28->pid = info24->pid;
172 info28->repl_epoch = 0;
173 break;
175 case 48: {
176 struct drsuapi_DsBindInfo48 *info48;
177 info48 = &state->bind_r.out.bind_info->info.info48;
179 info28->supported_extensions = info48->supported_extensions;
180 info28->site_guid = info48->site_guid;
181 info28->pid = info48->pid;
182 info28->repl_epoch = info48->repl_epoch;
183 break;
185 case 28:
186 *info28 = state->bind_r.out.bind_info->info.info28;
187 break;
191 tevent_req_done(req);
194 NTSTATUS dreplsrv_out_drsuapi_recv(struct tevent_req *req)
196 struct dreplsrv_out_drsuapi_state *state = tevent_req_data(req,
197 struct dreplsrv_out_drsuapi_state);
198 NTSTATUS status;
200 if (tevent_req_is_nterror(req, &status)) {
201 tevent_req_received(req);
202 return status;
205 state->conn->drsuapi = talloc_move(state->conn, &state->drsuapi);
207 tevent_req_received(req);
208 return NT_STATUS_OK;
211 struct dreplsrv_op_pull_source_state {
212 struct tevent_context *ev;
213 struct dreplsrv_out_operation *op;
214 void *ndr_struct_ptr;
217 static void dreplsrv_op_pull_source_connect_done(struct tevent_req *subreq);
219 struct tevent_req *dreplsrv_op_pull_source_send(TALLOC_CTX *mem_ctx,
220 struct tevent_context *ev,
221 struct dreplsrv_out_operation *op)
223 struct tevent_req *req;
224 struct dreplsrv_op_pull_source_state *state;
225 struct tevent_req *subreq;
227 req = tevent_req_create(mem_ctx, &state,
228 struct dreplsrv_op_pull_source_state);
229 if (req == NULL) {
230 return NULL;
232 state->ev = ev;
233 state->op = op;
235 subreq = dreplsrv_out_drsuapi_send(state, ev, op->source_dsa->conn);
236 if (tevent_req_nomem(subreq, req)) {
237 return tevent_req_post(req, ev);
239 tevent_req_set_callback(subreq, dreplsrv_op_pull_source_connect_done, req);
241 return req;
244 static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req);
246 static void dreplsrv_op_pull_source_connect_done(struct tevent_req *subreq)
248 struct tevent_req *req = tevent_req_callback_data(subreq,
249 struct tevent_req);
250 NTSTATUS status;
252 status = dreplsrv_out_drsuapi_recv(subreq);
253 TALLOC_FREE(subreq);
254 if (tevent_req_nterror(req, status)) {
255 return;
258 dreplsrv_op_pull_source_get_changes_trigger(req);
261 static void dreplsrv_op_pull_source_get_changes_done(struct tevent_req *subreq);
263 static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
265 struct dreplsrv_op_pull_source_state *state = tevent_req_data(req,
266 struct dreplsrv_op_pull_source_state);
267 struct repsFromTo1 *rf1 = state->op->source_dsa->repsFrom1;
268 struct dreplsrv_service *service = state->op->service;
269 struct dreplsrv_partition *partition = state->op->source_dsa->partition;
270 struct dreplsrv_drsuapi_connection *drsuapi = state->op->source_dsa->conn->drsuapi;
271 struct drsuapi_DsGetNCChanges *r;
272 struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector;
273 struct tevent_req *subreq;
275 if ((rf1->replica_flags & DRSUAPI_DRS_WRIT_REP) == 0 &&
276 state->op->extended_op == DRSUAPI_EXOP_NONE) {
277 return;
280 r = talloc(state, struct drsuapi_DsGetNCChanges);
281 if (tevent_req_nomem(r, req)) {
282 return;
285 r->out.level_out = talloc(r, uint32_t);
286 if (tevent_req_nomem(r->out.level_out, req)) {
287 return;
289 r->in.req = talloc(r, union drsuapi_DsGetNCChangesRequest);
290 if (tevent_req_nomem(r->in.req, req)) {
291 return;
293 r->out.ctr = talloc(r, union drsuapi_DsGetNCChangesCtr);
294 if (tevent_req_nomem(r->out.ctr, req)) {
295 return;
298 if (partition->uptodatevector_ex.count == 0) {
299 uptodateness_vector = NULL;
300 } else {
301 uptodateness_vector = &partition->uptodatevector_ex;
304 r->in.bind_handle = &drsuapi->bind_handle;
305 if (drsuapi->remote_info28.supported_extensions & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8) {
306 r->in.level = 8;
307 r->in.req->req8.destination_dsa_guid = service->ntds_guid;
308 r->in.req->req8.source_dsa_invocation_id= rf1->source_dsa_invocation_id;
309 r->in.req->req8.naming_context = &partition->nc;
310 r->in.req->req8.highwatermark = rf1->highwatermark;
311 r->in.req->req8.uptodateness_vector = uptodateness_vector;
312 r->in.req->req8.replica_flags = rf1->replica_flags;
313 r->in.req->req8.max_object_count = 133;
314 r->in.req->req8.max_ndr_size = 1336811;
315 r->in.req->req8.extended_op = state->op->extended_op;
316 r->in.req->req8.fsmo_info = state->op->fsmo_info;
317 r->in.req->req8.partial_attribute_set = NULL;
318 r->in.req->req8.partial_attribute_set_ex= NULL;
319 r->in.req->req8.mapping_ctr.num_mappings= 0;
320 r->in.req->req8.mapping_ctr.mappings = NULL;
321 } else {
322 r->in.level = 5;
323 r->in.req->req5.destination_dsa_guid = service->ntds_guid;
324 r->in.req->req5.source_dsa_invocation_id= rf1->source_dsa_invocation_id;
325 r->in.req->req5.naming_context = &partition->nc;
326 r->in.req->req5.highwatermark = rf1->highwatermark;
327 r->in.req->req5.uptodateness_vector = uptodateness_vector;
328 r->in.req->req5.replica_flags = rf1->replica_flags;
329 r->in.req->req5.max_object_count = 133;
330 r->in.req->req5.max_ndr_size = 1336770;
331 r->in.req->req5.extended_op = state->op->extended_op;
332 r->in.req->req5.fsmo_info = state->op->fsmo_info;
335 #if 0
336 NDR_PRINT_IN_DEBUG(drsuapi_DsGetNCChanges, r);
337 #endif
339 state->ndr_struct_ptr = r;
340 subreq = dcerpc_drsuapi_DsGetNCChanges_r_send(state,
341 state->ev,
342 drsuapi->drsuapi_handle,
344 if (tevent_req_nomem(subreq, req)) {
345 return;
347 tevent_req_set_callback(subreq, dreplsrv_op_pull_source_get_changes_done, req);
350 static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req,
351 struct drsuapi_DsGetNCChanges *r,
352 uint32_t ctr_level,
353 struct drsuapi_DsGetNCChangesCtr1 *ctr1,
354 struct drsuapi_DsGetNCChangesCtr6 *ctr6);
356 static void dreplsrv_op_pull_source_get_changes_done(struct tevent_req *subreq)
358 struct tevent_req *req = tevent_req_callback_data(subreq,
359 struct tevent_req);
360 struct dreplsrv_op_pull_source_state *state = tevent_req_data(req,
361 struct dreplsrv_op_pull_source_state);
362 NTSTATUS status;
363 struct drsuapi_DsGetNCChanges *r = talloc_get_type(state->ndr_struct_ptr,
364 struct drsuapi_DsGetNCChanges);
365 uint32_t ctr_level = 0;
366 struct drsuapi_DsGetNCChangesCtr1 *ctr1 = NULL;
367 struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL;
369 state->ndr_struct_ptr = NULL;
371 status = dcerpc_drsuapi_DsGetNCChanges_r_recv(subreq, r);
372 TALLOC_FREE(subreq);
373 if (tevent_req_nterror(req, status)) {
374 return;
377 if (!W_ERROR_IS_OK(r->out.result)) {
378 status = werror_to_ntstatus(r->out.result);
379 tevent_req_nterror(req, status);
380 return;
383 if (*r->out.level_out == 1) {
384 ctr_level = 1;
385 ctr1 = &r->out.ctr->ctr1;
386 } else if (*r->out.level_out == 2 &&
387 r->out.ctr->ctr2.mszip1.ts) {
388 ctr_level = 1;
389 ctr1 = &r->out.ctr->ctr2.mszip1.ts->ctr1;
390 } else if (*r->out.level_out == 6) {
391 ctr_level = 6;
392 ctr6 = &r->out.ctr->ctr6;
393 } else if (*r->out.level_out == 7 &&
394 r->out.ctr->ctr7.level == 6 &&
395 r->out.ctr->ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP &&
396 r->out.ctr->ctr7.ctr.mszip6.ts) {
397 ctr_level = 6;
398 ctr6 = &r->out.ctr->ctr7.ctr.mszip6.ts->ctr6;
399 } else if (*r->out.level_out == 7 &&
400 r->out.ctr->ctr7.level == 6 &&
401 r->out.ctr->ctr7.type == DRSUAPI_COMPRESSION_TYPE_XPRESS &&
402 r->out.ctr->ctr7.ctr.xpress6.ts) {
403 ctr_level = 6;
404 ctr6 = &r->out.ctr->ctr7.ctr.xpress6.ts->ctr6;
405 } else {
406 status = werror_to_ntstatus(WERR_BAD_NET_RESP);
407 tevent_req_nterror(req, status);
408 return;
411 if (!ctr1 && !ctr6) {
412 status = werror_to_ntstatus(WERR_BAD_NET_RESP);
413 tevent_req_nterror(req, status);
414 return;
417 if (ctr_level == 6) {
418 if (!W_ERROR_IS_OK(ctr6->drs_error)) {
419 status = werror_to_ntstatus(ctr6->drs_error);
420 tevent_req_nterror(req, status);
421 return;
425 dreplsrv_op_pull_source_apply_changes_trigger(req, r, ctr_level, ctr1, ctr6);
428 static void dreplsrv_update_refs_trigger(struct tevent_req *req);
430 static void dreplsrv_op_pull_source_apply_changes_trigger(struct tevent_req *req,
431 struct drsuapi_DsGetNCChanges *r,
432 uint32_t ctr_level,
433 struct drsuapi_DsGetNCChangesCtr1 *ctr1,
434 struct drsuapi_DsGetNCChangesCtr6 *ctr6)
436 struct dreplsrv_op_pull_source_state *state = tevent_req_data(req,
437 struct dreplsrv_op_pull_source_state);
438 struct repsFromTo1 rf1 = *state->op->source_dsa->repsFrom1;
439 struct dreplsrv_service *service = state->op->service;
440 struct dreplsrv_partition *partition = state->op->source_dsa->partition;
441 struct dreplsrv_drsuapi_connection *drsuapi = state->op->source_dsa->conn->drsuapi;
442 const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
443 uint32_t object_count;
444 struct drsuapi_DsReplicaObjectListItemEx *first_object;
445 uint32_t linked_attributes_count;
446 struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
447 const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector;
448 struct dsdb_extended_replicated_objects *objects;
449 bool more_data = false;
450 WERROR status;
451 NTSTATUS nt_status;
453 switch (ctr_level) {
454 case 1:
455 mapping_ctr = &ctr1->mapping_ctr;
456 object_count = ctr1->object_count;
457 first_object = ctr1->first_object;
458 linked_attributes_count = 0;
459 linked_attributes = NULL;
460 rf1.highwatermark = ctr1->new_highwatermark;
461 uptodateness_vector = NULL; /* TODO: map it */
462 more_data = ctr1->more_data;
463 break;
464 case 6:
465 mapping_ctr = &ctr6->mapping_ctr;
466 object_count = ctr6->object_count;
467 first_object = ctr6->first_object;
468 linked_attributes_count = ctr6->linked_attributes_count;
469 linked_attributes = ctr6->linked_attributes;
470 rf1.highwatermark = ctr6->new_highwatermark;
471 uptodateness_vector = ctr6->uptodateness_vector;
472 more_data = ctr6->more_data;
473 break;
474 default:
475 nt_status = werror_to_ntstatus(WERR_BAD_NET_RESP);
476 tevent_req_nterror(req, nt_status);
477 return;
480 status = dsdb_extended_replicated_objects_convert(service->samdb,
481 partition->nc.dn,
482 mapping_ctr,
483 object_count,
484 first_object,
485 linked_attributes_count,
486 linked_attributes,
487 &rf1,
488 uptodateness_vector,
489 &drsuapi->gensec_skey,
490 state, &objects);
491 if (!W_ERROR_IS_OK(status)) {
492 nt_status = werror_to_ntstatus(WERR_BAD_NET_RESP);
493 DEBUG(0,("Failed to convert objects: %s/%s\n",
494 win_errstr(status), nt_errstr(nt_status)));
495 tevent_req_nterror(req, nt_status);
496 return;
499 status = dsdb_extended_replicated_objects_commit(service->samdb,
500 objects,
501 &state->op->source_dsa->notify_uSN);
502 talloc_free(objects);
503 if (!W_ERROR_IS_OK(status)) {
504 nt_status = werror_to_ntstatus(WERR_BAD_NET_RESP);
505 DEBUG(0,("Failed to commit objects: %s/%s\n",
506 win_errstr(status), nt_errstr(nt_status)));
507 tevent_req_nterror(req, nt_status);
508 return;
511 /* if it applied fine, we need to update the highwatermark */
512 *state->op->source_dsa->repsFrom1 = rf1;
515 * TODO: update our uptodatevector!
518 /* we don't need this maybe very large structure anymore */
519 TALLOC_FREE(r);
521 if (more_data) {
522 dreplsrv_op_pull_source_get_changes_trigger(req);
523 return;
526 /* now we need to update the repsTo record for this partition
527 on the server. These records are initially established when
528 we join the domain, but they quickly expire. We do it here
529 so we can use the already established DRSUAPI pipe
531 if (state->op->extended_op == DRSUAPI_EXOP_NONE) {
532 dreplsrv_update_refs_trigger(req);
533 } else {
534 tevent_req_done(req);
538 static void dreplsrv_update_refs_done(struct tevent_req *subreq);
541 send a UpdateRefs request to refresh our repsTo record on the server
543 static void dreplsrv_update_refs_trigger(struct tevent_req *req)
545 struct dreplsrv_op_pull_source_state *state = tevent_req_data(req,
546 struct dreplsrv_op_pull_source_state);
547 struct dreplsrv_service *service = state->op->service;
548 struct dreplsrv_partition *partition = state->op->source_dsa->partition;
549 struct dreplsrv_drsuapi_connection *drsuapi = state->op->source_dsa->conn->drsuapi;
550 struct drsuapi_DsReplicaUpdateRefs *r;
551 char *ntds_guid_str;
552 char *ntds_dns_name;
553 struct tevent_req *subreq;
554 bool am_rodc;
555 int ret;
557 r = talloc(state, struct drsuapi_DsReplicaUpdateRefs);
558 if (tevent_req_nomem(r, req)) {
559 return;
562 ntds_guid_str = GUID_string(r, &service->ntds_guid);
563 if (tevent_req_nomem(ntds_guid_str, req)) {
564 return;
567 ntds_dns_name = talloc_asprintf(r, "%s._msdcs.%s",
568 ntds_guid_str,
569 lp_dnsdomain(service->task->lp_ctx));
570 if (tevent_req_nomem(ntds_dns_name, req)) {
571 return;
574 r->in.bind_handle = &drsuapi->bind_handle;
575 r->in.level = 1;
576 r->in.req.req1.naming_context = &partition->nc;
577 r->in.req.req1.dest_dsa_dns_name = ntds_dns_name;
578 r->in.req.req1.dest_dsa_guid = service->ntds_guid;
579 r->in.req.req1.options = DRSUAPI_DRS_ADD_REF | DRSUAPI_DRS_DEL_REF;
580 ret = samdb_rodc(service->samdb, &am_rodc);
581 if (ret == LDB_SUCCESS && !am_rodc) {
582 r->in.req.req1.options |= DRSUAPI_DRS_WRIT_REP;
585 state->ndr_struct_ptr = r;
586 subreq = dcerpc_drsuapi_DsReplicaUpdateRefs_r_send(state,
587 state->ev,
588 drsuapi->drsuapi_handle,
590 if (tevent_req_nomem(subreq, req)) {
591 return;
593 tevent_req_set_callback(subreq, dreplsrv_update_refs_done, req);
597 receive a UpdateRefs reply
599 static void dreplsrv_update_refs_done(struct tevent_req *subreq)
601 struct tevent_req *req = tevent_req_callback_data(subreq,
602 struct tevent_req);
603 struct dreplsrv_op_pull_source_state *state = tevent_req_data(req,
604 struct dreplsrv_op_pull_source_state);
605 struct drsuapi_DsReplicaUpdateRefs *r = talloc_get_type(state->ndr_struct_ptr,
606 struct drsuapi_DsReplicaUpdateRefs);
607 NTSTATUS status;
609 state->ndr_struct_ptr = NULL;
611 status = dcerpc_drsuapi_DsReplicaUpdateRefs_r_recv(subreq, r);
612 TALLOC_FREE(subreq);
613 if (!NT_STATUS_IS_OK(status)) {
614 DEBUG(0,("UpdateRefs failed with %s\n",
615 nt_errstr(status)));
616 tevent_req_nterror(req, status);
617 return;
620 if (!W_ERROR_IS_OK(r->out.result)) {
621 status = werror_to_ntstatus(r->out.result);
622 DEBUG(0,("UpdateRefs failed with %s/%s for %s %s\n",
623 win_errstr(r->out.result),
624 nt_errstr(status),
625 r->in.req.req1.dest_dsa_dns_name,
626 r->in.req.req1.naming_context->dn));
627 tevent_req_nterror(req, status);
628 return;
631 DEBUG(4,("UpdateRefs OK for %s %s\n",
632 r->in.req.req1.dest_dsa_dns_name,
633 r->in.req.req1.naming_context->dn));
635 tevent_req_done(req);
638 WERROR dreplsrv_op_pull_source_recv(struct tevent_req *req)
640 NTSTATUS status;
642 if (tevent_req_is_nterror(req, &status)) {
643 tevent_req_received(req);
644 return ntstatus_to_werror(status);
647 tevent_req_received(req);
648 return WERR_OK;