Author: metze Date: 2006-12-06 12:08:32 +0000 (Wed, 06 Dec 2006) New Revision: 20051
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=20051 Log: handle the case where the server object exist, but doesn't have a serverReference metze Modified: branches/SAMBA_4_0/source/libnet/libnet_become_dc.c Changeset: Modified: branches/SAMBA_4_0/source/libnet/libnet_become_dc.c =================================================================== --- branches/SAMBA_4_0/source/libnet/libnet_become_dc.c 2006-12-06 11:45:33 UTC (rev 20050) +++ branches/SAMBA_4_0/source/libnet/libnet_become_dc.c 2006-12-06 12:08:32 UTC (rev 20051) @@ -629,21 +629,22 @@ return NT_STATUS_INVALID_NETWORK_RESPONSE; } - server_reference_dn_str = samdb_result_string(r->msgs[0], "serverReference", NULL); - if (!server_reference_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE; - server_reference_dn = ldb_dn_new(r, s->ldap1.ldb, server_reference_dn_str); - NT_STATUS_HAVE_NO_MEMORY(server_reference_dn); + server_reference_dn_str = samdb_result_string(r->msgs[0], "serverReference", NULL); + if (server_reference_dn_str) { + server_reference_dn = ldb_dn_new(r, s->ldap1.ldb, server_reference_dn_str); + NT_STATUS_HAVE_NO_MEMORY(server_reference_dn); - computer_dn = ldb_dn_new(r, s->ldap1.ldb, s->dest_dsa.computer_dn_str); - NT_STATUS_HAVE_NO_MEMORY(computer_dn); + computer_dn = ldb_dn_new(r, s->ldap1.ldb, s->dest_dsa.computer_dn_str); + NT_STATUS_HAVE_NO_MEMORY(computer_dn); - /* - * if the server object belongs to another DC in another domain in the forest, - * we should not touch this object! - */ - if (ldb_dn_compare(computer_dn, server_reference_dn) != 0) { - talloc_free(r); - return NT_STATUS_OBJECT_NAME_COLLISION; + /* + * if the server object belongs to another DC in another domain in the forest, + * we should not touch this object! + */ + if (ldb_dn_compare(computer_dn, server_reference_dn) != 0) { + talloc_free(r); + return NT_STATUS_OBJECT_NAME_COLLISION; + } } /* if the server object is already for the dest_dsa, then we don't need to create it */ @@ -749,6 +750,56 @@ return NT_STATUS_OK; } +static NTSTATUS becomeDC_ldap1_server_object_modify(struct libnet_BecomeDC_state *s) +{ + int ret; + struct ldb_message *msg; + uint32_t i; + + /* make a 'modify' msg, and only for serverReference */ + msg = ldb_msg_new(s); + NT_STATUS_HAVE_NO_MEMORY(msg); + msg->dn = ldb_dn_new(msg, s->ldap1.ldb, s->dest_dsa.server_dn_str); + NT_STATUS_HAVE_NO_MEMORY(msg->dn); + + ret = ldb_msg_add_string(msg, "serverReference", s->dest_dsa.computer_dn_str); + if (ret != 0) { + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + + /* mark all the message elements (should be just one) + as LDB_FLAG_MOD_ADD */ + for (i=0;i<msg->num_elements;i++) { + msg->elements[i].flags = LDB_FLAG_MOD_ADD; + } + + ret = ldb_modify(s->ldap1.ldb, msg); + if (ret == LDB_SUCCESS) { + talloc_free(msg); + return NT_STATUS_OK; + } else if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { + /* retry with LDB_FLAG_MOD_REPLACE */ + } else { + talloc_free(msg); + return NT_STATUS_LDAP(ret); + } + + /* mark all the message elements (should be just one) + as LDB_FLAG_MOD_REPLACE */ + for (i=0;i<msg->num_elements;i++) { + msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; + } + + ret = ldb_modify(s->ldap1.ldb, msg); + talloc_free(msg); + if (ret != LDB_SUCCESS) { + return NT_STATUS_LDAP(ret); + } + + return NT_STATUS_OK; +} + static void becomeDC_connect_ldap2(struct libnet_BecomeDC_state *s); static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s) @@ -794,6 +845,9 @@ c->status = becomeDC_ldap1_server_object_add(s); if (!composite_is_ok(c)) return; + c->status = becomeDC_ldap1_server_object_modify(s); + if (!composite_is_ok(c)) return; + becomeDC_connect_ldap2(s); }