diff options
-rw-r--r-- | source4/libnet/libnet_become_dc.c | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index fc46691ab3..0bc0fed335 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -629,21 +629,22 @@ static NTSTATUS becomeDC_ldap1_server_object_1(struct libnet_BecomeDC_state *s) 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); - - 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; + 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); + + /* + * 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 @@ static NTSTATUS becomeDC_ldap1_server_object_add(struct libnet_BecomeDC_state *s 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 @@ static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s) 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); } |