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"
36 struct test_become_dc_state
{
37 struct libnet_context
*ctx
;
38 struct torture_context
*tctx
;
39 const char *netbios_name
;
41 struct cli_credentials
*machine_account
;
42 struct dsdb_schema
*self_made_schema
;
43 const struct dsdb_schema
*schema
;
45 struct ldb_context
*ldb
;
48 uint32_t object_count
;
49 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
50 struct drsuapi_DsReplicaObjectListItemEx
*last_object
;
53 const char *targetdir
;
55 struct loadparm_context
*lp_ctx
;
58 static NTSTATUS
test_become_dc_prepare_db(void *private_data
,
59 const struct libnet_BecomeDC_PrepareDB
*p
)
61 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
62 struct provision_settings settings
;
63 struct provision_result result
;
66 settings
.site_name
= p
->dest_dsa
->site_name
;
67 settings
.root_dn_str
= p
->forest
->root_dn_str
;
68 settings
.domain_dn_str
= p
->domain
->dn_str
;
69 settings
.config_dn_str
= p
->forest
->config_dn_str
;
70 settings
.schema_dn_str
= p
->forest
->schema_dn_str
;
71 settings
.server_dn_str
= torture_join_server_dn_str(s
->tj
);
72 settings
.invocation_id
= &p
->dest_dsa
->invocation_id
;
73 settings
.netbios_name
= p
->dest_dsa
->netbios_name
;
74 settings
.host_ip
= NULL
;
75 settings
.realm
= torture_join_dom_dns_name(s
->tj
);
76 settings
.domain
= torture_join_dom_netbios_name(s
->tj
);
77 settings
.ntds_dn_str
= p
->dest_dsa
->ntds_dn_str
;
78 settings
.machine_password
= cli_credentials_get_password(s
->machine_account
);
79 settings
.targetdir
= s
->targetdir
;
81 status
= provision_bare(s
, s
->lp_ctx
, &settings
, &result
);
83 s
->ldb
= result
.samdb
;
84 s
->lp_ctx
= result
.lp_ctx
;
90 static NTSTATUS
test_become_dc_check_options(void *private_data
,
91 const struct libnet_BecomeDC_CheckOptions
*o
)
93 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
95 DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n",
97 o
->domain
->netbios_name
, o
->domain
->dns_name
));
99 DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n",
100 o
->source_dsa
->dns_name
, o
->source_dsa
->site_name
));
102 DEBUG(0,("Options:crossRef behavior_version[%u]\n"
103 "\tschema object_version[%u]\n"
104 "\tdomain behavior_version[%u]\n"
105 "\tdomain w2k3_update_revision[%u]\n",
106 o
->forest
->crossref_behavior_version
,
107 o
->forest
->schema_object_version
,
108 o
->domain
->behavior_version
,
109 o
->domain
->w2k3_update_revision
));
114 static NTSTATUS
test_apply_schema(struct test_become_dc_state
*s
,
115 const struct libnet_BecomeDC_StoreChunk
*c
)
118 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
119 uint32_t object_count
;
120 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
121 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
122 uint32_t linked_attributes_count
;
123 struct drsuapi_DsReplicaLinkedAttribute
*linked_attributes
;
124 const struct drsuapi_DsReplicaCursor2CtrEx
*uptodateness_vector
;
125 struct dsdb_extended_replicated_objects
*objs
;
126 struct repsFromTo1
*s_dsa
;
128 struct ldb_message
*msg
;
129 struct ldb_val prefixMap_val
;
130 struct ldb_message_element
*prefixMap_el
;
131 struct ldb_val schemaInfo_val
;
138 DEBUG(0,("Analyze and apply schema objects\n"));
140 s_dsa
= talloc_zero(s
, struct repsFromTo1
);
141 NT_STATUS_HAVE_NO_MEMORY(s_dsa
);
142 s_dsa
->other_info
= talloc(s_dsa
, struct repsFromTo1OtherInfo
);
143 NT_STATUS_HAVE_NO_MEMORY(s_dsa
->other_info
);
145 switch (c
->ctr_level
) {
147 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
148 object_count
= s
->schema_part
.object_count
;
149 first_object
= s
->schema_part
.first_object
;
150 linked_attributes_count
= 0;
151 linked_attributes
= NULL
;
152 s_dsa
->highwatermark
= c
->ctr1
->new_highwatermark
;
153 s_dsa
->source_dsa_obj_guid
= c
->ctr1
->source_dsa_guid
;
154 s_dsa
->source_dsa_invocation_id
= c
->ctr1
->source_dsa_invocation_id
;
155 uptodateness_vector
= NULL
; /* TODO: map it */
158 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
159 object_count
= s
->schema_part
.object_count
;
160 first_object
= s
->schema_part
.first_object
;
161 linked_attributes_count
= 0; /* TODO: ! */
162 linked_attributes
= NULL
; /* TODO: ! */;
163 s_dsa
->highwatermark
= c
->ctr6
->new_highwatermark
;
164 s_dsa
->source_dsa_obj_guid
= c
->ctr6
->source_dsa_guid
;
165 s_dsa
->source_dsa_invocation_id
= c
->ctr6
->source_dsa_invocation_id
;
166 uptodateness_vector
= c
->ctr6
->uptodateness_vector
;
169 return NT_STATUS_INVALID_PARAMETER
;
172 s_dsa
->replica_flags
= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
173 | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
174 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
;
175 memset(s_dsa
->schedule
, 0x11, sizeof(s_dsa
->schedule
));
177 tmp_dns_name
= GUID_string(s_dsa
->other_info
, &s_dsa
->source_dsa_obj_guid
);
178 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
179 tmp_dns_name
= talloc_asprintf_append_buffer(tmp_dns_name
, "._msdcs.%s", c
->forest
->dns_name
);
180 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
181 s_dsa
->other_info
->dns_name
= tmp_dns_name
;
183 for (cur
= first_object
; cur
; cur
= cur
->next_object
) {
184 bool is_attr
= false;
185 bool is_class
= false;
187 for (i
=0; i
< cur
->object
.attribute_ctr
.num_attributes
; i
++) {
188 struct drsuapi_DsReplicaAttribute
*a
;
190 const char *oid
= NULL
;
192 a
= &cur
->object
.attribute_ctr
.attributes
[i
];
193 status
= dsdb_schema_pfm_oid_from_attid(s
->self_made_schema
->prefixmap
,
195 if (!W_ERROR_IS_OK(status
)) {
196 return werror_to_ntstatus(status
);
200 case DRSUAPI_ATTRIBUTE_objectClass
:
201 for (j
=0; j
< a
->value_ctr
.num_values
; j
++) {
202 uint32_t val
= 0xFFFFFFFF;
204 if (a
->value_ctr
.values
[i
].blob
205 && a
->value_ctr
.values
[i
].blob
->length
== 4) {
206 val
= IVAL(a
->value_ctr
.values
[i
].blob
->data
,0);
209 if (val
== DRSUAPI_OBJECTCLASS_attributeSchema
) {
212 if (val
== DRSUAPI_OBJECTCLASS_classSchema
) {
224 struct dsdb_attribute
*sa
;
226 sa
= talloc_zero(s
->self_made_schema
, struct dsdb_attribute
);
227 NT_STATUS_HAVE_NO_MEMORY(sa
);
229 status
= dsdb_attribute_from_drsuapi(s
->ldb
, s
->self_made_schema
, &cur
->object
, s
, sa
);
230 if (!W_ERROR_IS_OK(status
)) {
231 return werror_to_ntstatus(status
);
234 DLIST_ADD_END(s
->self_made_schema
->attributes
, sa
, struct dsdb_attribute
*);
238 struct dsdb_class
*sc
;
240 sc
= talloc_zero(s
->self_made_schema
, struct dsdb_class
);
241 NT_STATUS_HAVE_NO_MEMORY(sc
);
243 status
= dsdb_class_from_drsuapi(s
->self_made_schema
, &cur
->object
, s
, sc
);
244 if (!W_ERROR_IS_OK(status
)) {
245 return werror_to_ntstatus(status
);
248 DLIST_ADD_END(s
->self_made_schema
->classes
, sc
, struct dsdb_class
*);
252 /* attach the schema to the ldb */
253 ret
= dsdb_set_schema(s
->ldb
, s
->self_made_schema
);
254 if (ret
!= LDB_SUCCESS
) {
255 return NT_STATUS_FOOBAR
;
257 /* we don't want to access the self made schema anymore */
258 s
->self_made_schema
= NULL
;
259 s
->schema
= dsdb_get_schema(s
->ldb
);
261 status
= dsdb_extended_replicated_objects_commit(s
->ldb
,
266 linked_attributes_count
,
272 if (!W_ERROR_IS_OK(status
)) {
273 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status
)));
274 return werror_to_ntstatus(status
);
277 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
278 for (i
=0; i
< objs
->num_objects
; i
++) {
279 struct ldb_ldif ldif
;
280 fprintf(stdout
, "#\n");
281 ldif
.changetype
= LDB_CHANGETYPE_NONE
;
282 ldif
.msg
= objs
->objects
[i
].msg
;
283 ldb_ldif_write_file(s
->ldb
, stdout
, &ldif
);
284 NDR_PRINT_DEBUG(replPropertyMetaDataBlob
, objs
->objects
[i
].meta_data
);
288 msg
= ldb_msg_new(objs
);
289 NT_STATUS_HAVE_NO_MEMORY(msg
);
290 msg
->dn
= objs
->partition_dn
;
292 status
= dsdb_get_oid_mappings_ldb(s
->schema
, msg
, &prefixMap_val
, &schemaInfo_val
);
293 if (!W_ERROR_IS_OK(status
)) {
294 DEBUG(0,("Failed dsdb_get_oid_mappings_ldb(%s)\n", win_errstr(status
)));
295 return werror_to_ntstatus(status
);
298 /* we only add prefixMap here, because schemaInfo is a replicated attribute and already applied */
299 ret
= ldb_msg_add_value(msg
, "prefixMap", &prefixMap_val
, &prefixMap_el
);
300 if (ret
!= LDB_SUCCESS
) {
301 return NT_STATUS_FOOBAR
;
303 prefixMap_el
->flags
= LDB_FLAG_MOD_REPLACE
;
305 ret
= ldb_modify(s
->ldb
, msg
);
306 if (ret
!= LDB_SUCCESS
) {
307 DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret
)));
308 return NT_STATUS_FOOBAR
;
315 talloc_free(s
->ldb
); /* this also free's the s->schema, because dsdb_set_schema() steals it */
318 sam_ldb_path
= talloc_asprintf(s
, "%s/%s", s
->targetdir
, "private/sam.ldb");
319 DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema: %s\n", sam_ldb_path
));
320 s
->ldb
= ldb_wrap_connect(s
, s
->tctx
->ev
, s
->tctx
->lp_ctx
, sam_ldb_path
,
321 system_session(s
->tctx
->lp_ctx
),
324 DEBUG(0,("Failed to open '%s'\n",
326 return NT_STATUS_INTERNAL_DB_ERROR
;
329 ok
= samdb_set_ntds_invocation_id(s
->ldb
, &c
->dest_dsa
->invocation_id
);
331 DEBUG(0,("Failed to set cached ntds invocationId\n"));
332 return NT_STATUS_FOOBAR
;
334 ok
= samdb_set_ntds_objectGUID(s
->ldb
, &c
->dest_dsa
->ntds_guid
);
336 DEBUG(0,("Failed to set cached ntds objectGUID\n"));
337 return NT_STATUS_FOOBAR
;
340 s
->schema
= dsdb_get_schema(s
->ldb
);
342 DEBUG(0,("Failed to get loaded dsdb_schema\n"));
343 return NT_STATUS_FOOBAR
;
349 static NTSTATUS
test_become_dc_schema_chunk(void *private_data
,
350 const struct libnet_BecomeDC_StoreChunk
*c
)
352 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
354 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
355 uint32_t nc_object_count
;
356 uint32_t object_count
;
357 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
358 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
359 uint32_t nc_linked_attributes_count
;
360 uint32_t linked_attributes_count
;
362 switch (c
->ctr_level
) {
364 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
365 nc_object_count
= c
->ctr1
->extended_ret
; /* maybe w2k send this unexpected? */
366 object_count
= c
->ctr1
->object_count
;
367 first_object
= c
->ctr1
->first_object
;
368 nc_linked_attributes_count
= 0;
369 linked_attributes_count
= 0;
372 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
373 nc_object_count
= c
->ctr6
->nc_object_count
;
374 object_count
= c
->ctr6
->object_count
;
375 first_object
= c
->ctr6
->first_object
;
376 nc_linked_attributes_count
= c
->ctr6
->nc_linked_attributes_count
;
377 linked_attributes_count
= c
->ctr6
->linked_attributes_count
;
380 return NT_STATUS_INVALID_PARAMETER
;
383 if (nc_object_count
) {
384 DEBUG(0,("Schema-DN[%s] objects[%u/%u] linked_values[%u/%u]\n",
385 c
->partition
->nc
.dn
, object_count
, nc_object_count
,
386 linked_attributes_count
, nc_linked_attributes_count
));
388 DEBUG(0,("Schema-DN[%s] objects[%u] linked_values[%u\n",
389 c
->partition
->nc
.dn
, object_count
, linked_attributes_count
));
393 s
->self_made_schema
= dsdb_new_schema(s
, lp_iconv_convenience(s
->lp_ctx
));
395 NT_STATUS_HAVE_NO_MEMORY(s
->self_made_schema
);
397 status
= dsdb_load_prefixmap_from_drsuapi(s
->self_made_schema
, mapping_ctr
);
398 if (!W_ERROR_IS_OK(status
)) {
399 return werror_to_ntstatus(status
);
402 s
->schema
= s
->self_made_schema
;
404 status
= dsdb_schema_pfm_contains_drsuapi_pfm(s
->schema
->prefixmap
, mapping_ctr
);
405 if (!W_ERROR_IS_OK(status
)) {
406 return werror_to_ntstatus(status
);
410 if (!s
->schema_part
.first_object
) {
411 s
->schema_part
.object_count
= object_count
;
412 s
->schema_part
.first_object
= talloc_steal(s
, first_object
);
414 s
->schema_part
.object_count
+= object_count
;
415 s
->schema_part
.last_object
->next_object
= talloc_steal(s
->schema_part
.last_object
,
418 for (cur
= first_object
; cur
->next_object
; cur
= cur
->next_object
) {}
419 s
->schema_part
.last_object
= cur
;
421 if (!c
->partition
->more_data
) {
422 return test_apply_schema(s
, c
);
428 static NTSTATUS
test_become_dc_store_chunk(void *private_data
,
429 const struct libnet_BecomeDC_StoreChunk
*c
)
431 struct test_become_dc_state
*s
= talloc_get_type(private_data
, struct test_become_dc_state
);
433 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
434 uint32_t nc_object_count
;
435 uint32_t object_count
;
436 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
437 uint32_t nc_linked_attributes_count
;
438 uint32_t linked_attributes_count
;
439 struct drsuapi_DsReplicaLinkedAttribute
*linked_attributes
;
440 const struct drsuapi_DsReplicaCursor2CtrEx
*uptodateness_vector
;
441 struct dsdb_extended_replicated_objects
*objs
;
442 struct repsFromTo1
*s_dsa
;
447 s_dsa
= talloc_zero(s
, struct repsFromTo1
);
448 NT_STATUS_HAVE_NO_MEMORY(s_dsa
);
449 s_dsa
->other_info
= talloc(s_dsa
, struct repsFromTo1OtherInfo
);
450 NT_STATUS_HAVE_NO_MEMORY(s_dsa
->other_info
);
452 switch (c
->ctr_level
) {
454 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
455 nc_object_count
= c
->ctr1
->extended_ret
; /* maybe w2k send this unexpected? */
456 object_count
= c
->ctr1
->object_count
;
457 first_object
= c
->ctr1
->first_object
;
458 nc_linked_attributes_count
= 0;
459 linked_attributes_count
= 0;
460 linked_attributes
= NULL
;
461 s_dsa
->highwatermark
= c
->ctr1
->new_highwatermark
;
462 s_dsa
->source_dsa_obj_guid
= c
->ctr1
->source_dsa_guid
;
463 s_dsa
->source_dsa_invocation_id
= c
->ctr1
->source_dsa_invocation_id
;
464 uptodateness_vector
= NULL
; /* TODO: map it */
467 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
468 nc_object_count
= c
->ctr6
->nc_object_count
;
469 object_count
= c
->ctr6
->object_count
;
470 first_object
= c
->ctr6
->first_object
;
471 nc_linked_attributes_count
= c
->ctr6
->nc_linked_attributes_count
;
472 linked_attributes_count
= c
->ctr6
->linked_attributes_count
;
473 linked_attributes
= c
->ctr6
->linked_attributes
;
474 s_dsa
->highwatermark
= c
->ctr6
->new_highwatermark
;
475 s_dsa
->source_dsa_obj_guid
= c
->ctr6
->source_dsa_guid
;
476 s_dsa
->source_dsa_invocation_id
= c
->ctr6
->source_dsa_invocation_id
;
477 uptodateness_vector
= c
->ctr6
->uptodateness_vector
;
480 return NT_STATUS_INVALID_PARAMETER
;
483 s_dsa
->replica_flags
= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
484 | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
485 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
;
486 memset(s_dsa
->schedule
, 0x11, sizeof(s_dsa
->schedule
));
488 tmp_dns_name
= GUID_string(s_dsa
->other_info
, &s_dsa
->source_dsa_obj_guid
);
489 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
490 tmp_dns_name
= talloc_asprintf_append_buffer(tmp_dns_name
, "._msdcs.%s", c
->forest
->dns_name
);
491 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
492 s_dsa
->other_info
->dns_name
= tmp_dns_name
;
494 if (nc_object_count
) {
495 DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n",
496 c
->partition
->nc
.dn
, object_count
, nc_object_count
,
497 linked_attributes_count
, nc_linked_attributes_count
));
499 DEBUG(0,("Partition[%s] objects[%u] linked_values[%u\n",
500 c
->partition
->nc
.dn
, object_count
, linked_attributes_count
));
503 status
= dsdb_extended_replicated_objects_commit(s
->ldb
,
508 linked_attributes_count
,
514 if (!W_ERROR_IS_OK(status
)) {
515 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status
)));
516 return werror_to_ntstatus(status
);
519 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
520 for (i
=0; i
< objs
->num_objects
; i
++) {
521 struct ldb_ldif ldif
;
522 fprintf(stdout
, "#\n");
523 ldif
.changetype
= LDB_CHANGETYPE_NONE
;
524 ldif
.msg
= objs
->objects
[i
].msg
;
525 ldb_ldif_write_file(s
->ldb
, stdout
, &ldif
);
526 NDR_PRINT_DEBUG(replPropertyMetaDataBlob
, objs
->objects
[i
].meta_data
);
532 for (i
=0; i
< linked_attributes_count
; i
++) {
533 const struct dsdb_attribute
*sa
;
535 if (!linked_attributes
[i
].identifier
) {
536 return NT_STATUS_FOOBAR
;
539 if (!linked_attributes
[i
].value
.blob
) {
540 return NT_STATUS_FOOBAR
;
543 sa
= dsdb_attribute_by_attributeID_id(s
->schema
,
544 linked_attributes
[i
].attid
);
546 return NT_STATUS_FOOBAR
;
549 if (lp_parm_bool(s
->tctx
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
550 DEBUG(0,("# %s\n", sa
->lDAPDisplayName
));
551 NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute
, &linked_attributes
[i
]);
553 linked_attributes
[i
].value
.blob
->data
,
554 linked_attributes
[i
].value
.blob
->length
);
561 bool torture_net_become_dc(struct torture_context
*torture
)
565 struct libnet_BecomeDC b
;
566 struct libnet_UnbecomeDC u
;
567 struct test_become_dc_state
*s
;
568 struct ldb_message
*msg
;
573 char *location
= NULL
;
574 torture_assert_ntstatus_ok(torture
, torture_temp_dir(torture
, "libnet_BecomeDC", &location
),
575 "torture_temp_dir should return NT_STATUS_OK" );
577 s
= talloc_zero(torture
, struct test_become_dc_state
);
578 if (!s
) return false;
581 s
->lp_ctx
= torture
->lp_ctx
;
583 s
->netbios_name
= lp_parm_string(torture
->lp_ctx
, NULL
, "become dc", "smbtorture dc");
584 if (!s
->netbios_name
|| !s
->netbios_name
[0]) {
585 s
->netbios_name
= "smbtorturedc";
588 s
->targetdir
= location
;
590 /* Join domain as a member server. */
591 s
->tj
= torture_join_domain(torture
, s
->netbios_name
,
593 &s
->machine_account
);
595 DEBUG(0, ("%s failed to join domain as workstation\n",
600 s
->ctx
= libnet_context_init(torture
->ev
, torture
->lp_ctx
);
601 s
->ctx
->cred
= cmdline_credentials
;
603 s
->ldb
= ldb_init(s
, torture
->ev
);
606 b
.in
.domain_dns_name
= torture_join_dom_dns_name(s
->tj
);
607 b
.in
.domain_netbios_name
= torture_join_dom_netbios_name(s
->tj
);
608 b
.in
.domain_sid
= torture_join_sid(s
->tj
);
609 b
.in
.source_dsa_address
= torture_setting_string(torture
, "host", NULL
);
610 b
.in
.dest_dsa_netbios_name
= s
->netbios_name
;
612 b
.in
.callbacks
.private_data
= s
;
613 b
.in
.callbacks
.check_options
= test_become_dc_check_options
;
614 b
.in
.callbacks
.prepare_db
= test_become_dc_prepare_db
;
615 b
.in
.callbacks
.schema_chunk
= test_become_dc_schema_chunk
;
616 b
.in
.callbacks
.config_chunk
= test_become_dc_store_chunk
;
617 b
.in
.callbacks
.domain_chunk
= test_become_dc_store_chunk
;
619 status
= libnet_BecomeDC(s
->ctx
, s
, &b
);
620 if (!NT_STATUS_IS_OK(status
)) {
621 printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status
));
626 msg
= ldb_msg_new(s
);
628 printf("ldb_msg_new() failed\n");
632 msg
->dn
= ldb_dn_new(msg
, s
->ldb
, "@ROOTDSE");
634 printf("ldb_msg_new(@ROOTDSE) failed\n");
639 ldb_ret
= ldb_msg_add_string(msg
, "isSynchronized", "TRUE");
640 if (ldb_ret
!= LDB_SUCCESS
) {
641 printf("ldb_msg_add_string(msg, isSynchronized, TRUE) failed: %d\n", ldb_ret
);
646 for (i
=0; i
< msg
->num_elements
; i
++) {
647 msg
->elements
[i
].flags
= LDB_FLAG_MOD_REPLACE
;
650 printf("mark ROOTDSE with isSynchronized=TRUE\n");
651 ldb_ret
= ldb_modify(s
->ldb
, msg
);
652 if (ldb_ret
!= LDB_SUCCESS
) {
653 printf("ldb_modify() failed: %d\n", ldb_ret
);
659 talloc_free(s
->ldb
); /* this also free's the s->schema, because dsdb_set_schema() steals it */
662 sam_ldb_path
= talloc_asprintf(s
, "%s/%s", s
->targetdir
, "private/sam.ldb");
663 DEBUG(0,("Reopen the SAM LDB with system credentials and all replicated data: %s\n", sam_ldb_path
));
664 s
->ldb
= ldb_wrap_connect(s
, s
->tctx
->ev
, s
->lp_ctx
, sam_ldb_path
,
665 system_session(s
->lp_ctx
),
668 DEBUG(0,("Failed to open '%s'\n",
674 s
->schema
= dsdb_get_schema(s
->ldb
);
676 DEBUG(0,("Failed to get loaded dsdb_schema\n"));
681 /* Make sure we get this from the command line */
682 if (lp_parm_bool(torture
->lp_ctx
, NULL
, "become dc", "do not unjoin", false)) {
689 u
.in
.domain_dns_name
= torture_join_dom_dns_name(s
->tj
);
690 u
.in
.domain_netbios_name
= torture_join_dom_netbios_name(s
->tj
);
691 u
.in
.source_dsa_address
= torture_setting_string(torture
, "host", NULL
);
692 u
.in
.dest_dsa_netbios_name
= s
->netbios_name
;
694 status
= libnet_UnbecomeDC(s
->ctx
, s
, &u
);
695 if (!NT_STATUS_IS_OK(status
)) {
696 printf("libnet_UnbecomeDC() failed - %s\n", nt_errstr(status
));
701 torture_leave_domain(torture
, s
->tj
);