2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2006
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libnet/libnet.h"
23 #include "libcli/composite/composite.h"
24 #include "libcli/cldap/cldap.h"
25 #include "lib/ldb/include/ldb.h"
26 #include "lib/ldb/include/ldb_errors.h"
27 #include "lib/db_wrap.h"
28 #include "dsdb/samdb/samdb.h"
30 struct libnet_BecomeDC_state {
31 struct composite_context *creq;
33 struct libnet_context *libnet;
36 struct cldap_socket *sock;
37 struct cldap_netlogon io;
38 struct nbt_cldap_netlogon_5 netlogon5;
41 struct becomeDC_ldap {
42 struct ldb_context *ldb;
43 const struct ldb_message *rootdse;
49 const char *netbios_name;
59 const char *root_dn_str;
60 const char *config_dn_str;
61 const char *schema_dn_str;
70 const char *netbios_name;
71 const char *site_name;
72 const char *server_dn_str;
73 const char *ntds_dn_str;
78 const char *netbios_name;
82 const char *site_name;
83 struct GUID site_guid;
84 const char *computer_dn_str;
85 const char *server_dn_str;
86 const char *ntds_dn_str;
87 uint32_t user_account_control;
91 uint32_t domain_behavior_version;
92 uint32_t config_behavior_version;
93 uint32_t schema_object_version;
94 uint32_t w2k3_update_revision;
97 struct becomeDC_fsmo {
99 const char *server_dn_str;
100 const char *ntds_dn_str;
101 struct GUID ntds_guid;
102 } infrastructure_fsmo;
104 struct becomeDC_fsmo rid_manager_fsmo;
107 static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s);
109 static void becomeDC_recv_cldap(struct cldap_request *req)
111 struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
112 struct libnet_BecomeDC_state);
113 struct composite_context *c = s->creq;
115 c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
116 if (!composite_is_ok(c)) return;
118 s->cldap.netlogon5 = s->cldap.io.out.netlogon.logon5;
120 s->domain.dns_name = s->cldap.netlogon5.dns_domain;
121 s->domain.netbios_name = s->cldap.netlogon5.domain;
122 s->domain.guid = s->cldap.netlogon5.domain_uuid;
124 s->forest.dns_name = s->cldap.netlogon5.forest;
126 s->source_dsa.dns_name = s->cldap.netlogon5.pdc_dns_name;
127 s->source_dsa.netbios_name = s->cldap.netlogon5.pdc_name;
128 s->source_dsa.site_name = s->cldap.netlogon5.server_site;
130 s->dest_dsa.site_name = s->cldap.netlogon5.client_site;
132 becomeDC_connect_ldap1(s);
135 static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
137 struct composite_context *c = s->creq;
138 struct cldap_request *req;
140 s->cldap.io.in.dest_address = s->source_dsa.address;
141 s->cldap.io.in.realm = s->domain.dns_name;
142 s->cldap.io.in.host = s->dest_dsa.netbios_name;
143 s->cldap.io.in.user = NULL;
144 s->cldap.io.in.domain_guid = NULL;
145 s->cldap.io.in.domain_sid = NULL;
146 s->cldap.io.in.acct_control = -1;
147 s->cldap.io.in.version = 6;
149 s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx);
150 if (composite_nomem(s->cldap.sock, c)) return;
152 req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
153 if (composite_nomem(req, c)) return;
154 req->async.fn = becomeDC_recv_cldap;
155 req->async.private = s;
158 static NTSTATUS becomeDC_ldap_connect(struct libnet_BecomeDC_state *s, struct becomeDC_ldap *ldap)
162 url = talloc_asprintf(s, "ldap://%s/", s->source_dsa.dns_name);
163 NT_STATUS_HAVE_NO_MEMORY(url);
165 ldap->ldb = ldb_wrap_connect(s, url,
170 if (ldap->ldb == NULL) {
171 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
177 static NTSTATUS becomeDC_ldap1_rootdse(struct libnet_BecomeDC_state *s)
180 struct ldb_result *r;
181 struct ldb_dn *basedn;
182 static const char *attrs[] = {
187 basedn = ldb_dn_new(s, s->ldap1.ldb, NULL);
188 NT_STATUS_HAVE_NO_MEMORY(basedn);
190 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
191 "(objectClass=*)", attrs, &r);
193 if (ret != LDB_SUCCESS) {
194 return NT_STATUS_LDAP(ret);
195 } else if (r->count != 1) {
197 return NT_STATUS_INVALID_NETWORK_RESPONSE;
201 s->ldap1.rootdse = r->msgs[0];
203 s->domain.dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "defaultNamingContext", NULL);
204 if (!s->domain.dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
206 s->forest.root_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "rootDomainNamingContext", NULL);
207 if (!s->forest.root_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
208 s->forest.config_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "configurationNamingContext", NULL);
209 if (!s->forest.config_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
210 s->forest.schema_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "schemaNamingContext", NULL);
211 if (!s->forest.schema_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
213 s->source_dsa.server_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "serverName", NULL);
214 if (!s->source_dsa.server_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
215 s->source_dsa.ntds_dn_str = ldb_msg_find_attr_as_string(s->ldap1.rootdse, "dsServiceName", NULL);
216 if (!s->source_dsa.ntds_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
221 static NTSTATUS becomeDC_ldap1_config_behavior_version(struct libnet_BecomeDC_state *s)
224 struct ldb_result *r;
225 struct ldb_dn *basedn;
226 static const char *attrs[] = {
227 "msDs-Behavior-Version",
231 basedn = ldb_dn_new(s, s->ldap1.ldb, s->forest.config_dn_str);
232 NT_STATUS_HAVE_NO_MEMORY(basedn);
234 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_ONELEVEL,
235 "(cn=Partitions)", attrs, &r);
237 if (ret != LDB_SUCCESS) {
238 return NT_STATUS_LDAP(ret);
239 } else if (r->count != 1) {
241 return NT_STATUS_INVALID_NETWORK_RESPONSE;
244 s->ads_options.config_behavior_version = ldb_msg_find_attr_as_uint(r->msgs[0], "msDs-Behavior-Version", 0);
250 static NTSTATUS becomeDC_ldap1_domain_behavior_version(struct libnet_BecomeDC_state *s)
253 struct ldb_result *r;
254 struct ldb_dn *basedn;
255 static const char *attrs[] = {
256 "msDs-Behavior-Version",
260 basedn = ldb_dn_new(s, s->ldap1.ldb, s->domain.dn_str);
261 NT_STATUS_HAVE_NO_MEMORY(basedn);
263 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
264 "(objectClass=*)", attrs, &r);
266 if (ret != LDB_SUCCESS) {
267 return NT_STATUS_LDAP(ret);
268 } else if (r->count != 1) {
270 return NT_STATUS_INVALID_NETWORK_RESPONSE;
273 s->ads_options.domain_behavior_version = ldb_msg_find_attr_as_uint(r->msgs[0], "msDs-Behavior-Version", 0);
279 static NTSTATUS becomeDC_ldap1_schema_object_version(struct libnet_BecomeDC_state *s)
282 struct ldb_result *r;
283 struct ldb_dn *basedn;
284 static const char *attrs[] = {
289 basedn = ldb_dn_new(s, s->ldap1.ldb, s->forest.schema_dn_str);
290 NT_STATUS_HAVE_NO_MEMORY(basedn);
292 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
293 "(objectClass=*)", attrs, &r);
295 if (ret != LDB_SUCCESS) {
296 return NT_STATUS_LDAP(ret);
297 } else if (r->count != 1) {
299 return NT_STATUS_INVALID_NETWORK_RESPONSE;
302 s->ads_options.schema_object_version = ldb_msg_find_attr_as_uint(r->msgs[0], "objectVersion", 0);
308 static NTSTATUS becomeDC_ldap1_w2k3_update_revision(struct libnet_BecomeDC_state *s)
311 struct ldb_result *r;
312 struct ldb_dn *basedn;
313 static const char *attrs[] = {
318 basedn = ldb_dn_new_fmt(s, s->ldap1.ldb, "CN=Windows2003Update,CN=DomainUpdates,CN=System,%s",
320 NT_STATUS_HAVE_NO_MEMORY(basedn);
322 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
323 "(objectClass=*)", attrs, &r);
325 if (ret != LDB_SUCCESS) {
326 return NT_STATUS_LDAP(ret);
327 } else if (r->count != 1) {
329 return NT_STATUS_INVALID_NETWORK_RESPONSE;
332 s->ads_options.w2k3_update_revision = ldb_msg_find_attr_as_uint(r->msgs[0], "revision", 0);
338 static NTSTATUS becomeDC_ldap1_infrastructure_fsmo(struct libnet_BecomeDC_state *s)
341 struct ldb_result *r;
342 struct ldb_dn *basedn;
343 struct ldb_dn *ntds_dn;
344 struct ldb_dn *server_dn;
345 static const char *_1_1_attrs[] = {
349 static const char *fsmo_attrs[] = {
353 static const char *dns_attrs[] = {
357 static const char *guid_attrs[] = {
362 basedn = ldb_dn_new_fmt(s, s->ldap1.ldb, "<WKGUID=2fbac1870ade11d297c400c04fd8d5cd,%s>",
364 NT_STATUS_HAVE_NO_MEMORY(basedn);
366 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
367 "(objectClass=*)", _1_1_attrs, &r);
369 if (ret != LDB_SUCCESS) {
370 return NT_STATUS_LDAP(ret);
371 } else if (r->count != 1) {
373 return NT_STATUS_INVALID_NETWORK_RESPONSE;
376 basedn = talloc_steal(s, r->msgs[0]->dn);
379 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
380 "(objectClass=*)", fsmo_attrs, &r);
382 if (ret != LDB_SUCCESS) {
383 return NT_STATUS_LDAP(ret);
384 } else if (r->count != 1) {
386 return NT_STATUS_INVALID_NETWORK_RESPONSE;
389 s->infrastructure_fsmo.ntds_dn_str = samdb_result_string(r->msgs[0], "fSMORoleOwner", NULL);
390 if (!s->infrastructure_fsmo.ntds_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
391 talloc_steal(s, s->infrastructure_fsmo.ntds_dn_str);
395 ntds_dn = ldb_dn_new(s, s->ldap1.ldb, s->infrastructure_fsmo.ntds_dn_str);
396 NT_STATUS_HAVE_NO_MEMORY(ntds_dn);
398 server_dn = ldb_dn_get_parent(s, ntds_dn);
399 NT_STATUS_HAVE_NO_MEMORY(server_dn);
401 s->infrastructure_fsmo.server_dn_str = ldb_dn_alloc_linearized(s, server_dn);
402 NT_STATUS_HAVE_NO_MEMORY(s->infrastructure_fsmo.server_dn_str);
404 ret = ldb_search(s->ldap1.ldb, server_dn, LDB_SCOPE_BASE,
405 "(objectClass=*)", dns_attrs, &r);
406 if (ret != LDB_SUCCESS) {
407 return NT_STATUS_LDAP(ret);
408 } else if (r->count != 1) {
410 return NT_STATUS_INVALID_NETWORK_RESPONSE;
413 s->infrastructure_fsmo.dns_name = samdb_result_string(r->msgs[0], "dnsHostName", NULL);
414 if (!s->infrastructure_fsmo.dns_name) return NT_STATUS_INVALID_NETWORK_RESPONSE;
415 talloc_steal(s, s->infrastructure_fsmo.dns_name);
419 ret = ldb_search(s->ldap1.ldb, ntds_dn, LDB_SCOPE_BASE,
420 "(objectClass=*)", guid_attrs, &r);
421 if (ret != LDB_SUCCESS) {
422 return NT_STATUS_LDAP(ret);
423 } else if (r->count != 1) {
425 return NT_STATUS_INVALID_NETWORK_RESPONSE;
428 s->infrastructure_fsmo.ntds_guid = samdb_result_guid(r->msgs[0], "objectGUID");
435 static NTSTATUS becomeDC_ldap1_rid_manager_fsmo(struct libnet_BecomeDC_state *s)
438 struct ldb_result *r;
439 struct ldb_dn *basedn;
440 const char *reference_dn_str;
441 struct ldb_dn *ntds_dn;
442 struct ldb_dn *server_dn;
443 static const char *rid_attrs[] = {
444 "rIDManagerReference",
447 static const char *fsmo_attrs[] = {
451 static const char *dns_attrs[] = {
455 static const char *guid_attrs[] = {
460 basedn = ldb_dn_new(s, s->ldap1.ldb, s->domain.dn_str);
461 NT_STATUS_HAVE_NO_MEMORY(basedn);
463 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
464 "(objectClass=*)", rid_attrs, &r);
466 if (ret != LDB_SUCCESS) {
467 return NT_STATUS_LDAP(ret);
468 } else if (r->count != 1) {
470 return NT_STATUS_INVALID_NETWORK_RESPONSE;
473 reference_dn_str = samdb_result_string(r->msgs[0], "rIDManagerReference", NULL);
474 if (!reference_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
476 basedn = ldb_dn_new(s, s->ldap1.ldb, reference_dn_str);
477 NT_STATUS_HAVE_NO_MEMORY(basedn);
481 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
482 "(objectClass=*)", fsmo_attrs, &r);
484 if (ret != LDB_SUCCESS) {
485 return NT_STATUS_LDAP(ret);
486 } else if (r->count != 1) {
488 return NT_STATUS_INVALID_NETWORK_RESPONSE;
491 s->rid_manager_fsmo.ntds_dn_str = samdb_result_string(r->msgs[0], "fSMORoleOwner", NULL);
492 if (!s->rid_manager_fsmo.ntds_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
493 talloc_steal(s, s->rid_manager_fsmo.ntds_dn_str);
497 ntds_dn = ldb_dn_new(s, s->ldap1.ldb, s->rid_manager_fsmo.ntds_dn_str);
498 NT_STATUS_HAVE_NO_MEMORY(ntds_dn);
500 server_dn = ldb_dn_get_parent(s, ntds_dn);
501 NT_STATUS_HAVE_NO_MEMORY(server_dn);
503 s->rid_manager_fsmo.server_dn_str = ldb_dn_alloc_linearized(s, server_dn);
504 NT_STATUS_HAVE_NO_MEMORY(s->rid_manager_fsmo.server_dn_str);
506 ret = ldb_search(s->ldap1.ldb, server_dn, LDB_SCOPE_BASE,
507 "(objectClass=*)", dns_attrs, &r);
508 if (ret != LDB_SUCCESS) {
509 return NT_STATUS_LDAP(ret);
510 } else if (r->count != 1) {
512 return NT_STATUS_INVALID_NETWORK_RESPONSE;
515 s->rid_manager_fsmo.dns_name = samdb_result_string(r->msgs[0], "dnsHostName", NULL);
516 if (!s->rid_manager_fsmo.dns_name) return NT_STATUS_INVALID_NETWORK_RESPONSE;
517 talloc_steal(s, s->rid_manager_fsmo.dns_name);
521 ret = ldb_search(s->ldap1.ldb, ntds_dn, LDB_SCOPE_BASE,
522 "(objectClass=*)", guid_attrs, &r);
523 if (ret != LDB_SUCCESS) {
524 return NT_STATUS_LDAP(ret);
525 } else if (r->count != 1) {
527 return NT_STATUS_INVALID_NETWORK_RESPONSE;
530 s->rid_manager_fsmo.ntds_guid = samdb_result_guid(r->msgs[0], "objectGUID");
537 static NTSTATUS becomeDC_ldap1_site_object(struct libnet_BecomeDC_state *s)
540 struct ldb_result *r;
541 struct ldb_dn *basedn;
543 basedn = ldb_dn_new_fmt(s, s->ldap1.ldb, "CN=%s,CN=Sites,%s",
544 s->dest_dsa.site_name,
545 s->forest.config_dn_str);
546 NT_STATUS_HAVE_NO_MEMORY(basedn);
548 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
549 "(objectClass=*)", NULL, &r);
551 if (ret != LDB_SUCCESS) {
552 return NT_STATUS_LDAP(ret);
553 } else if (r->count != 1) {
555 return NT_STATUS_INVALID_NETWORK_RESPONSE;
558 s->dest_dsa.site_guid = samdb_result_guid(r->msgs[0], "objectGUID");
564 static NTSTATUS becomeDC_ldap1_computer_object(struct libnet_BecomeDC_state *s)
567 struct ldb_result *r;
568 struct ldb_dn *basedn;
570 static const char *attrs[] = {
572 "userAccountControl",
576 basedn = ldb_dn_new(s, s->ldap1.ldb, s->domain.dn_str);
577 NT_STATUS_HAVE_NO_MEMORY(basedn);
579 filter = talloc_asprintf(basedn, "(&(|(objectClass=user)(objectClass=computer))(sAMAccountName=%s$))",
580 s->dest_dsa.netbios_name);
581 NT_STATUS_HAVE_NO_MEMORY(filter);
583 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_SUBTREE,
586 if (ret != LDB_SUCCESS) {
587 return NT_STATUS_LDAP(ret);
588 } else if (r->count != 1) {
590 return NT_STATUS_INVALID_NETWORK_RESPONSE;
593 s->dest_dsa.computer_dn_str = samdb_result_string(r->msgs[0], "distinguishedName", NULL);
594 if (!s->dest_dsa.computer_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
595 talloc_steal(s, s->dest_dsa.computer_dn_str);
597 s->dest_dsa.user_account_control = samdb_result_uint(r->msgs[0], "userAccountControl", 0);
603 static NTSTATUS becomeDC_ldap1_server_object_1(struct libnet_BecomeDC_state *s)
606 struct ldb_result *r;
607 struct ldb_dn *basedn;
608 const char *server_reference_dn_str;
609 struct ldb_dn *server_reference_dn;
610 struct ldb_dn *computer_dn;
612 basedn = ldb_dn_new_fmt(s, s->ldap1.ldb, "CN=%s,CN=Servers,CN=%s,CN=Sites,%s",
613 s->dest_dsa.netbios_name,
614 s->dest_dsa.site_name,
615 s->forest.config_dn_str);
616 NT_STATUS_HAVE_NO_MEMORY(basedn);
618 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
619 "(objectClass=*)", NULL, &r);
621 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
622 /* if the object doesn't exist, we'll create it later */
624 } else if (ret != LDB_SUCCESS) {
625 return NT_STATUS_LDAP(ret);
626 } else if (r->count != 1) {
628 return NT_STATUS_INVALID_NETWORK_RESPONSE;
631 server_reference_dn_str = samdb_result_string(r->msgs[0], "serverReference", NULL);
632 if (!server_reference_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
633 server_reference_dn = ldb_dn_new(r, s->ldap1.ldb, server_reference_dn_str);
634 NT_STATUS_HAVE_NO_MEMORY(server_reference_dn);
636 computer_dn = ldb_dn_new(r, s->ldap1.ldb, s->dest_dsa.computer_dn_str);
637 NT_STATUS_HAVE_NO_MEMORY(computer_dn);
640 * if the server object belongs to another DC in another domain in the forest,
641 * we should not touch this object!
643 if (ldb_dn_compare(computer_dn, server_reference_dn) != 0) {
645 return NT_STATUS_OBJECT_NAME_COLLISION;
648 /* if the server object is already for the dest_dsa, then we don't need to create it */
649 s->dest_dsa.server_dn_str = samdb_result_string(r->msgs[0], "distinguishedName", NULL);
650 if (!s->dest_dsa.server_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;
651 talloc_steal(s, s->dest_dsa.server_dn_str);
657 static NTSTATUS becomeDC_ldap1_server_object_2(struct libnet_BecomeDC_state *s)
660 struct ldb_result *r;
661 struct ldb_dn *basedn;
662 const char *server_reference_bl_dn_str;
663 static const char *attrs[] = {
668 /* if the server_dn_str has a valid value, we skip this lookup */
669 if (s->dest_dsa.server_dn_str) return NT_STATUS_OK;
671 basedn = ldb_dn_new(s, s->ldap1.ldb, s->dest_dsa.computer_dn_str);
672 NT_STATUS_HAVE_NO_MEMORY(basedn);
674 ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
675 "(objectClass=*)", attrs, &r);
677 if (ret != LDB_SUCCESS) {
678 return NT_STATUS_LDAP(ret);
679 } else if (r->count != 1) {
681 return NT_STATUS_INVALID_NETWORK_RESPONSE;
684 server_reference_bl_dn_str = samdb_result_string(r->msgs[0], "serverReferenceBL", NULL);
685 if (!server_reference_bl_dn_str) {
686 /* if no back link is present, we're done for this function */
691 /* if the server object is already for the dest_dsa, then we don't need to create it */
692 s->dest_dsa.server_dn_str = samdb_result_string(r->msgs[0], "serverReferenceBL", NULL);
693 if (s->dest_dsa.server_dn_str) {
694 /* if a back link is present, we know that the server object is present */
695 talloc_steal(s, s->dest_dsa.server_dn_str);
702 static NTSTATUS becomeDC_ldap1_server_object_add(struct libnet_BecomeDC_state *s)
705 struct ldb_message *msg;
708 /* if the server_dn_str has a valid value, we skip this lookup */
709 if (s->dest_dsa.server_dn_str) return NT_STATUS_OK;
711 msg = ldb_msg_new(s);
712 NT_STATUS_HAVE_NO_MEMORY(msg);
714 msg->dn = ldb_dn_new_fmt(msg, s->ldap1.ldb, "CN=not,CN=add,CN=%s,CN=Servers,CN=%s,CN=Sites,%s",
715 s->dest_dsa.netbios_name,
716 s->dest_dsa.site_name,
717 s->forest.config_dn_str);
718 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
720 ret = ldb_msg_add_string(msg, "objectClass", "server");
723 return NT_STATUS_NO_MEMORY;
725 ret = ldb_msg_add_string(msg, "systemFlags", "50000000");
728 return NT_STATUS_NO_MEMORY;
730 ret = ldb_msg_add_string(msg, "serverReference", s->dest_dsa.computer_dn_str);
733 return NT_STATUS_NO_MEMORY;
736 server_dn_str = ldb_dn_alloc_linearized(s, msg->dn);
737 NT_STATUS_HAVE_NO_MEMORY(server_dn_str);
739 ret = ldb_add(s->ldap1.ldb, msg);
741 if (ret != LDB_SUCCESS) {
742 talloc_free(server_dn_str);
743 return NT_STATUS_LDAP(ret);
746 s->dest_dsa.server_dn_str = server_dn_str;
751 static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s)
753 struct composite_context *c = s->creq;
755 c->status = becomeDC_ldap_connect(s, &s->ldap1);
756 if (!composite_is_ok(c)) return;
758 c->status = becomeDC_ldap1_rootdse(s);
759 if (!composite_is_ok(c)) return;
761 c->status = becomeDC_ldap1_config_behavior_version(s);
762 if (!composite_is_ok(c)) return;
764 c->status = becomeDC_ldap1_domain_behavior_version(s);
765 if (!composite_is_ok(c)) return;
767 c->status = becomeDC_ldap1_schema_object_version(s);
768 if (!composite_is_ok(c)) return;
770 c->status = becomeDC_ldap1_w2k3_update_revision(s);
771 if (!composite_is_ok(c)) return;
773 c->status = becomeDC_ldap1_infrastructure_fsmo(s);
774 if (!composite_is_ok(c)) return;
776 c->status = becomeDC_ldap1_rid_manager_fsmo(s);
777 if (!composite_is_ok(c)) return;
779 c->status = becomeDC_ldap1_site_object(s);
780 if (!composite_is_ok(c)) return;
782 c->status = becomeDC_ldap1_computer_object(s);
783 if (!composite_is_ok(c)) return;
785 c->status = becomeDC_ldap1_server_object_1(s);
786 if (!composite_is_ok(c)) return;
788 c->status = becomeDC_ldap1_server_object_2(s);
789 if (!composite_is_ok(c)) return;
791 c->status = becomeDC_ldap1_server_object_add(s);
792 if (!composite_is_ok(c)) return;
794 composite_error(c, NT_STATUS_NOT_IMPLEMENTED);
797 struct composite_context *libnet_BecomeDC_send(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_BecomeDC *r)
799 struct composite_context *c;
800 struct libnet_BecomeDC_state *s;
803 c = composite_create(mem_ctx, ctx->event_ctx);
804 if (c == NULL) return NULL;
806 s = talloc_zero(c, struct libnet_BecomeDC_state);
807 if (composite_nomem(s, c)) return c;
813 s->domain.dns_name = talloc_strdup(s, r->in.domain_dns_name);
814 if (composite_nomem(s->domain.dns_name, c)) return c;
815 s->domain.netbios_name = talloc_strdup(s, r->in.domain_netbios_name);
816 if (composite_nomem(s->domain.netbios_name, c)) return c;
818 /* Source DSA input */
819 s->source_dsa.address = talloc_strdup(s, r->in.source_dsa_address);
820 if (composite_nomem(s->source_dsa.address, c)) return c;
822 /* Destination DSA input */
823 s->dest_dsa.netbios_name= talloc_strdup(s, r->in.dest_dsa_netbios_name);
824 if (composite_nomem(s->dest_dsa.netbios_name, c)) return c;
826 /* Destination DSA dns_name construction */
827 tmp_name = strlower_talloc(s, s->dest_dsa.netbios_name);
828 if (composite_nomem(tmp_name, c)) return c;
829 s->dest_dsa.dns_name = talloc_asprintf_append(tmp_name, ".%s",
831 if (composite_nomem(s->dest_dsa.dns_name, c)) return c;
833 becomeDC_send_cldap(s);
837 NTSTATUS libnet_BecomeDC_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, struct libnet_BecomeDC *r)
841 status = composite_wait(c);
849 NTSTATUS libnet_BecomeDC(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_BecomeDC *r)
852 struct composite_context *c;
853 c = libnet_BecomeDC_send(ctx, mem_ctx, r);
854 status = libnet_BecomeDC_recv(c, mem_ctx, r);