2 Unix SMB/CIFS implementation.
4 libnet_BecomeDC() tests
6 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "lib/cmdline/popt_common.h"
24 #include "torture/rpc/rpc.h"
25 #include "libnet/libnet.h"
26 #include "dsdb/samdb/samdb.h"
27 #include "../lib/util/dlinklist.h"
28 #include "librpc/gen_ndr/ndr_drsuapi.h"
29 #include "librpc/gen_ndr/ndr_drsblobs.h"
30 #include "system/time.h"
31 #include "lib/ldb_wrap.h"
32 #include "auth/auth.h"
33 #include "param/param.h"
34 #include "param/provision.h"
35 #include "libcli/resolve/resolve.h"
37 struct test_become_dc_state
{
38 struct libnet_context
*ctx
;
39 struct torture_context
*tctx
;
40 const char *netbios_name
;
42 struct cli_credentials
*machine_account
;
43 struct dsdb_schema
*self_made_schema
;
44 const struct dsdb_schema
*schema
;
46 struct ldb_context
*ldb
;
49 uint32_t object_count
;
50 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
51 struct drsuapi_DsReplicaObjectListItemEx
*last_object
;
54 const char *targetdir
;
56 struct loadparm_context
*lp_ctx
;
59 static NTSTATUS
test_become_dc_prepare_db(void *private_data
,
60 const struct libnet_BecomeDC_PrepareDB
*p
)
62 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
63 struct provision_settings settings
;
64 struct provision_result result
;
67 settings
.site_name
= p
->dest_dsa
->site_name
;
68 settings
.root_dn_str
= p
->forest
->root_dn_str
;
69 settings
.domain_dn_str
= p
->domain
->dn_str
;
70 settings
.config_dn_str
= p
->forest
->config_dn_str
;
71 settings
.schema_dn_str
= p
->forest
->schema_dn_str
;
72 settings
.server_dn_str
= torture_join_server_dn_str(s
->tj
);
73 settings
.invocation_id
= &p
->dest_dsa
->invocation_id
;
74 settings
.netbios_name
= p
->dest_dsa
->netbios_name
;
75 settings
.host_ip
= NULL
;
76 settings
.realm
= torture_join_dom_dns_name(s
->tj
);
77 settings
.domain
= torture_join_dom_netbios_name(s
->tj
);
78 settings
.ntds_dn_str
= p
->dest_dsa
->ntds_dn_str
;
79 settings
.machine_password
= cli_credentials_get_password(s
->machine_account
);
80 settings
.targetdir
= s
->targetdir
;
82 status
= provision_bare(s
, s
->lp_ctx
, &settings
, &result
);
84 s
->ldb
= result
.samdb
;
85 s
->lp_ctx
= result
.lp_ctx
;
91 static NTSTATUS
test_become_dc_check_options(void *private_data
,
92 const struct libnet_BecomeDC_CheckOptions
*o
)
94 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
96 DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n",
98 o
->domain
->netbios_name
, o
->domain
->dns_name
));
100 DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n",
101 o
->source_dsa
->dns_name
, o
->source_dsa
->site_name
));
103 DEBUG(0,("Options:crossRef behavior_version[%u]\n"
104 "\tschema object_version[%u]\n"
105 "\tdomain behavior_version[%u]\n"
106 "\tdomain w2k3_update_revision[%u]\n",
107 o
->forest
->crossref_behavior_version
,
108 o
->forest
->schema_object_version
,
109 o
->domain
->behavior_version
,
110 o
->domain
->w2k3_update_revision
));
115 static NTSTATUS
test_apply_schema(struct test_become_dc_state
*s
,
116 const struct libnet_BecomeDC_StoreChunk
*c
)
119 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
120 uint32_t object_count
;
121 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
122 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
123 uint32_t linked_attributes_count
;
124 struct drsuapi_DsReplicaLinkedAttribute
*linked_attributes
;
125 const struct drsuapi_DsReplicaCursor2CtrEx
*uptodateness_vector
;
126 struct dsdb_extended_replicated_objects
*objs
;
127 struct repsFromTo1
*s_dsa
;
129 struct ldb_message
*msg
;
130 struct ldb_val prefixMap_val
;
131 struct ldb_message_element
*prefixMap_el
;
132 struct ldb_val schemaInfo_val
;
139 DEBUG(0,("Analyze and apply schema objects\n"));
141 s_dsa
= talloc_zero(s
, struct repsFromTo1
);
142 NT_STATUS_HAVE_NO_MEMORY(s_dsa
);
143 s_dsa
->other_info
= talloc(s_dsa
, struct repsFromTo1OtherInfo
);
144 NT_STATUS_HAVE_NO_MEMORY(s_dsa
->other_info
);
146 switch (c
->ctr_level
) {
148 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
149 object_count
= s
->schema_part
.object_count
;
150 first_object
= s
->schema_part
.first_object
;
151 linked_attributes_count
= 0;
152 linked_attributes
= NULL
;
153 s_dsa
->highwatermark
= c
->ctr1
->new_highwatermark
;
154 s_dsa
->source_dsa_obj_guid
= c
->ctr1
->source_dsa_guid
;
155 s_dsa
->source_dsa_invocation_id
= c
->ctr1
->source_dsa_invocation_id
;
156 uptodateness_vector
= NULL
; /* TODO: map it */
159 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
160 object_count
= s
->schema_part
.object_count
;
161 first_object
= s
->schema_part
.first_object
;
162 linked_attributes_count
= 0; /* TODO: ! */
163 linked_attributes
= NULL
; /* TODO: ! */;
164 s_dsa
->highwatermark
= c
->ctr6
->new_highwatermark
;
165 s_dsa
->source_dsa_obj_guid
= c
->ctr6
->source_dsa_guid
;
166 s_dsa
->source_dsa_invocation_id
= c
->ctr6
->source_dsa_invocation_id
;
167 uptodateness_vector
= c
->ctr6
->uptodateness_vector
;
170 return NT_STATUS_INVALID_PARAMETER
;
173 s_dsa
->replica_flags
= DRSUAPI_DRS_WRIT_REP
174 | DRSUAPI_DRS_INIT_SYNC
175 | DRSUAPI_DRS_PER_SYNC
;
176 memset(s_dsa
->schedule
, 0x11, sizeof(s_dsa
->schedule
));
178 tmp_dns_name
= GUID_string(s_dsa
->other_info
, &s_dsa
->source_dsa_obj_guid
);
179 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
180 tmp_dns_name
= talloc_asprintf_append_buffer(tmp_dns_name
, "._msdcs.%s", c
->forest
->dns_name
);
181 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
182 s_dsa
->other_info
->dns_name
= tmp_dns_name
;
184 for (cur
= first_object
; cur
; cur
= cur
->next_object
) {
185 bool is_attr
= false;
186 bool is_class
= false;
188 for (i
=0; i
< cur
->object
.attribute_ctr
.num_attributes
; i
++) {
189 struct drsuapi_DsReplicaAttribute
*a
;
191 const char *oid
= NULL
;
193 a
= &cur
->object
.attribute_ctr
.attributes
[i
];
194 status
= dsdb_schema_pfm_oid_from_attid(s
->self_made_schema
->prefixmap
,
196 if (!W_ERROR_IS_OK(status
)) {
197 return werror_to_ntstatus(status
);
201 case DRSUAPI_ATTRIBUTE_objectClass
:
202 for (j
=0; j
< a
->value_ctr
.num_values
; j
++) {
203 uint32_t val
= 0xFFFFFFFF;
205 if (a
->value_ctr
.values
[i
].blob
206 && a
->value_ctr
.values
[i
].blob
->length
== 4) {
207 val
= IVAL(a
->value_ctr
.values
[i
].blob
->data
,0);
210 if (val
== DRSUAPI_OBJECTCLASS_attributeSchema
) {
213 if (val
== DRSUAPI_OBJECTCLASS_classSchema
) {
225 struct dsdb_attribute
*sa
;
227 sa
= talloc_zero(s
->self_made_schema
, struct dsdb_attribute
);
228 NT_STATUS_HAVE_NO_MEMORY(sa
);
230 status
= dsdb_attribute_from_drsuapi(s
->ldb
, s
->self_made_schema
, &cur
->object
, s
, sa
);
231 if (!W_ERROR_IS_OK(status
)) {
232 return werror_to_ntstatus(status
);
235 DLIST_ADD_END(s
->self_made_schema
->attributes
, sa
, struct dsdb_attribute
*);
239 struct dsdb_class
*sc
;
241 sc
= talloc_zero(s
->self_made_schema
, struct dsdb_class
);
242 NT_STATUS_HAVE_NO_MEMORY(sc
);
244 status
= dsdb_class_from_drsuapi(s
->ldb
, s
->self_made_schema
, &cur
->object
, s
, sc
);
245 if (!W_ERROR_IS_OK(status
)) {
246 return werror_to_ntstatus(status
);
249 DLIST_ADD_END(s
->self_made_schema
->classes
, sc
, struct dsdb_class
*);
253 /* attach the schema to the ldb */
254 ret
= dsdb_set_schema(s
->ldb
, s
->self_made_schema
);
255 if (ret
!= LDB_SUCCESS
) {
256 return NT_STATUS_FOOBAR
;
258 /* we don't want to access the self made schema anymore */
259 s
->self_made_schema
= NULL
;
260 s
->schema
= dsdb_get_schema(s
->ldb
);
262 status
= dsdb_extended_replicated_objects_convert(s
->ldb
,
267 linked_attributes_count
,
273 if (!W_ERROR_IS_OK(status
)) {
274 DEBUG(0,("Failed to convert objects: %s\n", win_errstr(status
)));
275 return werror_to_ntstatus(status
);
278 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
279 for (i
=0; i
< objs
->num_objects
; i
++) {
280 struct ldb_ldif ldif
;
281 fprintf(stdout
, "#\n");
282 ldif
.changetype
= LDB_CHANGETYPE_NONE
;
283 ldif
.msg
= objs
->objects
[i
].msg
;
284 ldb_ldif_write_file(s
->ldb
, stdout
, &ldif
);
285 NDR_PRINT_DEBUG(replPropertyMetaDataBlob
, objs
->objects
[i
].meta_data
);
289 status
= dsdb_extended_replicated_objects_commit(s
->ldb
,
291 if (!W_ERROR_IS_OK(status
)) {
292 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status
)));
293 return werror_to_ntstatus(status
);
296 msg
= ldb_msg_new(objs
);
297 NT_STATUS_HAVE_NO_MEMORY(msg
);
298 msg
->dn
= objs
->partition_dn
;
300 status
= dsdb_get_oid_mappings_ldb(s
->schema
, msg
, &prefixMap_val
, &schemaInfo_val
);
301 if (!W_ERROR_IS_OK(status
)) {
302 DEBUG(0,("Failed dsdb_get_oid_mappings_ldb(%s)\n", win_errstr(status
)));
303 return werror_to_ntstatus(status
);
306 /* we only add prefixMap here, because schemaInfo is a replicated attribute and already applied */
307 ret
= ldb_msg_add_value(msg
, "prefixMap", &prefixMap_val
, &prefixMap_el
);
308 if (ret
!= LDB_SUCCESS
) {
309 return NT_STATUS_FOOBAR
;
311 prefixMap_el
->flags
= LDB_FLAG_MOD_REPLACE
;
313 ret
= ldb_modify(s
->ldb
, msg
);
314 if (ret
!= LDB_SUCCESS
) {
315 DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret
)));
316 return NT_STATUS_FOOBAR
;
323 talloc_free(s
->ldb
); /* this also free's the s->schema, because dsdb_set_schema() steals it */
326 sam_ldb_path
= talloc_asprintf(s
, "%s/%s", s
->targetdir
, "private/sam.ldb");
327 DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema: %s\n", sam_ldb_path
));
328 s
->ldb
= ldb_wrap_connect(s
, s
->tctx
->ev
, s
->tctx
->lp_ctx
, sam_ldb_path
,
329 system_session(s
->tctx
->lp_ctx
),
332 DEBUG(0,("Failed to open '%s'\n",
334 return NT_STATUS_INTERNAL_DB_ERROR
;
337 ok
= samdb_set_ntds_invocation_id(s
->ldb
, &c
->dest_dsa
->invocation_id
);
339 DEBUG(0,("Failed to set cached ntds invocationId\n"));
340 return NT_STATUS_FOOBAR
;
342 ok
= samdb_set_ntds_objectGUID(s
->ldb
, &c
->dest_dsa
->ntds_guid
);
344 DEBUG(0,("Failed to set cached ntds objectGUID\n"));
345 return NT_STATUS_FOOBAR
;
348 s
->schema
= dsdb_get_schema(s
->ldb
);
350 DEBUG(0,("Failed to get loaded dsdb_schema\n"));
351 return NT_STATUS_FOOBAR
;
357 static NTSTATUS
test_become_dc_schema_chunk(void *private_data
,
358 const struct libnet_BecomeDC_StoreChunk
*c
)
360 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
362 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
363 uint32_t nc_object_count
;
364 uint32_t object_count
;
365 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
366 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
367 uint32_t nc_linked_attributes_count
;
368 uint32_t linked_attributes_count
;
370 switch (c
->ctr_level
) {
372 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
373 nc_object_count
= c
->ctr1
->extended_ret
; /* maybe w2k send this unexpected? */
374 object_count
= c
->ctr1
->object_count
;
375 first_object
= c
->ctr1
->first_object
;
376 nc_linked_attributes_count
= 0;
377 linked_attributes_count
= 0;
380 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
381 nc_object_count
= c
->ctr6
->nc_object_count
;
382 object_count
= c
->ctr6
->object_count
;
383 first_object
= c
->ctr6
->first_object
;
384 nc_linked_attributes_count
= c
->ctr6
->nc_linked_attributes_count
;
385 linked_attributes_count
= c
->ctr6
->linked_attributes_count
;
388 return NT_STATUS_INVALID_PARAMETER
;
391 if (nc_object_count
) {
392 DEBUG(0,("Schema-DN[%s] objects[%u/%u] linked_values[%u/%u]\n",
393 c
->partition
->nc
.dn
, object_count
, nc_object_count
,
394 linked_attributes_count
, nc_linked_attributes_count
));
396 DEBUG(0,("Schema-DN[%s] objects[%u] linked_values[%u\n",
397 c
->partition
->nc
.dn
, object_count
, linked_attributes_count
));
401 s
->self_made_schema
= dsdb_new_schema(s
, lp_iconv_convenience(s
->lp_ctx
));
403 NT_STATUS_HAVE_NO_MEMORY(s
->self_made_schema
);
405 status
= dsdb_load_prefixmap_from_drsuapi(s
->self_made_schema
, mapping_ctr
);
406 if (!W_ERROR_IS_OK(status
)) {
407 return werror_to_ntstatus(status
);
410 s
->schema
= s
->self_made_schema
;
412 status
= dsdb_schema_pfm_contains_drsuapi_pfm(s
->schema
->prefixmap
, mapping_ctr
);
413 if (!W_ERROR_IS_OK(status
)) {
414 return werror_to_ntstatus(status
);
418 if (!s
->schema_part
.first_object
) {
419 s
->schema_part
.object_count
= object_count
;
420 s
->schema_part
.first_object
= talloc_steal(s
, first_object
);
422 s
->schema_part
.object_count
+= object_count
;
423 s
->schema_part
.last_object
->next_object
= talloc_steal(s
->schema_part
.last_object
,
426 for (cur
= first_object
; cur
->next_object
; cur
= cur
->next_object
) {}
427 s
->schema_part
.last_object
= cur
;
429 if (!c
->partition
->more_data
) {
430 return test_apply_schema(s
, c
);
436 static NTSTATUS
test_become_dc_store_chunk(void *private_data
,
437 const struct libnet_BecomeDC_StoreChunk
*c
)
439 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
441 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
442 uint32_t nc_object_count
;
443 uint32_t object_count
;
444 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
445 uint32_t nc_linked_attributes_count
;
446 uint32_t linked_attributes_count
;
447 struct drsuapi_DsReplicaLinkedAttribute
*linked_attributes
;
448 const struct drsuapi_DsReplicaCursor2CtrEx
*uptodateness_vector
;
449 struct dsdb_extended_replicated_objects
*objs
;
450 struct repsFromTo1
*s_dsa
;
455 s_dsa
= talloc_zero(s
, struct repsFromTo1
);
456 NT_STATUS_HAVE_NO_MEMORY(s_dsa
);
457 s_dsa
->other_info
= talloc(s_dsa
, struct repsFromTo1OtherInfo
);
458 NT_STATUS_HAVE_NO_MEMORY(s_dsa
->other_info
);
460 switch (c
->ctr_level
) {
462 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
463 nc_object_count
= c
->ctr1
->extended_ret
; /* maybe w2k send this unexpected? */
464 object_count
= c
->ctr1
->object_count
;
465 first_object
= c
->ctr1
->first_object
;
466 nc_linked_attributes_count
= 0;
467 linked_attributes_count
= 0;
468 linked_attributes
= NULL
;
469 s_dsa
->highwatermark
= c
->ctr1
->new_highwatermark
;
470 s_dsa
->source_dsa_obj_guid
= c
->ctr1
->source_dsa_guid
;
471 s_dsa
->source_dsa_invocation_id
= c
->ctr1
->source_dsa_invocation_id
;
472 uptodateness_vector
= NULL
; /* TODO: map it */
475 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
476 nc_object_count
= c
->ctr6
->nc_object_count
;
477 object_count
= c
->ctr6
->object_count
;
478 first_object
= c
->ctr6
->first_object
;
479 nc_linked_attributes_count
= c
->ctr6
->nc_linked_attributes_count
;
480 linked_attributes_count
= c
->ctr6
->linked_attributes_count
;
481 linked_attributes
= c
->ctr6
->linked_attributes
;
482 s_dsa
->highwatermark
= c
->ctr6
->new_highwatermark
;
483 s_dsa
->source_dsa_obj_guid
= c
->ctr6
->source_dsa_guid
;
484 s_dsa
->source_dsa_invocation_id
= c
->ctr6
->source_dsa_invocation_id
;
485 uptodateness_vector
= c
->ctr6
->uptodateness_vector
;
488 return NT_STATUS_INVALID_PARAMETER
;
491 s_dsa
->replica_flags
= DRSUAPI_DRS_WRIT_REP
492 | DRSUAPI_DRS_INIT_SYNC
493 | DRSUAPI_DRS_PER_SYNC
;
494 memset(s_dsa
->schedule
, 0x11, sizeof(s_dsa
->schedule
));
496 tmp_dns_name
= GUID_string(s_dsa
->other_info
, &s_dsa
->source_dsa_obj_guid
);
497 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
498 tmp_dns_name
= talloc_asprintf_append_buffer(tmp_dns_name
, "._msdcs.%s", c
->forest
->dns_name
);
499 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
500 s_dsa
->other_info
->dns_name
= tmp_dns_name
;
502 if (nc_object_count
) {
503 DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n",
504 c
->partition
->nc
.dn
, object_count
, nc_object_count
,
505 linked_attributes_count
, nc_linked_attributes_count
));
507 DEBUG(0,("Partition[%s] objects[%u] linked_values[%u\n",
508 c
->partition
->nc
.dn
, object_count
, linked_attributes_count
));
511 status
= dsdb_extended_replicated_objects_convert(s
->ldb
,
516 linked_attributes_count
,
522 if (!W_ERROR_IS_OK(status
)) {
523 DEBUG(0,("Failed to convert objects: %s\n", win_errstr(status
)));
524 return werror_to_ntstatus(status
);
527 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
528 for (i
=0; i
< objs
->num_objects
; i
++) {
529 struct ldb_ldif ldif
;
530 fprintf(stdout
, "#\n");
531 ldif
.changetype
= LDB_CHANGETYPE_NONE
;
532 ldif
.msg
= objs
->objects
[i
].msg
;
533 ldb_ldif_write_file(s
->ldb
, stdout
, &ldif
);
534 NDR_PRINT_DEBUG(replPropertyMetaDataBlob
, objs
->objects
[i
].meta_data
);
537 status
= dsdb_extended_replicated_objects_commit(s
->ldb
, objs
, &seq_num
);
540 if (!W_ERROR_IS_OK(status
)) {
541 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status
)));
542 return werror_to_ntstatus(status
);
545 for (i
=0; i
< linked_attributes_count
; i
++) {
546 const struct dsdb_attribute
*sa
;
548 if (!linked_attributes
[i
].identifier
) {
549 return NT_STATUS_FOOBAR
;
552 if (!linked_attributes
[i
].value
.blob
) {
553 return NT_STATUS_FOOBAR
;
556 sa
= dsdb_attribute_by_attributeID_id(s
->schema
,
557 linked_attributes
[i
].attid
);
559 return NT_STATUS_FOOBAR
;
562 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
563 DEBUG(0,("# %s\n", sa
->lDAPDisplayName
));
564 NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute
, &linked_attributes
[i
]);
566 linked_attributes
[i
].value
.blob
->data
,
567 linked_attributes
[i
].value
.blob
->length
);
574 bool torture_net_become_dc(struct torture_context
*torture
)
578 struct libnet_BecomeDC b
;
579 struct libnet_UnbecomeDC u
;
580 struct test_become_dc_state
*s
;
581 struct ldb_message
*msg
;
586 struct nbt_name name
;
588 char *location
= NULL
;
589 torture_assert_ntstatus_ok(torture
, torture_temp_dir(torture
, "libnet_BecomeDC", &location
),
590 "torture_temp_dir should return NT_STATUS_OK" );
592 s
= talloc_zero(torture
, struct test_become_dc_state
);
593 if (!s
) return false;
596 s
->lp_ctx
= torture
->lp_ctx
;
598 make_nbt_name_server(&name
, torture_setting_string(torture
, "host", NULL
));
600 /* do an initial name resolution to find its IP */
601 status
= resolve_name(lp_resolve_context(torture
->lp_ctx
),
602 &name
, torture
, &address
, torture
->ev
);
603 if (!NT_STATUS_IS_OK(status
)) {
604 printf("Failed to resolve %s - %s\n",
605 name
.name
, nt_errstr(status
));
609 s
->netbios_name
= lp_parm_string(torture
->lp_ctx
, NULL
, "become dc", "smbtorture dc");
610 if (!s
->netbios_name
|| !s
->netbios_name
[0]) {
611 s
->netbios_name
= "smbtorturedc";
614 s
->targetdir
= location
;
616 /* Join domain as a member server. */
617 s
->tj
= torture_join_domain(torture
, s
->netbios_name
,
619 &s
->machine_account
);
621 DEBUG(0, ("%s failed to join domain as workstation\n",
626 s
->ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
627 s
->ctx
->cred
= cmdline_credentials
;
629 s
->ldb
= ldb_init(s
, torture
->ev
);
632 b
.in
.domain_dns_name
= torture_join_dom_dns_name(s
->tj
);
633 b
.in
.domain_netbios_name
= torture_join_dom_netbios_name(s
->tj
);
634 b
.in
.domain_sid
= torture_join_sid(s
->tj
);
635 b
.in
.source_dsa_address
= address
;
636 b
.in
.dest_dsa_netbios_name
= s
->netbios_name
;
638 b
.in
.callbacks
.private_data
= s
;
639 b
.in
.callbacks
.check_options
= test_become_dc_check_options
;
640 b
.in
.callbacks
.prepare_db
= test_become_dc_prepare_db
;
641 b
.in
.callbacks
.schema_chunk
= test_become_dc_schema_chunk
;
642 b
.in
.callbacks
.config_chunk
= test_become_dc_store_chunk
;
643 b
.in
.callbacks
.domain_chunk
= test_become_dc_store_chunk
;
645 status
= libnet_BecomeDC(s
->ctx
, s
, &b
);
646 if (!NT_STATUS_IS_OK(status
)) {
647 printf("libnet_BecomeDC() failed - %s %s\n", nt_errstr(status
), b
.out
.error_string
);
652 msg
= ldb_msg_new(s
);
654 printf("ldb_msg_new() failed\n");
658 msg
->dn
= ldb_dn_new(msg
, s
->ldb
, "@ROOTDSE");
660 printf("ldb_msg_new(@ROOTDSE) failed\n");
665 ldb_ret
= ldb_msg_add_string(msg
, "isSynchronized", "TRUE");
666 if (ldb_ret
!= LDB_SUCCESS
) {
667 printf("ldb_msg_add_string(msg, isSynchronized, TRUE) failed: %d\n", ldb_ret
);
672 for (i
=0; i
< msg
->num_elements
; i
++) {
673 msg
->elements
[i
].flags
= LDB_FLAG_MOD_REPLACE
;
676 printf("mark ROOTDSE with isSynchronized=TRUE\n");
677 ldb_ret
= ldb_modify(s
->ldb
, msg
);
678 if (ldb_ret
!= LDB_SUCCESS
) {
679 printf("ldb_modify() failed: %d\n", ldb_ret
);
685 talloc_free(s
->ldb
); /* this also free's the s->schema, because dsdb_set_schema() steals it */
688 sam_ldb_path
= talloc_asprintf(s
, "%s/%s", s
->targetdir
, "private/sam.ldb");
689 DEBUG(0,("Reopen the SAM LDB with system credentials and all replicated data: %s\n", sam_ldb_path
));
690 s
->ldb
= ldb_wrap_connect(s
, s
->tctx
->ev
, s
->lp_ctx
, sam_ldb_path
,
691 system_session(s
->lp_ctx
),
694 DEBUG(0,("Failed to open '%s'\n",
700 s
->schema
= dsdb_get_schema(s
->ldb
);
702 DEBUG(0,("Failed to get loaded dsdb_schema\n"));
707 /* Make sure we get this from the command line */
708 if (lp_parm_bool(torture
->lp_ctx
, NULL
, "become dc", "do not unjoin", false)) {
715 u
.in
.domain_dns_name
= torture_join_dom_dns_name(s
->tj
);
716 u
.in
.domain_netbios_name
= torture_join_dom_netbios_name(s
->tj
);
717 u
.in
.source_dsa_address
= address
;
718 u
.in
.dest_dsa_netbios_name
= s
->netbios_name
;
720 status
= libnet_UnbecomeDC(s
->ctx
, s
, &u
);
721 if (!NT_STATUS_IS_OK(status
)) {
722 printf("libnet_UnbecomeDC() failed - %s %s\n", nt_errstr(status
), u
.out
.error_string
);
727 torture_leave_domain(torture
, s
->tj
);