s4: fixed updaterefs options bitmap
[ira/wip.git] / source4 / libnet / libnet_become_dc.c
index 817fae12c5dd03e606cdf7518928b952caaa657c..2d35b40cfa793730b9672afc1ae4db3905a6397c 100644 (file)
@@ -5,7 +5,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "libcli/cldap/cldap.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
-#include "lib/db_wrap.h"
+#include "lib/ldb_wrap.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
 #include "libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "librpc/gen_ndr/ndr_security.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
 #include "librpc/gen_ndr/ndr_drsuapi.h"
 #include "auth/gensec/gensec.h"
+#include "param/param.h"
 
 /*****************************************************************************
  * Windows 2003 (w2k3) does the following steps when changing the server role
@@ -687,7 +688,7 @@ struct libnet_BecomeDC_state {
        struct {
                struct cldap_socket *sock;
                struct cldap_netlogon io;
-               struct nbt_cldap_netlogon_5 netlogon5;
+               struct NETLOGON_SAM_LOGON_RESPONSE_EX netlogon;
        } cldap;
 
        struct becomeDC_ldap {
@@ -730,67 +731,73 @@ struct libnet_BecomeDC_state {
        struct libnet_BecomeDC_Callbacks callbacks;
 };
 
-static void becomeDC_recv_cldap(struct cldap_request *req);
+static void becomeDC_recv_cldap(struct tevent_req *req);
 
 static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
 {
        struct composite_context *c = s->creq;
-       struct cldap_request *req;
+       struct tevent_req *req;
 
        s->cldap.io.in.dest_address     = s->source_dsa.address;
+       s->cldap.io.in.dest_port        = lp_cldap_port(s->libnet->lp_ctx);
        s->cldap.io.in.realm            = s->domain.dns_name;
        s->cldap.io.in.host             = s->dest_dsa.netbios_name;
        s->cldap.io.in.user             = NULL;
        s->cldap.io.in.domain_guid      = NULL;
        s->cldap.io.in.domain_sid       = NULL;
        s->cldap.io.in.acct_control     = -1;
-       s->cldap.io.in.version          = 6;
+       s->cldap.io.in.version          = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
+       s->cldap.io.in.map_response     = true;
 
-       s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx);
-       if (composite_nomem(s->cldap.sock, c)) return;
+       c->status = cldap_socket_init(s, s->libnet->event_ctx,
+                                     NULL, NULL, &s->cldap.sock);//TODO
+       if (!composite_is_ok(c)) return;
 
-       req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
+       req = cldap_netlogon_send(s, s->cldap.sock, &s->cldap.io);
        if (composite_nomem(req, c)) return;
-       req->async.fn           = becomeDC_recv_cldap;
-       req->async.private      = s;
+       tevent_req_set_callback(req, becomeDC_recv_cldap, s);
 }
 
 static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s);
 
-static void becomeDC_recv_cldap(struct cldap_request *req)
+static void becomeDC_recv_cldap(struct tevent_req *req)
 {
-       struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+       struct libnet_BecomeDC_state *s = tevent_req_callback_data(req,
                                          struct libnet_BecomeDC_state);
        struct composite_context *c = s->creq;
 
-       c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
+       c->status = cldap_netlogon_recv(req,
+                                       lp_iconv_convenience(s->libnet->lp_ctx),
+                                       s, &s->cldap.io);
+       talloc_free(req);
        if (!composite_is_ok(c)) return;
 
-       s->cldap.netlogon5 = s->cldap.io.out.netlogon.logon5;
+       s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;
 
-       s->domain.dns_name              = s->cldap.netlogon5.dns_domain;
-       s->domain.netbios_name          = s->cldap.netlogon5.domain;
-       s->domain.guid                  = s->cldap.netlogon5.domain_uuid;
+       s->domain.dns_name              = s->cldap.netlogon.dns_domain;
+       s->domain.netbios_name          = s->cldap.netlogon.domain;
+       s->domain.guid                  = s->cldap.netlogon.domain_uuid;
 
-       s->forest.dns_name              = s->cldap.netlogon5.forest;
+       s->forest.dns_name              = s->cldap.netlogon.forest;
 
-       s->source_dsa.dns_name          = s->cldap.netlogon5.pdc_dns_name;
-       s->source_dsa.netbios_name      = s->cldap.netlogon5.pdc_name;
-       s->source_dsa.site_name         = s->cldap.netlogon5.server_site;
+       s->source_dsa.dns_name          = s->cldap.netlogon.pdc_dns_name;
+       s->source_dsa.netbios_name      = s->cldap.netlogon.pdc_name;
+       s->source_dsa.site_name         = s->cldap.netlogon.server_site;
 
-       s->dest_dsa.site_name           = s->cldap.netlogon5.client_site;
+       s->dest_dsa.site_name           = s->cldap.netlogon.client_site;
 
        becomeDC_connect_ldap1(s);
 }
 
-static NTSTATUS becomeDC_ldap_connect(struct libnet_BecomeDC_state *s, struct becomeDC_ldap *ldap)
+static NTSTATUS becomeDC_ldap_connect(struct libnet_BecomeDC_state *s, 
+                                     struct becomeDC_ldap *ldap)
 {
        char *url;
 
        url = talloc_asprintf(s, "ldap://%s/", s->source_dsa.dns_name);
        NT_STATUS_HAVE_NO_MEMORY(url);
 
-       ldap->ldb = ldb_wrap_connect(s, url,
+       ldap->ldb = ldb_wrap_connect(s, s->libnet->event_ctx, s->libnet->lp_ctx, url,
                                     NULL,
                                     s->libnet->cred,
                                     0, NULL);
@@ -815,8 +822,8 @@ static NTSTATUS becomeDC_ldap1_rootdse(struct libnet_BecomeDC_state *s)
        basedn = ldb_dn_new(s, s->ldap1.ldb, NULL);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE, 
-                        "(objectClass=*)", attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE, attrs,
+                        "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -824,7 +831,6 @@ static NTSTATUS becomeDC_ldap1_rootdse(struct libnet_BecomeDC_state *s)
                talloc_free(r);
                return NT_STATUS_INVALID_NETWORK_RESPONSE;
        }
-       talloc_steal(s, r);
 
        s->ldap1.rootdse = r->msgs[0];
 
@@ -859,8 +865,8 @@ static NTSTATUS becomeDC_ldap1_crossref_behavior_version(struct libnet_BecomeDC_
        basedn = ldb_dn_new(s, s->ldap1.ldb, s->forest.config_dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_ONELEVEL,
-                        "(cn=Partitions)", attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_ONELEVEL, attrs,
+                        "(cn=Partitions)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -888,8 +894,8 @@ static NTSTATUS becomeDC_ldap1_domain_behavior_version(struct libnet_BecomeDC_st
        basedn = ldb_dn_new(s, s->ldap1.ldb, s->domain.dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE, attrs,
+                        "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -917,8 +923,8 @@ static NTSTATUS becomeDC_ldap1_schema_object_version(struct libnet_BecomeDC_stat
        basedn = ldb_dn_new(s, s->ldap1.ldb, s->forest.schema_dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE, attrs,
+                        "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -947,8 +953,8 @@ static NTSTATUS becomeDC_ldap1_w2k3_update_revision(struct libnet_BecomeDC_state
                                s->domain.dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE, attrs,
+                        "(objectClass=*)");
        talloc_free(basedn);
        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                /* w2k doesn't have this object */
