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"
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 "param/provision.h"
43 List of tasks vampire.py must perform:
45 - but don't write the secrets.ldb
46 - results for this should be enough to handle the provision
47 - if vampire method is samsync
48 - Provision using these results
49 - do we still want to support this NT4 technology?
50 - Start samsync with libnet code
51 - provision in the callback
52 - Write out the secrets database, using the code from libnet_Join
55 struct vampire_state
{
56 const char *netbios_name
;
57 struct libnet_JoinDomain
*join
;
58 struct cli_credentials
*machine_account
;
59 struct dsdb_schema
*self_made_schema
;
60 const struct dsdb_schema
*schema
;
62 struct ldb_context
*ldb
;
65 uint32_t object_count
;
66 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
67 struct drsuapi_DsReplicaObjectListItemEx
*last_object
;
70 const char *targetdir
;
72 struct loadparm_context
*lp_ctx
;
73 struct tevent_context
*event_ctx
;
76 static NTSTATUS
vampire_prepare_db(void *private_data
,
77 const struct libnet_BecomeDC_PrepareDB
*p
)
79 struct vampire_state
*s
= talloc_get_type(private_data
, struct vampire_state
);
80 struct provision_settings settings
;
81 struct provision_result result
;
84 settings
.site_name
= p
->dest_dsa
->site_name
;
85 settings
.root_dn_str
= p
->forest
->root_dn_str
;
86 settings
.domain_dn_str
= p
->domain
->dn_str
;
87 settings
.config_dn_str
= p
->forest
->config_dn_str
;
88 settings
.schema_dn_str
= p
->forest
->schema_dn_str
;
89 settings
.netbios_name
= p
->dest_dsa
->netbios_name
;
90 settings
.realm
= s
->join
->out
.realm
;
91 settings
.domain
= s
->join
->out
.domain_name
;
92 settings
.server_dn_str
= p
->dest_dsa
->server_dn_str
;
93 settings
.machine_password
= generate_random_str(s
, 16);
94 settings
.targetdir
= s
->targetdir
;
96 status
= provision_bare(s
, s
->lp_ctx
, &settings
, &result
);
98 if (!NT_STATUS_IS_OK(status
)) {
102 s
->ldb
= result
.samdb
;
103 s
->lp_ctx
= result
.lp_ctx
;
110 static NTSTATUS
vampire_check_options(void *private_data
,
111 const struct libnet_BecomeDC_CheckOptions
*o
)
113 struct vampire_state
*s
= talloc_get_type(private_data
, struct vampire_state
);
115 DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n",
117 o
->domain
->netbios_name
, o
->domain
->dns_name
));
119 DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n",
120 o
->source_dsa
->dns_name
, o
->source_dsa
->site_name
));
122 DEBUG(0,("Options:crossRef behavior_version[%u]\n"
123 "\tschema object_version[%u]\n"
124 "\tdomain behavior_version[%u]\n"
125 "\tdomain w2k3_update_revision[%u]\n",
126 o
->forest
->crossref_behavior_version
,
127 o
->forest
->schema_object_version
,
128 o
->domain
->behavior_version
,
129 o
->domain
->w2k3_update_revision
));
134 static NTSTATUS
vampire_apply_schema(struct vampire_state
*s
,
135 const struct libnet_BecomeDC_StoreChunk
*c
)
138 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
139 uint32_t object_count
;
140 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
141 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
142 uint32_t linked_attributes_count
;
143 struct drsuapi_DsReplicaLinkedAttribute
*linked_attributes
;
144 const struct drsuapi_DsReplicaCursor2CtrEx
*uptodateness_vector
;
145 struct dsdb_extended_replicated_objects
*objs
;
146 struct repsFromTo1
*s_dsa
;
148 struct ldb_message
*msg
;
149 struct ldb_val prefixMap_val
;
150 struct ldb_message_element
*prefixMap_el
;
151 struct ldb_val schemaInfo_val
;
156 DEBUG(0,("Analyze and apply schema objects\n"));
158 s_dsa
= talloc_zero(s
, struct repsFromTo1
);
159 NT_STATUS_HAVE_NO_MEMORY(s_dsa
);
160 s_dsa
->other_info
= talloc(s_dsa
, struct repsFromTo1OtherInfo
);
161 NT_STATUS_HAVE_NO_MEMORY(s_dsa
->other_info
);
163 switch (c
->ctr_level
) {
165 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
166 object_count
= s
->schema_part
.object_count
;
167 first_object
= s
->schema_part
.first_object
;
168 linked_attributes_count
= 0;
169 linked_attributes
= NULL
;
170 s_dsa
->highwatermark
= c
->ctr1
->new_highwatermark
;
171 s_dsa
->source_dsa_obj_guid
= c
->ctr1
->source_dsa_guid
;
172 s_dsa
->source_dsa_invocation_id
= c
->ctr1
->source_dsa_invocation_id
;
173 uptodateness_vector
= NULL
; /* TODO: map it */
176 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
177 object_count
= s
->schema_part
.object_count
;
178 first_object
= s
->schema_part
.first_object
;
179 linked_attributes_count
= 0; /* TODO: ! */
180 linked_attributes
= NULL
; /* TODO: ! */;
181 s_dsa
->highwatermark
= c
->ctr6
->new_highwatermark
;
182 s_dsa
->source_dsa_obj_guid
= c
->ctr6
->source_dsa_guid
;
183 s_dsa
->source_dsa_invocation_id
= c
->ctr6
->source_dsa_invocation_id
;
184 uptodateness_vector
= c
->ctr6
->uptodateness_vector
;
187 return NT_STATUS_INVALID_PARAMETER
;
190 s_dsa
->replica_flags
= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
191 | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
192 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
;
193 memset(s_dsa
->schedule
, 0x11, sizeof(s_dsa
->schedule
));
195 tmp_dns_name
= GUID_string(s_dsa
->other_info
, &s_dsa
->source_dsa_obj_guid
);
196 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
197 tmp_dns_name
= talloc_asprintf_append_buffer(tmp_dns_name
, "._msdcs.%s", c
->forest
->dns_name
);
198 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
199 s_dsa
->other_info
->dns_name
= tmp_dns_name
;
201 for (cur
= first_object
; cur
; cur
= cur
->next_object
) {
202 bool is_attr
= false;
203 bool is_class
= false;
205 for (i
=0; i
< cur
->object
.attribute_ctr
.num_attributes
; i
++) {
206 struct drsuapi_DsReplicaAttribute
*a
;
208 const char *oid
= NULL
;
210 a
= &cur
->object
.attribute_ctr
.attributes
[i
];
211 status
= dsdb_map_int2oid(s
->self_made_schema
, a
->attid
, s
, &oid
);
212 if (!W_ERROR_IS_OK(status
)) {
213 return werror_to_ntstatus(status
);
217 case DRSUAPI_ATTRIBUTE_objectClass
:
218 for (j
=0; j
< a
->value_ctr
.num_values
; j
++) {
219 uint32_t val
= 0xFFFFFFFF;
221 if (a
->value_ctr
.values
[i
].blob
222 && a
->value_ctr
.values
[i
].blob
->length
== 4) {
223 val
= IVAL(a
->value_ctr
.values
[i
].blob
->data
,0);
226 if (val
== DRSUAPI_OBJECTCLASS_attributeSchema
) {
229 if (val
== DRSUAPI_OBJECTCLASS_classSchema
) {
241 struct dsdb_attribute
*sa
;
243 sa
= talloc_zero(s
->self_made_schema
, struct dsdb_attribute
);
244 NT_STATUS_HAVE_NO_MEMORY(sa
);
246 status
= dsdb_attribute_from_drsuapi(s
->self_made_schema
, &cur
->object
, s
, sa
);
247 if (!W_ERROR_IS_OK(status
)) {
248 return werror_to_ntstatus(status
);
251 DLIST_ADD_END(s
->self_made_schema
->attributes
, sa
, struct dsdb_attribute
*);
255 struct dsdb_class
*sc
;
257 sc
= talloc_zero(s
->self_made_schema
, struct dsdb_class
);
258 NT_STATUS_HAVE_NO_MEMORY(sc
);
260 status
= dsdb_class_from_drsuapi(s
->self_made_schema
, &cur
->object
, s
, sc
);
261 if (!W_ERROR_IS_OK(status
)) {
262 return werror_to_ntstatus(status
);
265 DLIST_ADD_END(s
->self_made_schema
->classes
, sc
, struct dsdb_class
*);
269 /* attach the schema to the ldb */
270 ret
= dsdb_set_schema(s
->ldb
, s
->self_made_schema
);
271 if (ret
!= LDB_SUCCESS
) {
272 return NT_STATUS_FOOBAR
;
274 /* we don't want to access the self made schema anymore */
275 s
->self_made_schema
= NULL
;
276 s
->schema
= dsdb_get_schema(s
->ldb
);
278 status
= dsdb_extended_replicated_objects_commit(s
->ldb
,
283 linked_attributes_count
,
289 if (!W_ERROR_IS_OK(status
)) {
290 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status
)));
291 return werror_to_ntstatus(status
);
294 if (lp_parm_bool(s
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
295 for (i
=0; i
< objs
->num_objects
; i
++) {
296 struct ldb_ldif ldif
;
297 fprintf(stdout
, "#\n");
298 ldif
.changetype
= LDB_CHANGETYPE_NONE
;
299 ldif
.msg
= objs
->objects
[i
].msg
;
300 ldb_ldif_write_file(s
->ldb
, stdout
, &ldif
);
301 NDR_PRINT_DEBUG(replPropertyMetaDataBlob
, objs
->objects
[i
].meta_data
);
305 msg
= ldb_msg_new(objs
);
306 NT_STATUS_HAVE_NO_MEMORY(msg
);
307 msg
->dn
= objs
->partition_dn
;
309 status
= dsdb_get_oid_mappings_ldb(s
->schema
, msg
, &prefixMap_val
, &schemaInfo_val
);
310 if (!W_ERROR_IS_OK(status
)) {
311 DEBUG(0,("Failed dsdb_get_oid_mappings_ldb(%s)\n", win_errstr(status
)));
312 return werror_to_ntstatus(status
);
315 /* we only add prefixMap here, because schemaInfo is a replicated attribute and already applied */
316 ret
= ldb_msg_add_value(msg
, "prefixMap", &prefixMap_val
, &prefixMap_el
);
317 if (ret
!= LDB_SUCCESS
) {
318 return NT_STATUS_FOOBAR
;
320 prefixMap_el
->flags
= LDB_FLAG_MOD_REPLACE
;
322 ret
= ldb_modify(s
->ldb
, msg
);
323 if (ret
!= LDB_SUCCESS
) {
324 DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret
)));
325 return NT_STATUS_FOOBAR
;
332 talloc_free(s
->ldb
); /* this also free's the s->schema, because dsdb_set_schema() steals it */
335 DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema\n"));
336 s
->ldb
= samdb_connect(s
, s
->event_ctx
, s
->lp_ctx
,
337 system_session(s
, s
->lp_ctx
));
339 DEBUG(0,("Failed to reopen sam.ldb\n"));
340 return NT_STATUS_INTERNAL_DB_ERROR
;
343 /* We must set these up to ensure the replMetaData is written correctly, before our NTDS Settings entry is replicated */
344 ok
= samdb_set_ntds_invocation_id(s
->ldb
, &c
->dest_dsa
->invocation_id
);
346 DEBUG(0,("Failed to set cached ntds invocationId\n"));
347 return NT_STATUS_FOOBAR
;
349 ok
= samdb_set_ntds_objectGUID(s
->ldb
, &c
->dest_dsa
->ntds_guid
);
351 DEBUG(0,("Failed to set cached ntds objectGUID\n"));
352 return NT_STATUS_FOOBAR
;
355 s
->schema
= dsdb_get_schema(s
->ldb
);
357 DEBUG(0,("Failed to get loaded dsdb_schema\n"));
358 return NT_STATUS_FOOBAR
;
364 static NTSTATUS
vampire_schema_chunk(void *private_data
,
365 const struct libnet_BecomeDC_StoreChunk
*c
)
367 struct vampire_state
*s
= talloc_get_type(private_data
, struct vampire_state
);
369 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
370 uint32_t nc_object_count
;
371 uint32_t object_count
;
372 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
373 struct drsuapi_DsReplicaObjectListItemEx
*cur
;
374 uint32_t nc_linked_attributes_count
;
375 uint32_t linked_attributes_count
;
377 switch (c
->ctr_level
) {
379 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
380 nc_object_count
= c
->ctr1
->extended_ret
; /* maybe w2k send this unexpected? */
381 object_count
= c
->ctr1
->object_count
;
382 first_object
= c
->ctr1
->first_object
;
383 nc_linked_attributes_count
= 0;
384 linked_attributes_count
= 0;
387 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
388 nc_object_count
= c
->ctr6
->nc_object_count
;
389 object_count
= c
->ctr6
->object_count
;
390 first_object
= c
->ctr6
->first_object
;
391 nc_linked_attributes_count
= c
->ctr6
->nc_linked_attributes_count
;
392 linked_attributes_count
= c
->ctr6
->linked_attributes_count
;
395 return NT_STATUS_INVALID_PARAMETER
;
398 if (nc_object_count
) {
399 DEBUG(0,("Schema-DN[%s] objects[%u/%u] linked_values[%u/%u]\n",
400 c
->partition
->nc
.dn
, object_count
, nc_object_count
,
401 linked_attributes_count
, nc_linked_attributes_count
));
403 DEBUG(0,("Schema-DN[%s] objects[%u] linked_values[%u\n",
404 c
->partition
->nc
.dn
, object_count
, linked_attributes_count
));
408 s
->self_made_schema
= dsdb_new_schema(s
, lp_iconv_convenience(s
->lp_ctx
));
410 NT_STATUS_HAVE_NO_MEMORY(s
->self_made_schema
);
412 status
= dsdb_load_oid_mappings_drsuapi(s
->self_made_schema
, mapping_ctr
);
413 if (!W_ERROR_IS_OK(status
)) {
414 return werror_to_ntstatus(status
);
417 s
->schema
= s
->self_made_schema
;
419 status
= dsdb_verify_oid_mappings_drsuapi(s
->schema
, mapping_ctr
);
420 if (!W_ERROR_IS_OK(status
)) {
421 return werror_to_ntstatus(status
);
425 if (!s
->schema_part
.first_object
) {
426 s
->schema_part
.object_count
= object_count
;
427 s
->schema_part
.first_object
= talloc_steal(s
, first_object
);
429 s
->schema_part
.object_count
+= object_count
;
430 s
->schema_part
.last_object
->next_object
= talloc_steal(s
->schema_part
.last_object
,
433 for (cur
= first_object
; cur
->next_object
; cur
= cur
->next_object
) {}
434 s
->schema_part
.last_object
= cur
;
436 if (!c
->partition
->more_data
) {
437 return vampire_apply_schema(s
, c
);
443 static NTSTATUS
vampire_store_chunk(void *private_data
,
444 const struct libnet_BecomeDC_StoreChunk
*c
)
446 struct vampire_state
*s
= talloc_get_type(private_data
, struct vampire_state
);
448 const struct drsuapi_DsReplicaOIDMapping_Ctr
*mapping_ctr
;
449 uint32_t nc_object_count
;
450 uint32_t object_count
;
451 struct drsuapi_DsReplicaObjectListItemEx
*first_object
;
452 uint32_t nc_linked_attributes_count
;
453 uint32_t linked_attributes_count
;
454 struct drsuapi_DsReplicaLinkedAttribute
*linked_attributes
;
455 const struct drsuapi_DsReplicaCursor2CtrEx
*uptodateness_vector
;
456 struct dsdb_extended_replicated_objects
*objs
;
457 struct repsFromTo1
*s_dsa
;
461 s_dsa
= talloc_zero(s
, struct repsFromTo1
);
462 NT_STATUS_HAVE_NO_MEMORY(s_dsa
);
463 s_dsa
->other_info
= talloc(s_dsa
, struct repsFromTo1OtherInfo
);
464 NT_STATUS_HAVE_NO_MEMORY(s_dsa
->other_info
);
466 switch (c
->ctr_level
) {
468 mapping_ctr
= &c
->ctr1
->mapping_ctr
;
469 nc_object_count
= c
->ctr1
->extended_ret
; /* maybe w2k send this unexpected? */
470 object_count
= c
->ctr1
->object_count
;
471 first_object
= c
->ctr1
->first_object
;
472 nc_linked_attributes_count
= 0;
473 linked_attributes_count
= 0;
474 linked_attributes
= NULL
;
475 s_dsa
->highwatermark
= c
->ctr1
->new_highwatermark
;
476 s_dsa
->source_dsa_obj_guid
= c
->ctr1
->source_dsa_guid
;
477 s_dsa
->source_dsa_invocation_id
= c
->ctr1
->source_dsa_invocation_id
;
478 uptodateness_vector
= NULL
; /* TODO: map it */
481 mapping_ctr
= &c
->ctr6
->mapping_ctr
;
482 nc_object_count
= c
->ctr6
->nc_object_count
;
483 object_count
= c
->ctr6
->object_count
;
484 first_object
= c
->ctr6
->first_object
;
485 nc_linked_attributes_count
= c
->ctr6
->nc_linked_attributes_count
;
486 linked_attributes_count
= c
->ctr6
->linked_attributes_count
;
487 linked_attributes
= c
->ctr6
->linked_attributes
;
488 s_dsa
->highwatermark
= c
->ctr6
->new_highwatermark
;
489 s_dsa
->source_dsa_obj_guid
= c
->ctr6
->source_dsa_guid
;
490 s_dsa
->source_dsa_invocation_id
= c
->ctr6
->source_dsa_invocation_id
;
491 uptodateness_vector
= c
->ctr6
->uptodateness_vector
;
494 return NT_STATUS_INVALID_PARAMETER
;
497 s_dsa
->replica_flags
= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
498 | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
499 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
;
500 memset(s_dsa
->schedule
, 0x11, sizeof(s_dsa
->schedule
));
502 tmp_dns_name
= GUID_string(s_dsa
->other_info
, &s_dsa
->source_dsa_obj_guid
);
503 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
504 tmp_dns_name
= talloc_asprintf_append_buffer(tmp_dns_name
, "._msdcs.%s", c
->forest
->dns_name
);
505 NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name
);
506 s_dsa
->other_info
->dns_name
= tmp_dns_name
;
508 if (nc_object_count
) {
509 DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n",
510 c
->partition
->nc
.dn
, object_count
, nc_object_count
,
511 linked_attributes_count
, nc_linked_attributes_count
));
513 DEBUG(0,("Partition[%s] objects[%u] linked_values[%u\n",
514 c
->partition
->nc
.dn
, object_count
, linked_attributes_count
));
517 status
= dsdb_extended_replicated_objects_commit(s
->ldb
,
522 linked_attributes_count
,
528 if (!W_ERROR_IS_OK(status
)) {
529 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status
)));
530 return werror_to_ntstatus(status
);
533 if (lp_parm_bool(s
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
534 for (i
=0; i
< objs
->num_objects
; i
++) {
535 struct ldb_ldif ldif
;
536 fprintf(stdout
, "#\n");
537 ldif
.changetype
= LDB_CHANGETYPE_NONE
;
538 ldif
.msg
= objs
->objects
[i
].msg
;
539 ldb_ldif_write_file(s
->ldb
, stdout
, &ldif
);
540 NDR_PRINT_DEBUG(replPropertyMetaDataBlob
, objs
->objects
[i
].meta_data
);
546 for (i
=0; i
< linked_attributes_count
; i
++) {
547 const struct dsdb_attribute
*sa
;
549 if (!linked_attributes
[i
].identifier
) {
550 return NT_STATUS_FOOBAR
;
553 if (!linked_attributes
[i
].value
.blob
) {
554 return NT_STATUS_FOOBAR
;
557 sa
= dsdb_attribute_by_attributeID_id(s
->schema
,
558 linked_attributes
[i
].attid
);
560 return NT_STATUS_FOOBAR
;
563 if (lp_parm_bool(s
->lp_ctx
, NULL
, "become dc", "dump objects", false)) {
564 DEBUG(0,("# %s\n", sa
->lDAPDisplayName
));
565 NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute
, &linked_attributes
[i
]);
567 linked_attributes
[i
].value
.blob
->data
,
568 linked_attributes
[i
].value
.blob
->length
);
575 NTSTATUS
libnet_Vampire(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
,
576 struct libnet_Vampire
*r
)
578 struct libnet_JoinDomain
*join
;
579 struct libnet_set_join_secrets
*set_secrets
;
580 struct libnet_BecomeDC b
;
581 struct vampire_state
*s
;
582 struct ldb_message
*msg
;
587 const char *account_name
;
588 const char *netbios_name
;
590 r
->out
.error_string
= NULL
;
592 s
= talloc_zero(mem_ctx
, struct vampire_state
);
594 return NT_STATUS_NO_MEMORY
;
597 s
->lp_ctx
= ctx
->lp_ctx
;
598 s
->event_ctx
= ctx
->event_ctx
;
600 join
= talloc_zero(s
, struct libnet_JoinDomain
);
602 return NT_STATUS_NO_MEMORY
;
605 if (r
->in
.netbios_name
!= NULL
) {
606 netbios_name
= r
->in
.netbios_name
;
608 netbios_name
= talloc_reference(join
, lp_netbios_name(ctx
->lp_ctx
));
610 r
->out
.error_string
= NULL
;
612 return NT_STATUS_NO_MEMORY
;
616 account_name
= talloc_asprintf(join
, "%s$", netbios_name
);
618 r
->out
.error_string
= NULL
;
620 return NT_STATUS_NO_MEMORY
;
623 join
->in
.domain_name
= r
->in
.domain_name
;
624 join
->in
.account_name
= account_name
;
625 join
->in
.netbios_name
= netbios_name
;
626 join
->in
.level
= LIBNET_JOINDOMAIN_AUTOMATIC
;
627 join
->in
.acct_type
= ACB_WSTRUST
;
628 join
->in
.recreate_account
= false;
629 status
= libnet_JoinDomain(ctx
, join
, join
);
630 if (!NT_STATUS_IS_OK(status
)) {
631 r
->out
.error_string
= talloc_steal(mem_ctx
, join
->out
.error_string
);
638 s
->targetdir
= r
->in
.targetdir
;
641 b
.in
.domain_dns_name
= join
->out
.realm
;
642 b
.in
.domain_netbios_name
= join
->out
.domain_name
;
643 b
.in
.domain_sid
= join
->out
.domain_sid
;
644 b
.in
.source_dsa_address
= join
->out
.samr_binding
->host
;
645 b
.in
.dest_dsa_netbios_name
= netbios_name
;
647 b
.in
.callbacks
.private_data
= s
;
648 b
.in
.callbacks
.check_options
= vampire_check_options
;
649 b
.in
.callbacks
.prepare_db
= vampire_prepare_db
;
650 b
.in
.callbacks
.schema_chunk
= vampire_schema_chunk
;
651 b
.in
.callbacks
.config_chunk
= vampire_store_chunk
;
652 b
.in
.callbacks
.domain_chunk
= vampire_store_chunk
;
654 status
= libnet_BecomeDC(ctx
, s
, &b
);
655 if (!NT_STATUS_IS_OK(status
)) {
656 printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status
));
661 msg
= ldb_msg_new(s
);
663 printf("ldb_msg_new() failed\n");
665 return NT_STATUS_NO_MEMORY
;
667 msg
->dn
= ldb_dn_new(msg
, s
->ldb
, "@ROOTDSE");
669 printf("ldb_msg_new(@ROOTDSE) failed\n");
671 return NT_STATUS_NO_MEMORY
;
674 ldb_ret
= ldb_msg_add_string(msg
, "isSynchronized", "TRUE");
675 if (ldb_ret
!= LDB_SUCCESS
) {
676 printf("ldb_msg_add_string(msg, isSynchronized, TRUE) failed: %d\n", ldb_ret
);
678 return NT_STATUS_NO_MEMORY
;
681 for (i
=0; i
< msg
->num_elements
; i
++) {
682 msg
->elements
[i
].flags
= LDB_FLAG_MOD_REPLACE
;
685 printf("mark ROOTDSE with isSynchronized=TRUE\n");
686 ldb_ret
= ldb_modify(s
->ldb
, msg
);
687 if (ldb_ret
!= LDB_SUCCESS
) {
688 printf("ldb_modify() failed: %d\n", ldb_ret
);
690 return NT_STATUS_INTERNAL_DB_ERROR
;
693 set_secrets
= talloc_zero(s
, struct libnet_set_join_secrets
);
695 return NT_STATUS_NO_MEMORY
;
698 set_secrets
->in
.domain_name
= join
->out
.domain_name
;
699 set_secrets
->in
.realm
= join
->out
.realm
;
700 set_secrets
->in
.account_name
= account_name
;
701 set_secrets
->in
.netbios_name
= netbios_name
;
702 set_secrets
->in
.join_type
= SEC_CHAN_BDC
;
703 set_secrets
->in
.join_password
= join
->out
.join_password
;
704 set_secrets
->in
.kvno
= join
->out
.kvno
;
705 set_secrets
->in
.domain_sid
= join
->out
.domain_sid
;
707 status
= libnet_set_join_secrets(ctx
, set_secrets
, set_secrets
);
708 if (!NT_STATUS_IS_OK(status
)) {
709 r
->out
.error_string
= talloc_steal(mem_ctx
, set_secrets
->out
.error_string
);
714 r
->out
.domain_name
= talloc_steal(r
, join
->out
.domain_name
);
715 r
->out
.domain_sid
= talloc_steal(r
, join
->out
.domain_sid
);