2 Unix SMB/CIFS implementation.
4 Extract the user/system database from a remote server
6 Copyright (C) Stefan Metzmacher 2004-2006
7 Copyright (C) Brad Henry 2005
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2008
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "libnet/libnet.h"
27 #include "lib/events/events.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "../lib/util/dlinklist.h"
31 #include <ldb_errors.h>
32 #include "librpc/ndr/libndr.h"
33 #include "librpc/gen_ndr/ndr_drsuapi.h"
34 #include "librpc/gen_ndr/ndr_drsblobs.h"
35 #include "librpc/gen_ndr/ndr_misc.h"
36 #include "system/time.h"
38 #include "auth/auth.h"
39 #include "auth/credentials/credentials.h"
40 #include "param/param.h"
41 #include "param/provision.h"
42 #include "libcli/security/security.h"
43 #include "dsdb/common/util.h"
46 List of tasks vampire.py must perform:
48 - but don't write the secrets.ldb
49 - results for this should be enough to handle the provision
50 - if vampire method is samsync
51 - Provision using these results
52 - do we still want to support this NT4 technology?
53 - Start samsync with libnet code
54 - provision in the callback
55 - Write out the secrets database, using the code from libnet_Join
58 struct libnet_vampire_cb_state {
59 const char *netbios_name;
60 const char *domain_name;
62 struct cli_credentials *machine_account;
64 /* Schema loaded from local LDIF files */
65 struct dsdb_schema *provision_schema;
67 /* 1st pass, with some OIDs/attribute names/class names not
68 * converted, because we may not know them yet */
69 struct dsdb_schema *self_made_schema;
71 /* prefixMap in LDB format, from the remote DRS server */
72 DATA_BLOB prefixmap_blob;
73 const struct dsdb_schema *schema;
75 struct ldb_context *ldb;
78 uint32_t object_count;
79 struct drsuapi_DsReplicaObjectListItemEx *first_object;
80 struct drsuapi_DsReplicaObjectListItemEx *last_object;
83 const char *targetdir;
85 struct loadparm_context *lp_ctx;
86 struct tevent_context *event_ctx;
87 unsigned total_objects;
89 const char *server_dn_str;
92 /* initialise a state structure ready for replication of chunks */
93 void *libnet_vampire_replicate_init(TALLOC_CTX *mem_ctx,
94 struct ldb_context *samdb,
95 struct loadparm_context *lp_ctx)
97 struct libnet_vampire_cb_state *s = talloc_zero(mem_ctx, struct libnet_vampire_cb_state);
104 s->provision_schema = dsdb_get_schema(s->ldb, s);
105 s->schema = s->provision_schema;
106 s->netbios_name = lpcfg_netbios_name(lp_ctx);
107 s->domain_name = lpcfg_workgroup(lp_ctx);
108 s->realm = lpcfg_realm(lp_ctx);
113 /* Caller is expected to keep supplied pointers around for the lifetime of the structure */
114 void *libnet_vampire_cb_state_init(TALLOC_CTX *mem_ctx,
115 struct loadparm_context *lp_ctx, struct tevent_context *event_ctx,
116 const char *netbios_name, const char *domain_name, const char *realm,
117 const char *targetdir)
119 struct libnet_vampire_cb_state *s = talloc_zero(mem_ctx, struct libnet_vampire_cb_state);
125 s->event_ctx = event_ctx;
126 s->netbios_name = netbios_name;
127 s->domain_name = domain_name;
129 s->targetdir = targetdir;
133 struct ldb_context *libnet_vampire_cb_ldb(struct libnet_vampire_cb_state *state)
135 state = talloc_get_type_abort(state, struct libnet_vampire_cb_state);
139 struct loadparm_context *libnet_vampire_cb_lp_ctx(struct libnet_vampire_cb_state *state)
141 state = talloc_get_type_abort(state, struct libnet_vampire_cb_state);
142 return state->lp_ctx;
145 NTSTATUS libnet_vampire_cb_prepare_db(void *private_data,
146 const struct libnet_BecomeDC_PrepareDB *p)
148 struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state);
149 struct provision_settings settings;
150 struct provision_result result;
153 ZERO_STRUCT(settings);
154 settings.site_name = p->dest_dsa->site_name;
155 settings.root_dn_str = p->forest->root_dn_str;
156 settings.domain_dn_str = p->domain->dn_str;
157 settings.config_dn_str = p->forest->config_dn_str;
158 settings.schema_dn_str = p->forest->schema_dn_str;
159 settings.netbios_name = p->dest_dsa->netbios_name;
160 settings.realm = s->realm;
161 settings.domain = s->domain_name;
162 settings.server_dn_str = p->dest_dsa->server_dn_str;
163 settings.machine_password = generate_random_machine_password(s, 128, 255);
164 settings.targetdir = s->targetdir;
165 settings.use_ntvfs = true;
166 status = provision_bare(s, s->lp_ctx, &settings, &result);
168 if (!NT_STATUS_IS_OK(status)) {
172 s->ldb = talloc_steal(s, result.samdb);
173 s->lp_ctx = talloc_reparent(talloc_parent(result.lp_ctx), s, result.lp_ctx);
174 s->provision_schema = dsdb_get_schema(s->ldb, s);
175 s->server_dn_str = talloc_steal(s, p->dest_dsa->server_dn_str);
177 /* wrap the entire vapire operation in a transaction. This
178 isn't just cosmetic - we use this to ensure that linked
179 attribute back links are added at the end by relying on a
180 transaction commit hook in the linked attributes module. We
181 need to do this as the order of objects coming from the
182 server is not sufficiently deterministic to know that the
183 record that a backlink needs to be created in has itself
184 been created before the object containing the forward link
185 has come over the wire */
186 if (ldb_transaction_start(s->ldb) != LDB_SUCCESS) {
187 return NT_STATUS_FOOBAR;
195 NTSTATUS libnet_vampire_cb_check_options(void *private_data,
196 const struct libnet_BecomeDC_CheckOptions *o)
198 struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state);
200 DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n",
202 o->domain->netbios_name, o->domain->dns_name));
204 DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n",
205 o->source_dsa->dns_name, o->source_dsa->site_name));
207 DEBUG(0,("Options:crossRef behavior_version[%u]\n"
208 "\tschema object_version[%u]\n"
209 "\tdomain behavior_version[%u]\n"
210 "\tdomain w2k3_update_revision[%u]\n",
211 o->forest->crossref_behavior_version,
212 o->forest->schema_object_version,
213 o->domain->behavior_version,
214 o->domain->w2k3_update_revision));
219 static WERROR libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s,
220 const struct libnet_BecomeDC_StoreChunk *c)
223 struct dsdb_schema_prefixmap *pfm_remote;
224 const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
225 struct dsdb_schema *provision_schema;
226 uint32_t object_count = 0;
227 struct drsuapi_DsReplicaObjectListItemEx *first_object;
228 uint32_t linked_attributes_count;
229 struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
230 const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector;
231 struct dsdb_extended_replicated_objects *schema_objs;
232 struct repsFromTo1 *s_dsa;
234 struct ldb_context *schema_ldb;
235 struct ldb_dn *partition_dn;
236 struct ldb_message *msg;
237 struct ldb_message_element *prefixMap_el;
241 uint64_t seq_num = 0;
242 uint32_t cycle_before_switching;
244 DEBUG(0,("Analyze and apply schema objects\n"));
246 s_dsa = talloc_zero(s, struct repsFromTo1);
248 return WERR_NOT_ENOUGH_MEMORY;
250 s_dsa->other_info = talloc(s_dsa, struct repsFromTo1OtherInfo);
251 if (s_dsa->other_info == NULL) {
252 return WERR_NOT_ENOUGH_MEMORY;
255 switch (c->ctr_level) {
257 mapping_ctr = &c->ctr1->mapping_ctr;
258 object_count = s->schema_part.object_count;
259 first_object = s->schema_part.first_object;
260 linked_attributes_count = 0;
261 linked_attributes = NULL;
262 s_dsa->highwatermark = c->ctr1->new_highwatermark;
263 s_dsa->source_dsa_obj_guid = c->ctr1->source_dsa_guid;
264 s_dsa->source_dsa_invocation_id = c->ctr1->source_dsa_invocation_id;
265 uptodateness_vector = NULL; /* TODO: map it */
268 mapping_ctr = &c->ctr6->mapping_ctr;
269 object_count = s->schema_part.object_count;
270 first_object = s->schema_part.first_object;
271 linked_attributes_count = c->ctr6->linked_attributes_count;
272 linked_attributes = c->ctr6->linked_attributes;
273 s_dsa->highwatermark = c->ctr6->new_highwatermark;
274 s_dsa->source_dsa_obj_guid = c->ctr6->source_dsa_guid;
275 s_dsa->source_dsa_invocation_id = c->ctr6->source_dsa_invocation_id;
276 uptodateness_vector = c->ctr6->uptodateness_vector;
279 return WERR_INVALID_PARAMETER;
281 /* We must set these up to ensure the replMetaData is written
282 * correctly, before our NTDS Settings entry is replicated */
283 ok = samdb_set_ntds_invocation_id(s->ldb, &c->dest_dsa->invocation_id);
285 DEBUG(0,("Failed to set cached ntds invocationId\n"));
286 return WERR_INTERNAL_ERROR;
288 ok = samdb_set_ntds_objectGUID(s->ldb, &c->dest_dsa->ntds_guid);
290 DEBUG(0,("Failed to set cached ntds objectGUID\n"));
291 return WERR_INTERNAL_ERROR;
294 status = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true,
295 s, &pfm_remote, NULL);
296 if (!W_ERROR_IS_OK(status)) {
297 DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s",
298 win_errstr(status)));
302 s_dsa->replica_flags = DRSUAPI_DRS_WRIT_REP
303 | DRSUAPI_DRS_INIT_SYNC
304 | DRSUAPI_DRS_PER_SYNC;
305 memset(s_dsa->schedule, 0x11, sizeof(s_dsa->schedule));
307 tmp_dns_name = GUID_string(s_dsa->other_info, &s_dsa->source_dsa_obj_guid);
308 if (tmp_dns_name == NULL) {
309 return WERR_NOT_ENOUGH_MEMORY;
311 tmp_dns_name = talloc_asprintf_append_buffer(tmp_dns_name, "._msdcs.%s", c->forest->dns_name);
312 if (tmp_dns_name == NULL) {
313 return WERR_NOT_ENOUGH_MEMORY;
315 s_dsa->other_info->dns_name = tmp_dns_name;
317 if (s->self_made_schema == NULL) {
318 DEBUG(0,("libnet_vampire_cb_apply_schema: called with out self_made_schema\n"));
319 return WERR_INTERNAL_ERROR;
322 schema_ldb = provision_get_schema(s, s->lp_ctx,
323 c->forest->schema_dn_str,
326 DEBUG(0,("Failed to re-load from local provision using remote prefixMap. "
327 "Will continue with local prefixMap\n"));
328 provision_schema = dsdb_get_schema(s->ldb, s);
330 provision_schema = dsdb_get_schema(schema_ldb, s);
331 ret = dsdb_reference_schema(s->ldb, provision_schema, false);
332 if (ret != LDB_SUCCESS) {
333 DEBUG(0,("Failed to attach schema from local provision using remote prefixMap."));
334 return WERR_INTERNAL_ERROR;
336 talloc_free(schema_ldb);
339 cycle_before_switching = lpcfg_parm_long(s->lp_ctx, NULL,
341 "schema convert retrial", 1);
343 provision_schema->resolving_in_progress = true;
344 s->self_made_schema->resolving_in_progress = true;
346 status = dsdb_repl_resolve_working_schema(s->ldb,
348 cycle_before_switching,
353 if (!W_ERROR_IS_OK(status)) {
354 DEBUG(0, ("%s: dsdb_repl_resolve_working_schema() failed: %s",
355 __location__, win_errstr(status)));
359 /* free temp objects for 1st conversion phase */
360 talloc_unlink(s, provision_schema);
362 s->self_made_schema->resolving_in_progress = false;
365 * attach the schema we just brought over DRS to the ldb,
366 * so we can use it in dsdb_convert_object_ex below
368 ret = dsdb_set_schema(s->ldb, s->self_made_schema, true);
369 if (ret != LDB_SUCCESS) {
370 DEBUG(0,("Failed to attach working schema from DRS.\n"));
371 return WERR_INTERNAL_ERROR;
374 /* we don't want to access the self made schema anymore */
375 s->schema = s->self_made_schema;
376 s->self_made_schema = NULL;
378 partition_dn = ldb_dn_new(s, s->ldb, c->partition->nc.dn);
379 if (partition_dn == NULL) {
380 DEBUG(0,("Failed to parse partition DN from DRS.\n"));
381 return WERR_INVALID_PARAMETER;
384 /* Now convert the schema elements again, using the schema we finalised, ready to actually import */
385 status = dsdb_replicated_objects_convert(s->ldb,
391 linked_attributes_count,
398 if (!W_ERROR_IS_OK(status)) {
399 DEBUG(0,("Failed to convert objects when trying to import over DRS (2nd pass, to store remote schema): %s\n", win_errstr(status)));
403 if (lpcfg_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) {
404 for (i=0; i < schema_objs->num_objects; i++) {
405 struct ldb_ldif ldif;
406 fprintf(stdout, "#\n");
407 ldif.changetype = LDB_CHANGETYPE_NONE;
408 ldif.msg = schema_objs->objects[i].msg;
409 ldb_ldif_write_file(s->ldb, stdout, &ldif);
410 NDR_PRINT_DEBUG(replPropertyMetaDataBlob, schema_objs->objects[i].meta_data);
414 status = dsdb_replicated_objects_commit(s->ldb, NULL, schema_objs, &seq_num);
415 if (!W_ERROR_IS_OK(status)) {
416 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
420 msg = ldb_msg_new(schema_objs);
422 return WERR_NOT_ENOUGH_MEMORY;
424 msg->dn = schema_objs->partition_dn;
426 /* We must ensure a prefixMap has been written. Unlike other
427 * attributes (including schemaInfo), it is not replicated in
428 * the normal replication stream. We can use the one from
429 * s->prefixmap_blob because we operate with one, unchanging
430 * prefixMap for this entire operation. */
431 ret = ldb_msg_add_value(msg, "prefixMap", &s->prefixmap_blob, &prefixMap_el);
432 if (ret != LDB_SUCCESS) {
433 return WERR_NOT_ENOUGH_MEMORY;
435 /* We want to know if a prefixMap was written already, as it
436 * would mean that the above comment was not true, and we have
437 * somehow updated the prefixMap during this transaction */
438 prefixMap_el->flags = LDB_FLAG_MOD_ADD;
440 ret = dsdb_modify(s->ldb, msg, DSDB_FLAG_AS_SYSTEM);
441 if (ret != LDB_SUCCESS) {
442 DEBUG(0,("Failed to add prefixMap: %s\n", ldb_errstring(s->ldb)));
443 return WERR_INTERNAL_ERROR;
447 talloc_free(schema_objs);
449 s->schema = dsdb_get_schema(s->ldb, s);
451 DEBUG(0,("Failed to get loaded dsdb_schema\n"));
452 return WERR_INTERNAL_ERROR;
458 WERROR libnet_vampire_cb_schema_chunk(void *private_data,
459 const struct libnet_BecomeDC_StoreChunk *c)
461 struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state);
463 const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
464 uint32_t nc_object_count;
465 uint32_t nc_total_received = 0;
466 uint32_t object_count;
467 struct drsuapi_DsReplicaObjectListItemEx *first_object;
468 struct drsuapi_DsReplicaObjectListItemEx *cur;
469 uint32_t nc_linked_attributes_count;
470 uint32_t linked_attributes_count;
472 switch (c->ctr_level) {
474 mapping_ctr = &c->ctr1->mapping_ctr;
475 nc_object_count = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */
476 object_count = c->ctr1->object_count;
477 first_object = c->ctr1->first_object;
478 nc_linked_attributes_count = 0;
479 linked_attributes_count = 0;
482 mapping_ctr = &c->ctr6->mapping_ctr;
483 nc_object_count = c->ctr6->nc_object_count;
484 object_count = c->ctr6->object_count;
485 first_object = c->ctr6->first_object;
486 nc_linked_attributes_count = c->ctr6->nc_linked_attributes_count;
487 linked_attributes_count = c->ctr6->linked_attributes_count;
490 return WERR_INVALID_PARAMETER;
493 if (!s->schema_part.first_object) {
494 nc_total_received = object_count;
496 nc_total_received = s->schema_part.object_count + object_count;
498 if (nc_object_count) {
499 DEBUG(0,("Schema-DN[%s] objects[%u/%u] linked_values[%u/%u]\n",
500 c->partition->nc.dn, nc_total_received, nc_object_count,
501 linked_attributes_count, nc_linked_attributes_count));
503 DEBUG(0,("Schema-DN[%s] objects[%u] linked_values[%u]\n",
504 c->partition->nc.dn, nc_total_received, linked_attributes_count));
507 if (!s->self_made_schema) {
508 struct drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr_without_schema_info;
509 /* Put the DRS prefixmap aside for the schema we are
510 * about to load in the provision, and into the one we
511 * are making with the help of DRS */
513 mapping_ctr_without_schema_info = *mapping_ctr;
515 /* This strips off the 0xFF schema info from the end,
516 * because we don't want it in the blob */
517 if (mapping_ctr_without_schema_info.num_mappings > 0) {
518 mapping_ctr_without_schema_info.num_mappings--;
520 werr = dsdb_get_drsuapi_prefixmap_as_blob(&mapping_ctr_without_schema_info, s, &s->prefixmap_blob);
521 if (!W_ERROR_IS_OK(werr)) {
525 /* Set up two manually-constructed schema - the local
526 * schema from the provision will be used to build
527 * one, which will then in turn be used to build the
529 s->self_made_schema = dsdb_new_schema(s);
530 if (s->self_made_schema == NULL) {
531 return WERR_NOT_ENOUGH_MEMORY;
534 werr = dsdb_load_prefixmap_from_drsuapi(s->self_made_schema, mapping_ctr);
535 if (!W_ERROR_IS_OK(werr)) {
539 werr = dsdb_schema_pfm_contains_drsuapi_pfm(s->self_made_schema->prefixmap, mapping_ctr);
540 if (!W_ERROR_IS_OK(werr)) {
545 if (!s->schema_part.first_object) {
546 s->schema_part.object_count = object_count;
547 s->schema_part.first_object = talloc_steal(s, first_object);
549 s->schema_part.object_count += object_count;
550 s->schema_part.last_object->next_object = talloc_steal(s->schema_part.last_object,
553 for (cur = first_object; cur->next_object; cur = cur->next_object) {}
554 s->schema_part.last_object = cur;
556 if (!c->partition->more_data) {
557 return libnet_vampire_cb_apply_schema(s, c);
563 WERROR libnet_vampire_cb_store_chunk(void *private_data,
564 const struct libnet_BecomeDC_StoreChunk *c)
566 struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state);
568 struct dsdb_schema *schema;
569 const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
570 uint32_t nc_object_count;
571 uint32_t object_count;
572 struct drsuapi_DsReplicaObjectListItemEx *first_object;
573 uint32_t nc_linked_attributes_count;
574 uint32_t linked_attributes_count;
575 struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
576 const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector;
577 struct dsdb_extended_replicated_objects *objs;
578 uint32_t req_replica_flags;
579 uint32_t dsdb_repl_flags = 0;
580 struct repsFromTo1 *s_dsa;
584 bool is_exop = false;
585 struct ldb_dn *partition_dn = NULL;
586 struct ldb_dn *nc_root = NULL;
588 s_dsa = talloc_zero(s, struct repsFromTo1);
590 return WERR_NOT_ENOUGH_MEMORY;
592 s_dsa->other_info = talloc(s_dsa, struct repsFromTo1OtherInfo);
593 if (s_dsa->other_info == NULL) {
594 return WERR_NOT_ENOUGH_MEMORY;
597 switch (c->ctr_level) {
599 mapping_ctr = &c->ctr1->mapping_ctr;
600 nc_object_count = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */
601 object_count = c->ctr1->object_count;
602 first_object = c->ctr1->first_object;
603 nc_linked_attributes_count = 0;
604 linked_attributes_count = 0;
605 linked_attributes = NULL;
606 s_dsa->highwatermark = c->ctr1->new_highwatermark;
607 s_dsa->source_dsa_obj_guid = c->ctr1->source_dsa_guid;
608 s_dsa->source_dsa_invocation_id = c->ctr1->source_dsa_invocation_id;
609 uptodateness_vector = NULL; /* TODO: map it */
612 mapping_ctr = &c->ctr6->mapping_ctr;
613 nc_object_count = c->ctr6->nc_object_count;
614 object_count = c->ctr6->object_count;
615 first_object = c->ctr6->first_object;
616 nc_linked_attributes_count = c->ctr6->nc_linked_attributes_count;
617 linked_attributes_count = c->ctr6->linked_attributes_count;
618 linked_attributes = c->ctr6->linked_attributes;
619 s_dsa->highwatermark = c->ctr6->new_highwatermark;
620 s_dsa->source_dsa_obj_guid = c->ctr6->source_dsa_guid;
621 s_dsa->source_dsa_invocation_id = c->ctr6->source_dsa_invocation_id;
622 uptodateness_vector = c->ctr6->uptodateness_vector;
625 return WERR_INVALID_PARAMETER;
628 switch (c->req_level) {
631 req_replica_flags = 0;
634 if (c->req5->extended_op != DRSUAPI_EXOP_NONE) {
637 req_replica_flags = c->req5->replica_flags;
640 if (c->req8->extended_op != DRSUAPI_EXOP_NONE) {
643 req_replica_flags = c->req8->replica_flags;
646 if (c->req10->extended_op != DRSUAPI_EXOP_NONE) {
649 req_replica_flags = c->req10->replica_flags;
652 return WERR_INVALID_PARAMETER;
655 if (req_replica_flags & DRSUAPI_DRS_CRITICAL_ONLY || is_exop) {
657 * If we only replicate the critical objects, or this
658 * is an exop we should not remember what we already
659 * got, as it is incomplete.
661 ZERO_STRUCT(s_dsa->highwatermark);
662 uptodateness_vector = NULL;
663 dsdb_repl_flags |= DSDB_REPL_FLAG_OBJECT_SUBSET;
666 /* TODO: avoid hardcoded flags */
667 s_dsa->replica_flags = DRSUAPI_DRS_WRIT_REP
668 | DRSUAPI_DRS_INIT_SYNC
669 | DRSUAPI_DRS_PER_SYNC;
670 memset(s_dsa->schedule, 0x11, sizeof(s_dsa->schedule));
672 tmp_dns_name = GUID_string(s_dsa->other_info, &s_dsa->source_dsa_obj_guid);
673 if (tmp_dns_name == NULL) {
674 return WERR_NOT_ENOUGH_MEMORY;
676 tmp_dns_name = talloc_asprintf_append_buffer(tmp_dns_name, "._msdcs.%s", c->forest->dns_name);
677 if (tmp_dns_name == NULL) {
678 return WERR_NOT_ENOUGH_MEMORY;
680 s_dsa->other_info->dns_name = tmp_dns_name;
682 /* we want to show a count per partition */
683 if (!s->last_partition || strcmp(s->last_partition, c->partition->nc.dn) != 0) {
684 s->total_objects = 0;
685 talloc_free(s->last_partition);
686 s->last_partition = talloc_strdup(s, c->partition->nc.dn);
688 s->total_objects += object_count;
690 partition_dn = ldb_dn_new(s, s->ldb, c->partition->nc.dn);
691 if (partition_dn == NULL) {
692 DEBUG(0,("Failed to parse partition DN from DRS.\n"));
693 return WERR_INVALID_PARAMETER;
698 if (nc_object_count) {
699 DEBUG(0,("Exop on[%s] objects[%u/%u] linked_values[%u/%u]\n",
700 c->partition->nc.dn, s->total_objects, nc_object_count,
701 linked_attributes_count, nc_linked_attributes_count));
703 DEBUG(0,("Exop on[%s] objects[%u] linked_values[%u]\n",
704 c->partition->nc.dn, s->total_objects, linked_attributes_count));
706 ret = dsdb_find_nc_root(s->ldb, s,
707 partition_dn, &nc_root);
708 if (ret != LDB_SUCCESS) {
709 DEBUG(0,(__location__ ": Failed to find nc_root for %s\n",
710 ldb_dn_get_linearized(partition_dn)));
711 return WERR_INTERNAL_ERROR;
714 if (nc_object_count) {
715 DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n",
716 c->partition->nc.dn, s->total_objects, nc_object_count,
717 linked_attributes_count, nc_linked_attributes_count));
719 DEBUG(0,("Partition[%s] objects[%u] linked_values[%u]\n",
720 c->partition->nc.dn, s->total_objects, linked_attributes_count));
722 nc_root = partition_dn;
726 schema = dsdb_get_schema(s->ldb, NULL);
728 DEBUG(0,(__location__ ": Schema is not loaded yet!\n"));
729 return WERR_INTERNAL_ERROR;
732 if (req_replica_flags & DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS) {
733 dsdb_repl_flags |= DSDB_REPL_FLAG_PRIORITISE_INCOMING;
736 if (req_replica_flags & DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) {
737 dsdb_repl_flags |= DSDB_REPL_FLAG_EXPECT_NO_SECRETS;
740 status = dsdb_replicated_objects_convert(s->ldb,
746 linked_attributes_count,
753 if (!W_ERROR_IS_OK(status)) {
754 DEBUG(0,("Failed to convert objects: %s\n", win_errstr(status)));
758 if (lpcfg_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) {
759 for (i=0; i < objs->num_objects; i++) {
760 struct ldb_ldif ldif;
761 fprintf(stdout, "#\n");
762 ldif.changetype = LDB_CHANGETYPE_NONE;
763 ldif.msg = objs->objects[i].msg;
764 ldb_ldif_write_file(s->ldb, stdout, &ldif);
765 NDR_PRINT_DEBUG(replPropertyMetaDataBlob, objs->objects[i].meta_data);
768 status = dsdb_replicated_objects_commit(s->ldb, NULL, objs, &seq_num);
769 if (!W_ERROR_IS_OK(status)) {
770 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
777 for (i=0; i < linked_attributes_count; i++) {
778 const struct dsdb_attribute *sa;
780 if (!linked_attributes[i].identifier) {
781 DEBUG(0, ("No linked attribute identifier\n"));
782 return WERR_INTERNAL_ERROR;
785 if (!linked_attributes[i].value.blob) {
786 DEBUG(0, ("No linked attribute value\n"));
787 return WERR_INTERNAL_ERROR;
790 sa = dsdb_attribute_by_attributeID_id(s->schema,
791 linked_attributes[i].attid);
793 DEBUG(0, ("Unable to find attribute via attribute id %d\n", linked_attributes[i].attid));
794 return WERR_INTERNAL_ERROR;
797 if (lpcfg_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) {
798 DEBUG(0,("# %s\n", sa->lDAPDisplayName));
799 NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute, &linked_attributes[i]);
801 linked_attributes[i].value.blob->data,
802 linked_attributes[i].value.blob->length);