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/torture.h"
25 #include "torture/rpc/rpc.h"
26 #include "libnet/libnet.h"
27 #include "lib/events/events.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "../lib/util/dlinklist.h"
30 #include "lib/ldb/include/ldb.h"
31 #include "lib/ldb/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"
37 #include "lib/ldb_wrap.h"
38 #include "auth/auth.h"
39 #include "param/param.h"
40 #include "torture/util.h"
41 #include "param/provision.h"
43 struct test_become_dc_state
{
44 struct libnet_context
*ctx
;
45 struct torture_context
*tctx
;
46 const char *netbios_name
;
48 struct cli_credentials
*machine_account
;
49 struct dsdb_schema
*self_made_schema
;
50 const struct dsdb_schema
*schema
;
52 struct ldb_context
*ldb
;
55 uint32_t object_count
;
56 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
57 struct drsuapi_DsReplicaObjectListItemEx
*last_object
;
60 const char *targetdir
;
62 struct loadparm_context
*lp_ctx
;
65 static NTSTATUS
test_become_dc_prepare_db(void *private_data
,
66 const struct libnet_BecomeDC_PrepareDB
*p
)
68 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
69 struct provision_settings settings
;
70 struct provision_result result
;
73 settings
.site_name
= p
->dest_dsa
->site_name
;
74 settings
.root_dn_str
= p
->forest
->root_dn_str
;
75 settings
.domain_dn_str
= p
->domain
->dn_str
;
76 settings
.config_dn_str
= p
->forest
->config_dn_str
;
77 settings
.schema_dn_str
= p
->forest
->schema_dn_str
;
78 settings
.server_dn_str
= torture_join_server_dn_str(s
->tj
);
79 settings
.invocation_id
= &p
->dest_dsa
->invocation_id
;
80 settings
.netbios_name
= p
->dest_dsa
->netbios_name
;
81 settings
.host_ip
= NULL
;
82 settings
.realm
= torture_join_dom_dns_name(s
->tj
);
83 settings
.domain
= torture_join_dom_netbios_name(s
->tj
);
84 settings
.ntds_dn_str
= p
->dest_dsa
->ntds_dn_str
;
85 settings
.machine_password
= cli_credentials_get_password(s
->machine_account
);
86 settings
.targetdir
= s
->targetdir
;
88 status
= provision_bare(s
, s
->lp_ctx
, &settings
, &result
);
90 s
->ldb
= result
.samdb
;
91 s
->lp_ctx
= result
.lp_ctx
;
97 static NTSTATUS
test_become_dc_check_options(void *private_data
,
98 const struct libnet_BecomeDC_CheckOptions
*o
)
100 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
102 DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n",
104 o
->domain
->netbios_name
, o
->domain
->dns_name
));
106 DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n",
107 o
->source_dsa
->dns_name
, o
->source_dsa
->site_name
));
109 DEBUG(0,("Options:crossRef behavior_version[%u]\n"
110 "\tschema object_version[%u]\n"
111 "\tdomain behavior_version[%u]\n"
112 "\tdomain w2k3_update_revision[%u]\n",
113 o
->forest
->crossref_behavior_version
,
114 o
->forest
->schema_object_version
,
115 o
->domain
->behavior_version
,
116 o
->domain
->w2k3_update_revision
));
121 static NTSTATUS
test_apply_schema(struct test_become_dc_state
*s
,
122 const struct libnet_BecomeDC_StoreChunk
*c
)
125 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
126 uint32_t object_count
;
127 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
128 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
129 uint32_t linked_attributes_count
;
130 struct drsuapi_DsReplicaLinkedAttribute
*linked_attributes
;
131 const struct drsuapi_DsReplicaCursor2CtrEx
*uptodateness_vector
;
132 struct dsdb_extended_replicated_objects
*objs
;
133 struct repsFromTo1
*s_dsa
;
135 struct ldb_message
*msg
;
136 struct ldb_val prefixMap_val
;
137 struct ldb_message_element
*prefixMap_el
;
138 struct ldb_val schemaInfo_val
;
145 DEBUG(0,("Analyze and apply schema objects\n"));
147 s_dsa
= talloc_zero(s
, struct repsFromTo1
);
148 NT_STATUS_HAVE_NO_MEMORY(s_dsa
);
149 s_dsa
->other_info
= talloc(s_dsa
, struct repsFromTo1OtherInfo
);
150 NT_STATUS_HAVE_NO_MEMORY(s_dsa
->other_info
);
152 switch (c
->ctr_level
) {
154 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
155 object_count
= s
->schema_part
.object_count
;
156 first_object
= s
->schema_part
.first_object
;
157 linked_attributes_count
= 0;
158 linked_attributes
= NULL
;
159 s_dsa
->highwatermark
= c
->ctr1
->new_highwatermark
;
160 s_dsa
->source_dsa_obj_guid
= c
->ctr1
->source_dsa_guid
;
161 s_dsa
->source_dsa_invocation_id
= c
->ctr1
->source_dsa_invocation_id
;
162 uptodateness_vector
= NULL
; /* TODO: map it */
165 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
166 object_count
= s
->schema_part
.object_count
;
167 first_object
= s
->schema_part
.first_object
;
168 linked_attributes_count
= 0; /* TODO: ! */
169 linked_attributes
= NULL
; /* TODO: ! */;
170 s_dsa
->highwatermark
= c
->ctr6
->new_highwatermark
;
171 s_dsa
->source_dsa_obj_guid
= c
->ctr6
->source_dsa_guid
;
172 s_dsa
->source_dsa_invocation_id
= c
->ctr6
->source_dsa_invocation_id
;
173 uptodateness_vector
= c
->ctr6
->uptodateness_vector
;
176 return NT_STATUS_INVALID_PARAMETER
;
179 s_dsa
->replica_flags
= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
180 | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
181 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
;
182 memset(s_dsa
->schedule
, 0x11, sizeof(s_dsa
->schedule
));
184 tmp_dns_name
= GUID_string(s_dsa
->other_info
, &s_dsa
->source_dsa_obj_guid
);
185 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
186 tmp_dns_name
= talloc_asprintf_append_buffer(tmp_dns_name
, "._msdcs.%s", c
->forest
->dns_name
);
187 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
188 s_dsa
->other_info
->dns_name
= tmp_dns_name
;
190 for (cur
= first_object
; cur
; cur
= cur
->next_object
) {
191 bool is_attr
= false;
192 bool is_class
= false;
194 for (i
=0; i
< cur
->object
.attribute_ctr
.num_attributes
; i
++) {
195 struct drsuapi_DsReplicaAttribute
*a
;
197 const char *oid
= NULL
;
199 a
= &cur
->object
.attribute_ctr
.attributes
[i
];
200 status
= dsdb_map_int2oid(s
->self_made_schema
, a
->attid
, s
, &oid
);
201 if (!W_ERROR_IS_OK(status
)) {
202 return werror_to_ntstatus(status
);
206 case DRSUAPI_ATTRIBUTE_objectClass
:
207 for (j
=0; j
< a
->value_ctr
.num_values
; j
++) {
208 uint32_t val
= 0xFFFFFFFF;
210 if (a
->value_ctr
.values
[i
].blob
211 && a
->value_ctr
.values
[i
].blob
->length
== 4) {
212 val
= IVAL(a
->value_ctr
.values
[i
].blob
->data
,0);
215 if (val
== DRSUAPI_OBJECTCLASS_attributeSchema
) {
218 if (val
== DRSUAPI_OBJECTCLASS_classSchema
) {
230 struct dsdb_attribute
*sa
;
232 sa
= talloc_zero(s
->self_made_schema
, struct dsdb_attribute
);
233 NT_STATUS_HAVE_NO_MEMORY(sa
);
235 status
= dsdb_attribute_from_drsuapi(s
->ldb
, s
->self_made_schema
, &cur
->object
, s
, sa
);
236 if (!W_ERROR_IS_OK(status
)) {
237 return werror_to_ntstatus(status
);
240 DLIST_ADD_END(s
->self_made_schema
->attributes
, sa
, struct dsdb_attribute
*);
244 struct dsdb_class
*sc
;
246 sc
= talloc_zero(s
->self_made_schema
, struct dsdb_class
);
247 NT_STATUS_HAVE_NO_MEMORY(sc
);
249 status
= dsdb_class_from_drsuapi(s
->self_made_schema
, &cur
->object
, s
, sc
);
250 if (!W_ERROR_IS_OK(status
)) {
251 return werror_to_ntstatus(status
);
254 DLIST_ADD_END(s
->self_made_schema
->classes
, sc
, struct dsdb_class
*);
258 /* attach the schema to the ldb */
259 ret
= dsdb_set_schema(s
->ldb
, s
->self_made_schema
);
260 if (ret
!= LDB_SUCCESS
) {
261 return NT_STATUS_FOOBAR
;
263 /* we don't want to access the self made schema anymore */
264 s
->self_made_schema
= NULL
;
265 s
->schema
= dsdb_get_schema(s
->ldb
);
267 status
= dsdb_extended_replicated_objects_commit(s
->ldb
,
272 linked_attributes_count
,
278 if (!W_ERROR_IS_OK(status
)) {
279 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status
)));
280 return werror_to_ntstatus(status
);
283 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
284 for (i
=0; i
< objs
->num_objects
; i
++) {
285 struct ldb_ldif ldif
;
286 fprintf(stdout
, "#\n");
287 ldif
.changetype
= LDB_CHANGETYPE_NONE
;
288 ldif
.msg
= objs
->objects
[i
].msg
;
289 ldb_ldif_write_file(s
->ldb
, stdout
, &ldif
);
290 NDR_PRINT_DEBUG(replPropertyMetaDataBlob
, objs
->objects
[i
].meta_data
);
294 msg
= ldb_msg_new(objs
);
295 NT_STATUS_HAVE_NO_MEMORY(msg
);
296 msg
->dn
= objs
->partition_dn
;
298 status
= dsdb_get_oid_mappings_ldb(s
->schema
, msg
, &prefixMap_val
, &schemaInfo_val
);
299 if (!W_ERROR_IS_OK(status
)) {
300 DEBUG(0,("Failed dsdb_get_oid_mappings_ldb(%s)\n", win_errstr(status
)));
301 return werror_to_ntstatus(status
);
304 /* we only add prefixMap here, because schemaInfo is a replicated attribute and already applied */
305 ret
= ldb_msg_add_value(msg
, "prefixMap", &prefixMap_val
, &prefixMap_el
);
306 if (ret
!= LDB_SUCCESS
) {
307 return NT_STATUS_FOOBAR
;
309 prefixMap_el
->flags
= LDB_FLAG_MOD_REPLACE
;
311 ret
= ldb_modify(s
->ldb
, msg
);
312 if (ret
!= LDB_SUCCESS
) {
313 DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret
)));
314 return NT_STATUS_FOOBAR
;
321 talloc_free(s
->ldb
); /* this also free's the s->schema, because dsdb_set_schema() steals it */
324 sam_ldb_path
= talloc_asprintf(s
, "%s/%s", s
->targetdir
, "private/sam.ldb");
325 DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema: %s\n", sam_ldb_path
));
326 s
->ldb
= ldb_wrap_connect(s
, s
->tctx
->ev
, s
->tctx
->lp_ctx
, sam_ldb_path
,
327 system_session(s
, s
->tctx
->lp_ctx
),
330 DEBUG(0,("Failed to open '%s'\n",
332 return NT_STATUS_INTERNAL_DB_ERROR
;
335 ok
= samdb_set_ntds_invocation_id(s
->ldb
, &c
->dest_dsa
->invocation_id
);
337 DEBUG(0,("Failed to set cached ntds invocationId\n"));
338 return NT_STATUS_FOOBAR
;
340 ok
= samdb_set_ntds_objectGUID(s
->ldb
, &c
->dest_dsa
->ntds_guid
);
342 DEBUG(0,("Failed to set cached ntds objectGUID\n"));
343 return NT_STATUS_FOOBAR
;
346 s
->schema
= dsdb_get_schema(s
->ldb
);
348 DEBUG(0,("Failed to get loaded dsdb_schema\n"));
349 return NT_STATUS_FOOBAR
;
355 static NTSTATUS
test_become_dc_schema_chunk(void *private_data
,
356 const struct libnet_BecomeDC_StoreChunk
*c
)
358 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
360 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
361 uint32_t nc_object_count
;
362 uint32_t object_count
;
363 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
364 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
365 uint32_t nc_linked_attributes_count
;
366 uint32_t linked_attributes_count
;
368 switch (c
->ctr_level
) {
370 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
371 nc_object_count
= c
->ctr1
->extended_ret
; /* maybe w2k send this unexpected? */
372 object_count
= c
->ctr1
->object_count
;
373 first_object
= c
->ctr1
->first_object
;
374 nc_linked_attributes_count
= 0;
375 linked_attributes_count
= 0;
378 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
379 nc_object_count
= c
->ctr6
->nc_object_count
;
380 object_count
= c
->ctr6
->object_count
;
381 first_object
= c
->ctr6
->first_object
;
382 nc_linked_attributes_count
= c
->ctr6
->nc_linked_attributes_count
;
383 linked_attributes_count
= c
->ctr6
->linked_attributes_count
;
386 return NT_STATUS_INVALID_PARAMETER
;
389 if (nc_object_count
) {
390 DEBUG(0,("Schema-DN[%s] objects[%u/%u] linked_values[%u/%u]\n",
391 c
->partition
->nc
.dn
, object_count
, nc_object_count
,
392 linked_attributes_count
, nc_linked_attributes_count
));
394 DEBUG(0,("Schema-DN[%s] objects[%u] linked_values[%u\n",
395 c
->partition
->nc
.dn
, object_count
, linked_attributes_count
));
399 s
->self_made_schema
= dsdb_new_schema(s
, lp_iconv_convenience(s
->lp_ctx
));
401 NT_STATUS_HAVE_NO_MEMORY(s
->self_made_schema
);
403 status
= dsdb_load_oid_mappings_drsuapi(s
->self_made_schema
, mapping_ctr
);
404 if (!W_ERROR_IS_OK(status
)) {
405 return werror_to_ntstatus(status
);
408 s
->schema
= s
->self_made_schema
;
410 status
= dsdb_verify_oid_mappings_drsuapi(s
->schema
, mapping_ctr
);
411 if (!W_ERROR_IS_OK(status
)) {
412 return werror_to_ntstatus(status
);
416 if (!s
->schema_part
.first_object
) {
417 s
->schema_part
.object_count
= object_count
;
418 s
->schema_part
.first_object
= talloc_steal(s
, first_object
);
420 s
->schema_part
.object_count
+= object_count
;
421 s
->schema_part
.last_object
->next_object
= talloc_steal(s
->schema_part
.last_object
,
424 for (cur
= first_object
; cur
->next_object
; cur
= cur
->next_object
) {}
425 s
->schema_part
.last_object
= cur
;
427 if (!c
->partition
->more_data
) {
428 return test_apply_schema(s
, c
);
434 static NTSTATUS
test_become_dc_store_chunk(void *private_data
,
435 const struct libnet_BecomeDC_StoreChunk
*c
)
437 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
439 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
440 uint32_t nc_object_count
;
441 uint32_t object_count
;
442 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
443 uint32_t nc_linked_attributes_count
;
444 uint32_t linked_attributes_count
;
445 struct drsuapi_DsReplicaLinkedAttribute
*linked_attributes
;
446 const struct drsuapi_DsReplicaCursor2CtrEx
*uptodateness_vector
;
447 struct dsdb_extended_replicated_objects
*objs
;
448 struct repsFromTo1
*s_dsa
;
453 s_dsa
= talloc_zero(s
, struct repsFromTo1
);
454 NT_STATUS_HAVE_NO_MEMORY(s_dsa
);
455 s_dsa
->other_info
= talloc(s_dsa
, struct repsFromTo1OtherInfo
);
456 NT_STATUS_HAVE_NO_MEMORY(s_dsa
->other_info
);
458 switch (c
->ctr_level
) {
460 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
461 nc_object_count
= c
->ctr1
->extended_ret
; /* maybe w2k send this unexpected? */
462 object_count
= c
->ctr1
->object_count
;
463 first_object
= c
->ctr1
->first_object
;
464 nc_linked_attributes_count
= 0;
465 linked_attributes_count
= 0;
466 linked_attributes
= NULL
;
467 s_dsa
->highwatermark
= c
->ctr1
->new_highwatermark
;
468 s_dsa
->source_dsa_obj_guid
= c
->ctr1
->source_dsa_guid
;
469 s_dsa
->source_dsa_invocation_id
= c
->ctr1
->source_dsa_invocation_id
;
470 uptodateness_vector
= NULL
; /* TODO: map it */
473 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
474 nc_object_count
= c
->ctr6
->nc_object_count
;
475 object_count
= c
->ctr6
->object_count
;
476 first_object
= c
->ctr6
->first_object
;
477 nc_linked_attributes_count
= c
->ctr6
->nc_linked_attributes_count
;
478 linked_attributes_count
= c
->ctr6
->linked_attributes_count
;
479 linked_attributes
= c
->ctr6
->linked_attributes
;
480 s_dsa
->highwatermark
= c
->ctr6
->new_highwatermark
;
481 s_dsa
->source_dsa_obj_guid
= c
->ctr6
->source_dsa_guid
;
482 s_dsa
->source_dsa_invocation_id
= c
->ctr6
->source_dsa_invocation_id
;
483 uptodateness_vector
= c
->ctr6
->uptodateness_vector
;
486 return NT_STATUS_INVALID_PARAMETER
;
489 s_dsa
->replica_flags
= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
490 | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
491 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
;
492 memset(s_dsa
->schedule
, 0x11, sizeof(s_dsa
->schedule
));
494 tmp_dns_name
= GUID_string(s_dsa
->other_info
, &s_dsa
->source_dsa_obj_guid
);
495 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
496 tmp_dns_name
= talloc_asprintf_append_buffer(tmp_dns_name
, "._msdcs.%s", c
->forest
->dns_name
);
497 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
498 s_dsa
->other_info
->dns_name
= tmp_dns_name
;
500 if (nc_object_count
) {
501 DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n",
502 c
->partition
->nc
.dn
, object_count
, nc_object_count
,
503 linked_attributes_count
, nc_linked_attributes_count
));
505 DEBUG(0,("Partition[%s] objects[%u] linked_values[%u\n",
506 c
->partition
->nc
.dn
, object_count
, linked_attributes_count
));
509 status
= dsdb_extended_replicated_objects_commit(s
->ldb
,
514 linked_attributes_count
,
520 if (!W_ERROR_IS_OK(status
)) {
521 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status
)));
522 return werror_to_ntstatus(status
);
525 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
526 for (i
=0; i
< objs
->num_objects
; i
++) {
527 struct ldb_ldif ldif
;
528 fprintf(stdout
, "#\n");
529 ldif
.changetype
= LDB_CHANGETYPE_NONE
;
530 ldif
.msg
= objs
->objects
[i
].msg
;
531 ldb_ldif_write_file(s
->ldb
, stdout
, &ldif
);
532 NDR_PRINT_DEBUG(replPropertyMetaDataBlob
, objs
->objects
[i
].meta_data
);
538 for (i
=0; i
< linked_attributes_count
; i
++) {
539 const struct dsdb_attribute
*sa
;
541 if (!linked_attributes
[i
].identifier
) {
542 return NT_STATUS_FOOBAR
;
545 if (!linked_attributes
[i
].value
.blob
) {
546 return NT_STATUS_FOOBAR
;
549 sa
= dsdb_attribute_by_attributeID_id(s
->schema
,
550 linked_attributes
[i
].attid
);
552 return NT_STATUS_FOOBAR
;
555 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
556 DEBUG(0,("# %s\n", sa
->lDAPDisplayName
));
557 NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute
, &linked_attributes
[i
]);
559 linked_attributes
[i
].value
.blob
->data
,
560 linked_attributes
[i
].value
.blob
->length
);
567 bool torture_net_become_dc(struct torture_context
*torture
)
571 struct libnet_BecomeDC b
;
572 struct libnet_UnbecomeDC u
;
573 struct test_become_dc_state
*s
;
574 struct ldb_message
*msg
;
579 char *location
= NULL
;
580 torture_assert_ntstatus_ok(torture
, torture_temp_dir(torture
, "libnet_BecomeDC", &location
),
581 "torture_temp_dir should return NT_STATUS_OK" );
583 s
= talloc_zero(torture
, struct test_become_dc_state
);
584 if (!s
) return false;
587 s
->lp_ctx
= torture
->lp_ctx
;
589 s
->netbios_name
= lp_parm_string(torture
->lp_ctx
, NULL
, "become dc", "smbtorture dc");
590 if (!s
->netbios_name
|| !s
->netbios_name
[0]) {
591 s
->netbios_name
= "smbtorturedc";
594 s
->targetdir
= location
;
596 /* Join domain as a member server. */
597 s
->tj
= torture_join_domain(torture
, s
->netbios_name
,
599 &s
->machine_account
);
601 DEBUG(0, ("%s failed to join domain as workstation\n",
606 s
->ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
607 s
->ctx
->cred
= cmdline_credentials
;
609 s
->ldb
= ldb_init(s
, torture
->ev
);
612 b
.in
.domain_dns_name
= torture_join_dom_dns_name(s
->tj
);
613 b
.in
.domain_netbios_name
= torture_join_dom_netbios_name(s
->tj
);
614 b
.in
.domain_sid
= torture_join_sid(s
->tj
);
615 b
.in
.source_dsa_address
= torture_setting_string(torture
, "host", NULL
);
616 b
.in
.dest_dsa_netbios_name
= s
->netbios_name
;
618 b
.in
.callbacks
.private_data
= s
;
619 b
.in
.callbacks
.check_options
= test_become_dc_check_options
;
620 b
.in
.callbacks
.prepare_db
= test_become_dc_prepare_db
;
621 b
.in
.callbacks
.schema_chunk
= test_become_dc_schema_chunk
;
622 b
.in
.callbacks
.config_chunk
= test_become_dc_store_chunk
;
623 b
.in
.callbacks
.domain_chunk
= test_become_dc_store_chunk
;
625 status
= libnet_BecomeDC(s
->ctx
, s
, &b
);
626 if (!NT_STATUS_IS_OK(status
)) {
627 printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status
));
632 msg
= ldb_msg_new(s
);
634 printf("ldb_msg_new() failed\n");
638 msg
->dn
= ldb_dn_new(msg
, s
->ldb
, "@ROOTDSE");
640 printf("ldb_msg_new(@ROOTDSE) failed\n");
645 ldb_ret
= ldb_msg_add_string(msg
, "isSynchronized", "TRUE");
646 if (ldb_ret
!= LDB_SUCCESS
) {
647 printf("ldb_msg_add_string(msg, isSynchronized, TRUE) failed: %d\n", ldb_ret
);
652 for (i
=0; i
< msg
->num_elements
; i
++) {
653 msg
->elements
[i
].flags
= LDB_FLAG_MOD_REPLACE
;
656 printf("mark ROOTDSE with isSynchronized=TRUE\n");
657 ldb_ret
= ldb_modify(s
->ldb
, msg
);
658 if (ldb_ret
!= LDB_SUCCESS
) {
659 printf("ldb_modify() failed: %d\n", ldb_ret
);
665 talloc_free(s
->ldb
); /* this also free's the s->schema, because dsdb_set_schema() steals it */
668 sam_ldb_path
= talloc_asprintf(s
, "%s/%s", s
->targetdir
, "private/sam.ldb");
669 DEBUG(0,("Reopen the SAM LDB with system credentials and all replicated data: %s\n", sam_ldb_path
));
670 s
->ldb
= ldb_wrap_connect(s
, s
->tctx
->ev
, s
->lp_ctx
, sam_ldb_path
,
671 system_session(s
, s
->lp_ctx
),
674 DEBUG(0,("Failed to open '%s'\n",
680 s
->schema
= dsdb_get_schema(s
->ldb
);
682 DEBUG(0,("Failed to get loaded dsdb_schema\n"));
687 /* Make sure we get this from the command line */
688 if (lp_parm_bool(torture
->lp_ctx
, NULL
, "become dc", "do not unjoin", false)) {
695 u
.in
.domain_dns_name
= torture_join_dom_dns_name(s
->tj
);
696 u
.in
.domain_netbios_name
= torture_join_dom_netbios_name(s
->tj
);
697 u
.in
.source_dsa_address
= torture_setting_string(torture
, "host", NULL
);
698 u
.in
.dest_dsa_netbios_name
= s
->netbios_name
;
700 status
= libnet_UnbecomeDC(s
->ctx
, s
, &u
);
701 if (!NT_STATUS_IS_OK(status
)) {
702 printf("libnet_UnbecomeDC() failed - %s\n", nt_errstr(status
));
707 torture_leave_domain(torture
, s
->tj
);