@@ -995,8 +1001,8 @@ static NTSTATUS becomeDC_ldap1_infrastructure_fsmo(struct libnet_BecomeDC_state
                                s->domain.dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", _1_1_attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        _1_1_attrs, "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -1008,8 +1014,8 @@ static NTSTATUS becomeDC_ldap1_infrastructure_fsmo(struct libnet_BecomeDC_state
        basedn = talloc_steal(s, r->msgs[0]->dn);
        talloc_free(r);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", fsmo_attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        fsmo_attrs, "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -1033,8 +1039,8 @@ static NTSTATUS becomeDC_ldap1_infrastructure_fsmo(struct libnet_BecomeDC_state
        s->infrastructure_fsmo.server_dn_str = ldb_dn_alloc_linearized(s, server_dn);
        NT_STATUS_HAVE_NO_MEMORY(s->infrastructure_fsmo.server_dn_str);
 
-       ret = ldb_search(s->ldap1.ldb, server_dn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", dns_attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, server_dn, LDB_SCOPE_BASE,
+                        dns_attrs, "(objectClass=*)");
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
        } else if (r->count != 1) {
@@ -1048,8 +1054,8 @@ static NTSTATUS becomeDC_ldap1_infrastructure_fsmo(struct libnet_BecomeDC_state
 
        talloc_free(r);
 
-       ret = ldb_search(s->ldap1.ldb, ntds_dn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", guid_attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, ntds_dn, LDB_SCOPE_BASE,
+                        guid_attrs, "(objectClass=*)");
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
        } else if (r->count != 1) {
@@ -1092,8 +1098,8 @@ static NTSTATUS becomeDC_ldap1_rid_manager_fsmo(struct libnet_BecomeDC_state *s)
        basedn = ldb_dn_new(s, s->ldap1.ldb, s->domain.dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", rid_attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        rid_attrs, "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -1110,8 +1116,8 @@ static NTSTATUS becomeDC_ldap1_rid_manager_fsmo(struct libnet_BecomeDC_state *s)
 
        talloc_free(r);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", fsmo_attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        fsmo_attrs, "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -1135,8 +1141,8 @@ static NTSTATUS becomeDC_ldap1_rid_manager_fsmo(struct libnet_BecomeDC_state *s)
        s->rid_manager_fsmo.server_dn_str = ldb_dn_alloc_linearized(s, server_dn);
        NT_STATUS_HAVE_NO_MEMORY(s->rid_manager_fsmo.server_dn_str);
 
-       ret = ldb_search(s->ldap1.ldb, server_dn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", dns_attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, server_dn, LDB_SCOPE_BASE,
+                        dns_attrs, "(objectClass=*)");
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
        } else if (r->count != 1) {
@@ -1150,8 +1156,8 @@ static NTSTATUS becomeDC_ldap1_rid_manager_fsmo(struct libnet_BecomeDC_state *s)
 
        talloc_free(r);
 
-       ret = ldb_search(s->ldap1.ldb, ntds_dn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", guid_attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, ntds_dn, LDB_SCOPE_BASE,
+                        guid_attrs, "(objectClass=*)");
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
        } else if (r->count != 1) {
@@ -1177,8 +1183,8 @@ static NTSTATUS becomeDC_ldap1_site_object(struct libnet_BecomeDC_state *s)
                                s->forest.config_dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE, 
-                        "(objectClass=*)", NULL, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        NULL, "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -1209,7 +1215,6 @@ static NTSTATUS becomeDC_ldap1_computer_object(struct libnet_BecomeDC_state *s)
        int ret;
        struct ldb_result *r;
        struct ldb_dn *basedn;
-       char *filter;
        static const char *attrs[] = {
                "distinguishedName",
                "userAccountControl",
@@ -1219,12 +1224,9 @@ static NTSTATUS becomeDC_ldap1_computer_object(struct libnet_BecomeDC_state *s)
        basedn = ldb_dn_new(s, s->ldap1.ldb, s->domain.dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       filter = talloc_asprintf(basedn, "(&(|(objectClass=user)(objectClass=computer))(sAMAccountName=%s$))",
-                                s->dest_dsa.netbios_name);
-       NT_STATUS_HAVE_NO_MEMORY(filter);
-
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_SUBTREE, 
-                        filter, attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_SUBTREE, attrs,
+                        "(&(|(objectClass=user)(objectClass=computer))(sAMAccountName=%s$))",
+                        s->dest_dsa.netbios_name);
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -1258,8 +1260,8 @@ static NTSTATUS becomeDC_ldap1_server_object_1(struct libnet_BecomeDC_state *s)
                                s->forest.config_dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE, 
-                        "(objectClass=*)", NULL, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        NULL, "(objectClass=*)");
        talloc_free(basedn);
        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                /* if the object doesn't exist, we'll create it later */
@@ -1315,8 +1317,8 @@ static NTSTATUS becomeDC_ldap1_server_object_2(struct libnet_BecomeDC_state *s)
        basedn = ldb_dn_new(s, s->ldap1.ldb, s->dest_dsa.computer_dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE, 
-                        "(objectClass=*)", attrs, &r);
+       ret = ldb_search(s->ldap1.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        attrs, "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -1511,20 +1513,38 @@ static void becomeDC_drsuapi_connect_send(struct libnet_BecomeDC_state *s,
        drsuapi->s = s;
 
        if (!drsuapi->binding) {
-               if (lp_parm_bool(-1, "become_dc", "print", False)) {
-                       binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[krb5,print,seal]", s->source_dsa.dns_name);
-                       if (composite_nomem(binding_str, c)) return;
-               } else {
-                       binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[krb5,seal]", s->source_dsa.dns_name);
-                       if (composite_nomem(binding_str, c)) return;
+               const char *krb5_str = "";
+               const char *print_str = "";
+               /*
+                * Note: Replication only works with Windows 2000 when 'krb5' is
+                *       passed as auth_type here. If NTLMSSP is used, Windows
+                *       2000 returns garbage in the DsGetNCChanges() response
+                *       if encrypted password attributes would be in the response.
+                *       That means the replication of the schema and configuration
+                *       partition works fine, but it fails for the domain partition.
+                */
+               if (lp_parm_bool(s->libnet->lp_ctx, NULL, "become_dc",
+                                "force krb5", true))
+               {
+                       krb5_str = "krb5,";
+               }
+               if (lp_parm_bool(s->libnet->lp_ctx, NULL, "become_dc",
+                                "print", false))
+               {
+                       print_str = "print,";
                }
+               binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[%s%sseal]",
+                                             s->source_dsa.dns_name,
+                                             krb5_str, print_str);
+               if (composite_nomem(binding_str, c)) return;
                c->status = dcerpc_parse_binding(s, binding_str, &drsuapi->binding);
                talloc_free(binding_str);
                if (!composite_is_ok(c)) return;
        }
 
-       creq = dcerpc_pipe_connect_b_send(s, drsuapi->binding, &dcerpc_table_drsuapi,
-                                         s->libnet->cred, s->libnet->event_ctx);
+       creq = dcerpc_pipe_connect_b_send(s, drsuapi->binding, &ndr_table_drsuapi,
+                                         s->libnet->cred, s->libnet->event_ctx,
+                                         s->libnet->lp_ctx);
        composite_continue(c, creq, recv_fn, s);
 }
 
@@ -1596,12 +1616,7 @@ static void becomeDC_drsuapi_bind_send(struct libnet_BecomeDC_state *s,
        bind_info28->supported_extensions       |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
 #endif
        bind_info28->site_guid                  = s->dest_dsa.site_guid;
-       if (s->domain.behavior_version == 2) {
-               /* TODO: find out how this is really triggered! */
-               bind_info28->u1                         = 528;
-       } else {
-               bind_info28->u1                         = 516;
-       }
+       bind_info28->pid                        = 0;
        bind_info28->repl_epoch                 = 0;
 
        drsuapi->bind_info_ctr.length           = 28;
@@ -1630,10 +1645,19 @@ static WERROR becomeDC_drsuapi_bind_recv(struct libnet_BecomeDC_state *s,
                        info24 = &drsuapi->bind_r.out.bind_info->info.info24;
                        drsuapi->remote_info28.supported_extensions     = info24->supported_extensions;
                        drsuapi->remote_info28.site_guid                = info24->site_guid;
-                       drsuapi->remote_info28.u1                       = info24->u1;
+                       drsuapi->remote_info28.pid                      = info24->pid;
                        drsuapi->remote_info28.repl_epoch               = 0;
                        break;
                }
+               case 48: {
+                       struct drsuapi_DsBindInfo48 *info48;
+                       info48 = &drsuapi->bind_r.out.bind_info->info.info48;
+                       drsuapi->remote_info28.supported_extensions     = info48->supported_extensions;
+                       drsuapi->remote_info28.site_guid                = info48->site_guid;
+                       drsuapi->remote_info28.pid                      = info48->pid;
+                       drsuapi->remote_info28.repl_epoch               = info48->repl_epoch;
+                       break;
+               }
                case 28:
                        drsuapi->remote_info28 = drsuapi->bind_r.out.bind_info->info.info28;
                        break;
@@ -1684,6 +1708,8 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
        struct drsuapi_DsReplicaObjectIdentifier *identifier;
        uint32_t num_attrs, i = 0;
        struct drsuapi_DsReplicaAttribute *attrs;
+       struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(s->libnet->lp_ctx);
+       enum ndr_err_code ndr_err;
        bool w2k3;
 
        /* choose a random invocationId */
@@ -1736,7 +1762,8 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                domain_admins_sid_str = dom_sid_string(domain_admins_sid, domain_admins_sid);
                if (composite_nomem(domain_admins_sid_str, c)) return;
 
-               v = security_descriptor_create(vd,
+               v = security_descriptor_dacl_create(vd,
+                                              0,
                                               /* owner: domain admins */
                                               domain_admins_sid_str,
                                               /* owner group: domain admins */
@@ -1780,8 +1807,11 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                                               NULL);
                if (composite_nomem(v, c)) return;
 
-               c->status = ndr_push_struct_blob(&vd[0], vd, v,(ndr_push_flags_fn_t)ndr_push_security_descriptor);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, v,(ndr_push_flags_fn_t)ndr_push_security_descriptor);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
                vs[0].blob              = &vd[0];
 
@@ -1836,9 +1866,12 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                                                          s->forest.schema_dn_str);
                if (composite_nomem(v[0].dn, c)) return;
 
-               c->status = ndr_push_struct_blob(&vd[0], vd, &v[0],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, &v[0], 
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
                vs[0].blob              = &vd[0];
 
@@ -1863,8 +1896,11 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
 
                v = &s->dest_dsa.invocation_id;
 
-               c->status = ndr_push_struct_blob(&vd[0], vd, v, (ndr_push_flags_fn_t)ndr_push_GUID);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, v, (ndr_push_flags_fn_t)ndr_push_GUID);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
                vs[0].blob              = &vd[0];
 
@@ -1899,17 +1935,26 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                v[2].sid                = s->zero_sid;
                v[2].dn                 = s->forest.schema_dn_str;
 
-               c->status = ndr_push_struct_blob(&vd[0], vd, &v[0],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, &v[0],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
-               c->status = ndr_push_struct_blob(&vd[1], vd, &v[1],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[1], vd, iconv_convenience, &v[1],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
-               c->status = ndr_push_struct_blob(&vd[2], vd, &v[2],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[2], vd, iconv_convenience, &v[2],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
                vs[0].blob              = &vd[0];
                vs[1].blob              = &vd[1];
@@ -1946,17 +1991,26 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                v[2].sid                = s->zero_sid;
                v[2].dn                 = s->forest.schema_dn_str;
 
-               c->status = ndr_push_struct_blob(&vd[0], vd, &v[0],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, &v[0],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
-               c->status = ndr_push_struct_blob(&vd[1], vd, &v[1],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[1], vd, iconv_convenience, &v[1],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
-               c->status = ndr_push_struct_blob(&vd[2], vd, &v[2],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[2], vd, iconv_convenience, &v[2],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
                vs[0].blob              = &vd[0];
                vs[1].blob              = &vd[1];
@@ -1985,9 +2039,12 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                v[0].sid                = s->zero_sid;
                v[0].dn                 = s->forest.schema_dn_str;
 
-               c->status = ndr_push_struct_blob(&vd[0], vd, &v[0],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, &v[0],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
                vs[0].blob              = &vd[0];
 
@@ -2014,9 +2071,12 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                v[0].sid                = s->zero_sid;
                v[0].dn                 = s->domain.dn_str;
 
-               c->status = ndr_push_struct_blob(&vd[0], vd, &v[0],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, &v[0],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
                vs[0].blob              = &vd[0];
 
@@ -2041,7 +2101,7 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                vd[0] = data_blob_talloc(vd, NULL, 4);
                if (composite_nomem(vd[0].data, c)) return;
 
-               SIVAL(vd[0].data, 0, DS_BEHAVIOR_WIN2003);
+               SIVAL(vd[0].data, 0, DS_BEHAVIOR_WIN2008);
 
                vs[0].blob              = &vd[0];
 
@@ -2093,9 +2153,12 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                v[0].sid                = s->zero_sid;
                v[0].dn                 = s->dest_dsa.computer_dn_str;
 
-               c->status = ndr_push_struct_blob(&vd[0], vd, &v[0],
-                                                (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!composite_is_ok(c)) return;
+               ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, &v[0],
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       c->status = ndr_map_error2ntstatus(ndr_err);
+                       if (!composite_is_ok(c)) return;
+               }
 
                vs[0].blob              = &vd[0];
 
@@ -2112,11 +2175,15 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
        /* setup request structure */
        r->in.bind_handle                                               = &s->drsuapi1.bind_handle;
        r->in.level                                                     = 2;
-       r->in.req.req2.first_object.next_object                         = NULL;
-       r->in.req.req2.first_object.object.identifier                   = identifier;
-       r->in.req.req2.first_object.object.unknown1                     = 0x00000000;   
-       r->in.req.req2.first_object.object.attribute_ctr.num_attributes = num_attrs;
-       r->in.req.req2.first_object.object.attribute_ctr.attributes     = attrs;
+       r->in.req                                                       = talloc(s, union drsuapi_DsAddEntryRequest);
+       r->in.req->req2.first_object.next_object                        = NULL;
+       r->in.req->req2.first_object.object.identifier                  = identifier;
+       r->in.req->req2.first_object.object.flags                       = 0x00000000;
+       r->in.req->req2.first_object.object.attribute_ctr.num_attributes= num_attrs;
+       r->in.req->req2.first_object.object.attribute_ctr.attributes    = attrs;
+
+       r->out.level_out        = talloc(s, int32_t);
+       r->out.ctr              = talloc(s, union drsuapi_DsAddEntryCtr);
 
        req = dcerpc_drsuapi_DsAddEntry_send(s->drsuapi1.pipe, r, r);
        composite_continue_rpc(c, req, becomeDC_drsuapi1_add_entry_recv, s);
@@ -2151,37 +2218,37 @@ static void becomeDC_drsuapi1_add_entry_recv(struct rpc_request *req)
                return;
        }
 
-       if (r->out.level == 3) {
-               if (r->out.ctr.ctr3.count != 1) {
+       if (*r->out.level_out == 3) {
+               if (r->out.ctr->ctr3.count != 1) {
                        WERROR status;
 
-                       if (r->out.ctr.ctr3.level != 1) {
+                       if (r->out.ctr->ctr3.level != 1) {
                                composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
                                return;
                        }
 
-                       if (!r->out.ctr.ctr3.error) {
+                       if (!r->out.ctr->ctr3.error) {
                                composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
                                return;
                        }
 
-                       status = r->out.ctr.ctr3.error->info1.status;
+                       status = r->out.ctr->ctr3.error->info1.status;
 
-                       if (!r->out.ctr.ctr3.error->info1.info) {
+                       if (!r->out.ctr->ctr3.error->info1.info) {
                                composite_error(c, werror_to_ntstatus(status));
                                return;
                        }
 
                        /* see if we can get a more detailed error */
-                       switch (r->out.ctr.ctr3.error->info1.level) {
+                       switch (r->out.ctr->ctr3.error->info1.level) {
                        case 1:
-                               status = r->out.ctr.ctr3.error->info1.info->error1.status;
+                               status = r->out.ctr->ctr3.error->info1.info->error1.status;
                                break;
                        case 4:
                        case 5:
                        case 6:
                        case 7:
-                               status = r->out.ctr.ctr3.error->info1.info->errorX.status;
+                               status = r->out.ctr->ctr3.error->info1.info->errorX.status;
                                break;
                        }
 
@@ -2189,14 +2256,14 @@ static void becomeDC_drsuapi1_add_entry_recv(struct rpc_request *req)
                        return;
                }
 
-               s->dest_dsa.ntds_guid   = r->out.ctr.ctr3.objects[0].guid;
-       } else if (r->out.level == 2) {
-               if (r->out.ctr.ctr2.count != 1) {
-                       composite_error(c, werror_to_ntstatus(r->out.ctr.ctr2.error.status));
+               s->dest_dsa.ntds_guid   = r->out.ctr->ctr3.objects[0].guid;
+       } else if (*r->out.level_out == 2) {
+               if (r->out.ctr->ctr2.count != 1) {
+                       composite_error(c, werror_to_ntstatus(r->out.ctr->ctr2.error.status));
                        return;
                }
 
-               s->dest_dsa.ntds_guid   = r->out.ctr.ctr2.objects[0].guid;
+               s->dest_dsa.ntds_guid   = r->out.ctr->ctr2.objects[0].guid;
        } else {
                composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
                return;
@@ -2331,40 +2398,42 @@ static void becomeDC_drsuapi_pull_partition_send(struct libnet_BecomeDC_state *s
        r = talloc(s, struct drsuapi_DsGetNCChanges);
        if (composite_nomem(r, c)) return;
 
-       r->in.level = talloc(r, int32_t);
-       if (composite_nomem(r->in.level, c)) return;
-       r->out.level = talloc(r, int32_t);
-       if (composite_nomem(r->out.level, c)) return;
+       r->out.level_out = talloc(r, int32_t);
+       if (composite_nomem(r->out.level_out, c)) return;
+       r->in.req = talloc(r, union drsuapi_DsGetNCChangesRequest);
+       if (composite_nomem(r->in.req, c)) return;
+       r->out.ctr = talloc(r, union drsuapi_DsGetNCChangesCtr);
+       if (composite_nomem(r->out.ctr, c)) return;
 
        r->in.bind_handle       = &drsuapi_h->bind_handle;
        if (drsuapi_h->remote_info28.supported_extensions & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8) {
-               *r->in.level                            = 8;
-               r->in.req.req8.destination_dsa_guid     = partition->destination_dsa_guid;
-               r->in.req.req8.source_dsa_invocation_id = partition->source_dsa_invocation_id;
-               r->in.req.req8.naming_context           = &partition->nc;
-               r->in.req.req8.highwatermark            = partition->highwatermark;
-               r->in.req.req8.uptodateness_vector      = NULL;
-               r->in.req.req8.replica_flags            = partition->replica_flags;
-               r->in.req.req8.max_object_count         = 133;
-               r->in.req.req8.max_ndr_size             = 1336811;
-               r->in.req.req8.unknown4                 = 0;
-               r->in.req.req8.h1                       = 0;
-               r->in.req.req8.unique_ptr1              = 0;
-               r->in.req.req8.unique_ptr2              = 0;
-               r->in.req.req8.mapping_ctr.num_mappings = 0;
-               r->in.req.req8.mapping_ctr.mappings     = NULL;
+               r->in.level                             = 8;
+               r->in.req->req8.destination_dsa_guid    = partition->destination_dsa_guid;
+               r->in.req->req8.source_dsa_invocation_id= partition->source_dsa_invocation_id;
+               r->in.req->req8.naming_context          = &partition->nc;
+               r->in.req->req8.highwatermark           = partition->highwatermark;
+               r->in.req->req8.uptodateness_vector     = NULL;
+               r->in.req->req8.replica_flags           = partition->replica_flags;
+               r->in.req->req8.max_object_count        = 133;
+               r->in.req->req8.max_ndr_size            = 1336811;
+               r->in.req->req8.extended_op             = DRSUAPI_EXOP_NONE;
+               r->in.req->req8.fsmo_info               = 0;
+               r->in.req->req8.partial_attribute_set   = NULL;
+               r->in.req->req8.partial_attribute_set_ex= NULL;
+               r->in.req->req8.mapping_ctr.num_mappings= 0;
+               r->in.req->req8.mapping_ctr.mappings    = NULL;
        } else {
-               *r->in.level                            = 5;
-               r->in.req.req5.destination_dsa_guid     = partition->destination_dsa_guid;
-               r->in.req.req5.source_dsa_invocation_id = partition->source_dsa_invocation_id;
-               r->in.req.req5.naming_context           = &partition->nc;
-               r->in.req.req5.highwatermark            = partition->highwatermark;
-               r->in.req.req5.uptodateness_vector      = NULL;
-               r->in.req.req5.replica_flags            = partition->replica_flags;
-               r->in.req.req5.max_object_count         = 133;
-               r->in.req.req5.max_ndr_size             = 1336770;
-               r->in.req.req5.unknown4                 = 0;
-               r->in.req.req5.h1                       = 0;
+               r->in.level                             = 5;
+               r->in.req->req5.destination_dsa_guid    = partition->destination_dsa_guid;
+               r->in.req->req5.source_dsa_invocation_id= partition->source_dsa_invocation_id;
+               r->in.req->req5.naming_context          = &partition->nc;
+               r->in.req->req5.highwatermark           = partition->highwatermark;
+               r->in.req->req5.uptodateness_vector     = NULL;
+               r->in.req->req5.replica_flags           = partition->replica_flags;
+               r->in.req->req5.max_object_count        = 133;
+               r->in.req->req5.max_ndr_size            = 1336770;
+               r->in.req->req5.extended_op             = DRSUAPI_EXOP_NONE;
+               r->in.req->req5.fsmo_info               = 0;
        }
 
        /* 
@@ -2389,46 +2458,68 @@ static WERROR becomeDC_drsuapi_pull_partition_recv(struct libnet_BecomeDC_state
        struct GUID *source_dsa_guid;
        struct GUID *source_dsa_invocation_id;
        struct drsuapi_DsReplicaHighWaterMark *new_highwatermark;
+       bool more_data = false;
        NTSTATUS nt_status;
 
        if (!W_ERROR_IS_OK(r->out.result)) {
                return r->out.result;
        }
 
-       if (*r->out.level == 1) {
+       if (*r->out.level_out == 1) {
                ctr_level = 1;
-               ctr1 = &r->out.ctr.ctr1;
-       } else if (*r->out.level == 2) {
+               ctr1 = &r->out.ctr->ctr1;
+       } else if (*r->out.level_out == 2 &&
+                  r->out.ctr->ctr2.mszip1.ts) {
                ctr_level = 1;
-               ctr1 = r->out.ctr.ctr2.ctr.mszip1.ctr1;
-       } else if (*r->out.level == 6) {
+               ctr1 = &r->out.ctr->ctr2.mszip1.ts->ctr1;
+       } else if (*r->out.level_out == 6) {
+               ctr_level = 6;
+               ctr6 = &r->out.ctr->ctr6;
+       } else if (*r->out.level_out == 7 &&
+                  r->out.ctr->ctr7.level == 6 &&
+                  r->out.ctr->ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP &&
+                  r->out.ctr->ctr7.ctr.mszip6.ts) {
                ctr_level = 6;
-               ctr6 = &r->out.ctr.ctr6;
-       } else if (*r->out.level == 7 &&
-                  r->out.ctr.ctr7.level == 6 &&
-                  r->out.ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP) {
+               ctr6 = &r->out.ctr->ctr7.ctr.mszip6.ts->ctr6;
+       } else if (*r->out.level_out == 7 &&
+                  r->out.ctr->ctr7.level == 6 &&
+                  r->out.ctr->ctr7.type == DRSUAPI_COMPRESSION_TYPE_XPRESS &&
+                  r->out.ctr->ctr7.ctr.xpress6.ts) {
                ctr_level = 6;
-               ctr6 = r->out.ctr.ctr7.ctr.mszip6.ctr6;
+               ctr6 = &r->out.ctr->ctr7.ctr.xpress6.ts->ctr6;
        } else {
                return WERR_BAD_NET_RESP;
        }
 
+       if (!ctr1 && ! ctr6) {
+               return WERR_BAD_NET_RESP;
+       }
+
+       if (ctr_level == 6) {
+               if (!W_ERROR_IS_OK(ctr6->drs_error)) {
+                       return ctr6->drs_error;
+               }
+       }
+
        switch (ctr_level) {
        case 1:
                source_dsa_guid                 = &ctr1->source_dsa_guid;
                source_dsa_invocation_id        = &ctr1->source_dsa_invocation_id;
                new_highwatermark               = &ctr1->new_highwatermark;
+               more_data                       = ctr1->more_data;
                break;
        case 6:
                source_dsa_guid                 = &ctr6->source_dsa_guid;
                source_dsa_invocation_id        = &ctr6->source_dsa_invocation_id;
                new_highwatermark               = &ctr6->new_highwatermark;
+               more_data                       = ctr6->more_data;
                break;
        }
 
        partition->highwatermark                = *new_highwatermark;
        partition->source_dsa_guid              = *source_dsa_guid;
        partition->source_dsa_invocation_id     = *source_dsa_invocation_id;
+       partition->more_data                    = more_data;
 
        if (!partition->store_chunk) return WERR_OK;
 
@@ -2509,7 +2600,7 @@ static void becomeDC_drsuapi3_pull_schema_recv(struct rpc_request *req)
 
        talloc_free(r);
 
-       if (s->schema_part.highwatermark.tmp_highest_usn > s->schema_part.highwatermark.highest_usn) {
+       if (s->schema_part.more_data) {
                becomeDC_drsuapi_pull_partition_send(s, &s->drsuapi2, &s->drsuapi3, &s->schema_part,
                                                     becomeDC_drsuapi3_pull_schema_recv);
                return;
@@ -2571,7 +2662,7 @@ static void becomeDC_drsuapi3_pull_config_recv(struct rpc_request *req)
 
        talloc_free(r);
 
-       if (s->config_part.highwatermark.tmp_highest_usn > s->config_part.highwatermark.highest_usn) {
+       if (s->config_part.more_data) {
                becomeDC_drsuapi_pull_partition_send(s, &s->drsuapi2, &s->drsuapi3, &s->config_part,
                                                     becomeDC_drsuapi3_pull_config_recv);
                return;
@@ -2638,7 +2729,7 @@ static void becomeDC_drsuapi3_pull_domain_recv(struct rpc_request *req)
 
        talloc_free(r);
 
-       if (s->domain_part.highwatermark.tmp_highest_usn > s->domain_part.highwatermark.highest_usn) {
+       if (s->domain_part.more_data) {
                becomeDC_drsuapi_pull_partition_send(s, &s->drsuapi2, &s->drsuapi3, &s->domain_part,
                                                     becomeDC_drsuapi3_pull_domain_recv);
                return;
@@ -2677,7 +2768,7 @@ static void becomeDC_drsuapi_update_refs_send(struct libnet_BecomeDC_state *s,
        r->in.req.req1.dest_dsa_guid    = s->dest_dsa.ntds_guid;
        r->in.req.req1.options          = DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE
                                        | DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE
-                                       | DRSUAPI_DS_REPLICA_UPDATE_0x00000010;
+                                       | DRSUAPI_DS_REPLICA_UPDATE_WRITEABLE;
 
        req = dcerpc_drsuapi_DsReplicaUpdateRefs_send(drsuapi->pipe, r, r);
        composite_continue_rpc(c, req, recv_fn, s);
@@ -2820,8 +2911,8 @@ static NTSTATUS becomeDC_ldap2_move_computer(struct libnet_BecomeDC_state *s)
                                s->domain.dn_str);
        NT_STATUS_HAVE_NO_MEMORY(basedn);
 
-       ret = ldb_search(s->ldap2.ldb, basedn, LDB_SCOPE_BASE,
-                        "(objectClass=*)", _1_1_attrs, &r);
+       ret = ldb_search(s->ldap2.ldb, s, &r, basedn, LDB_SCOPE_BASE,
+                        _1_1_attrs, "(objectClass=*)");
        talloc_free(basedn);
        if (ret != LDB_SUCCESS) {
                return NT_STATUS_LDAP(ret);
@@ -2910,7 +3001,7 @@ struct composite_context *libnet_BecomeDC_send(struct libnet_context *ctx, TALLO
        /* Destination DSA dns_name construction */
        tmp_name        = strlower_talloc(s, s->dest_dsa.netbios_name);
        if (composite_nomem(tmp_name, c)) return c;
-       tmp_name        = talloc_asprintf_append(tmp_name, ".%s",s->domain.dns_name);
+       tmp_name        = talloc_asprintf_append_buffer(tmp_name, ".%s",s->domain.dns_name);
        if (composite_nomem(tmp_name, c)) return c;
        s->dest_dsa.dns_name    = tmp_name;