NET-API-BECOME-DC: resolve the host name to an address before calling
[metze/samba/wip.git] / source4 / torture / libnet / libnet_BecomeDC.c
index 0555e4b74b15d109db4231af64c2a73d0b6ca26d..d969caccc25bf6a9fdfbd04d7161491b904f3a64 100644 (file)
@@ -3,11 +3,11 @@
 
    libnet_BecomeDC() tests
 
-   Copyright (C) Stefan (metze) Metzmacher 2006
+   Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
    
    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,
    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 "lib/cmdline/popt_common.h"
-#include "torture/torture.h"
 #include "torture/rpc/rpc.h"
 #include "libnet/libnet.h"
-#include "lib/events/events.h"
 #include "dsdb/samdb/samdb.h"
-#include "lib/util/dlinklist.h"
-#include "lib/ldb/include/ldb.h"
-#include "lib/ldb/include/ldb_errors.h"
-#include "librpc/ndr/libndr.h"
+#include "../lib/util/dlinklist.h"
 #include "librpc/gen_ndr/ndr_drsuapi.h"
 #include "librpc/gen_ndr/ndr_drsblobs.h"
-#include "librpc/gen_ndr/ndr_misc.h"
 #include "system/time.h"
+#include "lib/ldb_wrap.h"
 #include "auth/auth.h"
-#include "lib/db_wrap.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/appweb/ejs/ejsInternal.h"
-#include "scripting/ejs/smbcalls.h"
-
-static EjsId eid;
-static int ejs_error;
-
-static void test_ejs_exception(const char *reason)
-{
-       Ejs *ep = ejsPtr(eid);
-       ejsSetErrorMsg(eid, "%s", reason);
-       fprintf(stderr, "%s", ep->error);
-       ejs_error = 127;
-}
-
-static int test_run_ejs(char *script)
-{
-       EjsHandle handle = 0;
-       MprVar result;
-       char *emsg;
-       TALLOC_CTX *mem_ctx = talloc_new(NULL);
-       struct MprVar *return_var;
-
-       mprSetCtx(mem_ctx);
-
-       if (ejsOpen(NULL, NULL, NULL) != 0) {
-               d_printf("ejsOpen(): unable to initialise EJS subsystem\n");
-               ejs_error = 127;
-               goto failed;
-       }
-
-       smb_setup_ejs_functions(test_ejs_exception);
-
-       if ((eid = ejsOpenEngine(handle, 0)) == (EjsId)-1) {
-               d_printf("smbscript: ejsOpenEngine(): unable to initialise an EJS engine\n");
-               ejs_error = 127;
-               goto failed;
-       }
-
-       mprSetVar(ejsGetGlobalObject(eid), "ARGV", mprList("ARGV", NULL));
-
-       /* run the script */
-       if (ejsEvalScript(eid, script, &result, &emsg) == -1) {
-               d_printf("smbscript: ejsEvalScript(): %s\n", emsg);
-               if (ejs_error == 0) ejs_error = 127;
-               goto failed;
-       }
-
-       return_var = ejsGetReturnValue(eid);
-       ejs_error = mprVarToNumber(return_var);
-
-failed:
-       ejsClose();
-       talloc_free(mem_ctx);
-       return ejs_error;
-}
-
-#define TORTURE_NETBIOS_NAME "smbtorturedc"
-#define TORTURE_SAMDB_LDB "test_samdb.ldb"
-#define TORTURE_SECRETS_LDB "test_secrets.ldb"
-#define TORTURE_SECRETS_KEYTAB "test_secrets.keytab"
+#include "param/param.h"
+#include "param/provision.h"
+#include "libcli/resolve/resolve.h"
 
 struct test_become_dc_state {
        struct libnet_context *ctx;
+       struct torture_context *tctx;
+       const char *netbios_name;
        struct test_join *tj;
        struct cli_credentials *machine_account;
        struct dsdb_schema *self_made_schema;
@@ -114,13 +51,50 @@ struct test_become_dc_state {
                struct drsuapi_DsReplicaObjectListItemEx *last_object;
        } schema_part;
 
-       const char *computer_dn;
+       const char *targetdir;
+
+       struct loadparm_context *lp_ctx;
 };
 
+static NTSTATUS test_become_dc_prepare_db(void *private_data,
+                                             const struct libnet_BecomeDC_PrepareDB *p)
+{
+       struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
+       struct provision_settings settings;
+       struct provision_result result;
+       NTSTATUS status;
+
+       settings.site_name = p->dest_dsa->site_name;
+       settings.root_dn_str = p->forest->root_dn_str;
+       settings.domain_dn_str = p->domain->dn_str;
+       settings.config_dn_str = p->forest->config_dn_str;
+       settings.schema_dn_str = p->forest->schema_dn_str;
+       settings.server_dn_str = torture_join_server_dn_str(s->tj);
+       settings.invocation_id = &p->dest_dsa->invocation_id;
+       settings.netbios_name = p->dest_dsa->netbios_name;
+       settings.host_ip = NULL;
+       settings.realm = torture_join_dom_dns_name(s->tj);
+       settings.domain = torture_join_dom_netbios_name(s->tj);
+       settings.ntds_dn_str = p->dest_dsa->ntds_dn_str;
+       settings.machine_password = cli_credentials_get_password(s->machine_account);
+       settings.targetdir = s->targetdir;
+
+       status = provision_bare(s, s->lp_ctx, &settings, &result);
+       
+       s->ldb = result.samdb;
+       s->lp_ctx = result.lp_ctx;
+        return NT_STATUS_OK;
+
+
+}
+
 static NTSTATUS test_become_dc_check_options(void *private_data,
                                             const struct libnet_BecomeDC_CheckOptions *o)
 {
-       DEBUG(0,("Become DC of Domain[%s]/[%s]\n",
+       struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
+
+       DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n",
+               s->netbios_name,
                o->domain->netbios_name, o->domain->dns_name));
 
        DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n",
@@ -138,137 +112,11 @@ static NTSTATUS test_become_dc_check_options(void *private_data,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS test_become_dc_prepare_db(void *private_data,
-                                         const struct libnet_BecomeDC_PrepareDB *p)
-{
-       struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
-       char *ejs;
-       int ret;
-       bool ok;
-
-       DEBUG(0,("New Server[%s] in Site[%s]\n",
-               p->dest_dsa->dns_name, p->dest_dsa->site_name));
-
-       DEBUG(0,("DSA Instance [%s]\n"
-               "\tobjectGUID[%s]\n"
-               "\tinvocationId[%s]\n",
-               p->dest_dsa->ntds_dn_str,
-               GUID_string(s, &p->dest_dsa->ntds_guid),
-               GUID_string(s, &p->dest_dsa->invocation_id)));
-
-       DEBUG(0,("Schema Partition[%s]\n",
-               p->forest->schema_dn_str));
-
-       DEBUG(0,("Config Partition[%s]\n",
-               p->forest->config_dn_str));
-
-       DEBUG(0,("Domain Partition[%s]\n",
-               p->domain->dn_str));
-
-       ejs = talloc_asprintf(s,
-               "libinclude(\"base.js\");\n"
-               "libinclude(\"provision.js\");\n"
-               "\n"
-               "function message() { print(vsprintf(arguments)); }\n"
-               "\n"
-               "var subobj = provision_guess();\n"
-               "subobj.ROOTDN       = \"%s\";\n"
-               "subobj.DOMAINDN     = \"%s\";\n"
-               "subobj.DOMAINDN_LDB = \"test_domain.ldb\";\n"
-               "subobj.CONFIGDN     = \"%s\";\n"
-               "subobj.CONFIGDN_LDB = \"test_config.ldb\";\n"
-               "subobj.SCHEMADN     = \"%s\";\n"
-               "subobj.SCHEMADN_LDB = \"test_schema.ldb\";\n"
-               "subobj.HOSTNAME     = \"%s\";\n"
-               "subobj.DNSNAME      = \"%s\";\n"
-               "subobj.DEFAULTSITE  = \"%s\";\n"
-               "\n"
-               "modules_list        = new Array(\"rootdse\",\n"
-               "                                \"kludge_acl\",\n"
-               "                                \"paged_results\",\n"
-               "                                \"server_sort\",\n"
-               "                                \"extended_dn\",\n"
-               "                                \"asq\",\n"
-               "                                \"samldb\",\n"
-               "                                \"operational\",\n"
-               "                                \"objectclass\",\n"
-               "                                \"rdn_name\",\n"
-               "                                \"show_deleted\",\n"
-               "                                \"partition\");\n"
-               "subobj.MODULES_LIST = join(\",\", modules_list);\n"
-               "subobj.DOMAINDN_MOD = \"pdc_fsmo,password_hash,repl_meta_data\";\n"
-               "subobj.CONFIGDN_MOD = \"naming_fsmo,repl_meta_data\";\n"
-               "subobj.SCHEMADN_MOD = \"schema_fsmo,repl_meta_data\";\n"
-               "\n"
-               "subobj.KRBTGTPASS   = \"test\";\n"
-               "subobj.MACHINEPASS  = \"test\";\n"
-               "subobj.ADMINPASS    = \"test\";\n"
-               "\n"
-               "var paths = provision_default_paths(subobj);\n"
-               "paths.samdb = \"%s\";\n"
-               "paths.secrets = \"%s\";\n"
-               "paths.keytab = \"%s\";\n"
-               "\n"
-               "var system_session = system_session();\n"
-               "\n"
-               "var ok = provision_become_dc(subobj, message, paths, system_session);\n"
-               "assert(ok);\n"
-               "\n"
-               "return 0;\n",
-               p->forest->root_dn_str,         /* subobj.ROOTDN */
-               p->domain->dn_str,              /* subobj.DOMAINDN */
-               p->forest->config_dn_str,       /* subobj.CONFIGDN */
-               p->forest->schema_dn_str,       /* subobj.SCHEMADN */
-               p->dest_dsa->netbios_name,      /* subobj.HOSTNAME */
-               p->dest_dsa->dns_name,          /* subobj.DNSNAME */
-               p->dest_dsa->site_name,         /* subobj.DEFAULTSITE */
-               TORTURE_SAMDB_LDB,              /* paths.samdb */
-               TORTURE_SECRETS_LDB,            /* paths.secrets */
-               TORTURE_SECRETS_KEYTAB);        /* paths.keytab */
-       NT_STATUS_HAVE_NO_MEMORY(ejs);
-
-       ret = test_run_ejs(ejs);
-       if (ret != 0) {
-               DEBUG(0,("Failed to run ejs script: %d:\n%s",
-                       ret, ejs));
-               talloc_free(ejs);
-               return NT_STATUS_FOOBAR;
-       }
-       talloc_free(ejs);
-
-       talloc_free(s->ldb);
-
-       DEBUG(0,("Open the SAM LDB with system credentials: %s\n", TORTURE_SAMDB_LDB));
-
-       s->ldb = ldb_wrap_connect(s, TORTURE_SAMDB_LDB,
-                                 system_session(s),
-                                 NULL, 0, NULL);
-       if (!s->ldb) {
-               DEBUG(0,("Failed to open '%s'\n",
-                       TORTURE_SAMDB_LDB));
-               return NT_STATUS_INTERNAL_DB_ERROR;
-       }
-
-       ok = samdb_set_ntds_invocation_id(s->ldb, &p->dest_dsa->invocation_id);
-       if (!ok) {
-               DEBUG(0,("Failed to set cached ntds invocationId\n"));
-               return NT_STATUS_FOOBAR;
-       }
-       ok = samdb_set_ntds_objectGUID(s->ldb, &p->dest_dsa->ntds_guid);
-       if (!ok) {
-               DEBUG(0,("Failed to set cached ntds objectGUID\n"));
-               return NT_STATUS_FOOBAR;
-       }
-
-       return NT_STATUS_OK;
-}
-
 static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
                                  const struct libnet_BecomeDC_StoreChunk *c)
 {
        WERROR status;
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
-       uint32_t total_object_count;
        uint32_t object_count;
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
        struct drsuapi_DsReplicaObjectListItemEx *cur;
@@ -282,9 +130,11 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
        struct ldb_val prefixMap_val;
        struct ldb_message_element *prefixMap_el;
        struct ldb_val schemaInfo_val;
+       char *sam_ldb_path;
        uint32_t i;
        int ret;
        bool ok;
+       uint64_t seq_num;
 
        DEBUG(0,("Analyze and apply schema objects\n"));
 
@@ -296,7 +146,6 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
        switch (c->ctr_level) {
        case 1:
                mapping_ctr                     = &c->ctr1->mapping_ctr;
-               total_object_count              = c->ctr1->total_object_count;
                object_count                    = s->schema_part.object_count;
                first_object                    = s->schema_part.first_object;
                linked_attributes_count         = 0;
@@ -308,7 +157,6 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
                break;
        case 6:
                mapping_ctr                     = &c->ctr6->mapping_ctr;
-               total_object_count              = c->ctr6->total_object_count;
                object_count                    = s->schema_part.object_count;
                first_object                    = s->schema_part.first_object;
                linked_attributes_count         = 0; /* TODO: ! */
@@ -329,7 +177,7 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
 
        tmp_dns_name    = GUID_string(s_dsa->other_info, &s_dsa->source_dsa_obj_guid);
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
-       tmp_dns_name    = talloc_asprintf_append(tmp_dns_name, "._msdcs.%s", c->forest->dns_name);
+       tmp_dns_name    = talloc_asprintf_append_buffer(tmp_dns_name, "._msdcs.%s", c->forest->dns_name);
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
        s_dsa->other_info->dns_name = tmp_dns_name;
 
@@ -343,7 +191,8 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
                        const char *oid = NULL;
 
                        a = &cur->object.attribute_ctr.attributes[i];
-                       status = dsdb_map_int2oid(s->self_made_schema, a->attid, s, &oid);
+                       status = dsdb_schema_pfm_oid_from_attid(s->self_made_schema->prefixmap,
+                                                               a->attid, s, &oid);
                        if (!W_ERROR_IS_OK(status)) {
                                return werror_to_ntstatus(status);
                        }
@@ -378,7 +227,7 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
                        sa = talloc_zero(s->self_made_schema, struct dsdb_attribute);
                        NT_STATUS_HAVE_NO_MEMORY(sa);
 
-                       status = dsdb_attribute_from_drsuapi(s->self_made_schema, &cur->object, s, sa);
+                       status = dsdb_attribute_from_drsuapi(s->ldb, s->self_made_schema, &cur->object, s, sa);
                        if (!W_ERROR_IS_OK(status)) {
                                return werror_to_ntstatus(status);
                        }
@@ -419,13 +268,14 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
                                                         linked_attributes,
                                                         s_dsa,
                                                         uptodateness_vector,
-                                                        s, &objs);
+                                                        c->gensec_skey,
+                                                        s, &objs, &seq_num);
        if (!W_ERROR_IS_OK(status)) {
                DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
                return werror_to_ntstatus(status);
        }
 
-       if (lp_parm_bool(-1, "become dc", "dump objects", False)) {
+       if (lp_parm_bool(s->tctx->lp_ctx, NULL, "become dc", "dump objects", false)) {
                for (i=0; i < objs->num_objects; i++) {
                        struct ldb_ldif ldif;
                        fprintf(stdout, "#\n");
@@ -466,13 +316,14 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
        talloc_free(s->ldb); /* this also free's the s->schema, because dsdb_set_schema() steals it */
        s->schema = NULL;
 
-       DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema: %s\n", TORTURE_SAMDB_LDB));
-       s->ldb = ldb_wrap_connect(s, TORTURE_SAMDB_LDB,
-                                 system_session(s),
-                                 NULL, 0, NULL);
+       sam_ldb_path = talloc_asprintf(s, "%s/%s", s->targetdir, "private/sam.ldb");
+       DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema: %s\n", sam_ldb_path));
+       s->ldb = ldb_wrap_connect(s, s->tctx->ev, s->tctx->lp_ctx, sam_ldb_path,
+                                 system_session(s->tctx->lp_ctx),
+                                 NULL, 0);
        if (!s->ldb) {
                DEBUG(0,("Failed to open '%s'\n",
-                       TORTURE_SAMDB_LDB));
+                       sam_ldb_path));
                return NT_STATUS_INTERNAL_DB_ERROR;
        }
 
@@ -502,48 +353,56 @@ static NTSTATUS test_become_dc_schema_chunk(void *private_data,
        struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
        WERROR status;
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
-       uint32_t total_object_count;
+       uint32_t nc_object_count;
        uint32_t object_count;
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
        struct drsuapi_DsReplicaObjectListItemEx *cur;
+       uint32_t nc_linked_attributes_count;
+       uint32_t linked_attributes_count;
 
        switch (c->ctr_level) {
        case 1:
-               mapping_ctr             = &c->ctr1->mapping_ctr;
-               total_object_count      = c->ctr1->total_object_count;
-               object_count            = c->ctr1->object_count;
-               first_object            = c->ctr1->first_object;
+               mapping_ctr                     = &c->ctr1->mapping_ctr;
+               nc_object_count                 = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */
+               object_count                    = c->ctr1->object_count;
+               first_object                    = c->ctr1->first_object;
+               nc_linked_attributes_count      = 0;
+               linked_attributes_count         = 0;
                break;
        case 6:
-               mapping_ctr             = &c->ctr6->mapping_ctr;
-               total_object_count      = c->ctr6->total_object_count;
-               object_count            = c->ctr6->object_count;
-               first_object            = c->ctr6->first_object;
+               mapping_ctr                     = &c->ctr6->mapping_ctr;
+               nc_object_count                 = c->ctr6->nc_object_count;
+               object_count                    = c->ctr6->object_count;
+               first_object                    = c->ctr6->first_object;
+               nc_linked_attributes_count      = c->ctr6->nc_linked_attributes_count;
+               linked_attributes_count         = c->ctr6->linked_attributes_count;
                break;
        default:
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (total_object_count) {
-               DEBUG(0,("Schema-DN[%s] objects[%u/%u]\n",
-                       c->partition->nc.dn, object_count, total_object_count));
+       if (nc_object_count) {
+               DEBUG(0,("Schema-DN[%s] objects[%u/%u] linked_values[%u/%u]\n",
+                       c->partition->nc.dn, object_count, nc_object_count,
+                       linked_attributes_count, nc_linked_attributes_count));
        } else {
-               DEBUG(0,("Schema-DN[%s] objects[%u]\n",
-               c->partition->nc.dn, object_count));
+               DEBUG(0,("Schema-DN[%s] objects[%u] linked_values[%u\n",
+               c->partition->nc.dn, object_count, linked_attributes_count));
        }
 
        if (!s->schema) {
-               s->self_made_schema = talloc_zero(s, struct dsdb_schema);
+               s->self_made_schema = dsdb_new_schema(s, lp_iconv_convenience(s->lp_ctx));
+
                NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema);
 
-               status = dsdb_load_oid_mappings_drsuapi(s->self_made_schema, mapping_ctr);
+               status = dsdb_load_prefixmap_from_drsuapi(s->self_made_schema, mapping_ctr);
                if (!W_ERROR_IS_OK(status)) {
                        return werror_to_ntstatus(status);
                }
 
                s->schema = s->self_made_schema;
        } else {
-               status = dsdb_verify_oid_mappings_drsuapi(s->schema, mapping_ctr);
+               status = dsdb_schema_pfm_contains_drsuapi_pfm(s->schema->prefixmap, mapping_ctr);
                if (!W_ERROR_IS_OK(status)) {
                        return werror_to_ntstatus(status);
                }
@@ -560,7 +419,7 @@ static NTSTATUS test_become_dc_schema_chunk(void *private_data,
        for (cur = first_object; cur->next_object; cur = cur->next_object) {}
        s->schema_part.last_object = cur;
 
-       if (c->partition->highwatermark.tmp_highest_usn == c->partition->highwatermark.highest_usn) {
+       if (!c->partition->more_data) {
                return test_apply_schema(s, c);
        }
 
@@ -573,9 +432,10 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
        struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
        WERROR status;
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
-       uint32_t total_object_count;
+       uint32_t nc_object_count;
        uint32_t object_count;
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
+       uint32_t nc_linked_attributes_count;
        uint32_t linked_attributes_count;
        struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
        const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector;
@@ -583,6 +443,7 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
        struct repsFromTo1 *s_dsa;
        char *tmp_dns_name;
        uint32_t i;
+       uint64_t seq_num;
 
        s_dsa                   = talloc_zero(s, struct repsFromTo1);
        NT_STATUS_HAVE_NO_MEMORY(s_dsa);
@@ -592,9 +453,10 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
        switch (c->ctr_level) {
        case 1:
                mapping_ctr                     = &c->ctr1->mapping_ctr;
-               total_object_count              = c->ctr1->total_object_count;
+               nc_object_count                 = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */
                object_count                    = c->ctr1->object_count;
                first_object                    = c->ctr1->first_object;
+               nc_linked_attributes_count      = 0;
                linked_attributes_count         = 0;
                linked_attributes               = NULL;
                s_dsa->highwatermark            = c->ctr1->new_highwatermark;
@@ -604,9 +466,10 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
                break;
        case 6:
                mapping_ctr                     = &c->ctr6->mapping_ctr;
-               total_object_count              = c->ctr6->total_object_count;
+               nc_object_count                 = c->ctr6->nc_object_count;
                object_count                    = c->ctr6->object_count;
                first_object                    = c->ctr6->first_object;
+               nc_linked_attributes_count      = c->ctr6->nc_linked_attributes_count;
                linked_attributes_count         = c->ctr6->linked_attributes_count;
                linked_attributes               = c->ctr6->linked_attributes;
                s_dsa->highwatermark            = c->ctr6->new_highwatermark;
@@ -625,16 +488,17 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
 
        tmp_dns_name    = GUID_string(s_dsa->other_info, &s_dsa->source_dsa_obj_guid);
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
-       tmp_dns_name    = talloc_asprintf_append(tmp_dns_name, "._msdcs.%s", c->forest->dns_name);
+       tmp_dns_name    = talloc_asprintf_append_buffer(tmp_dns_name, "._msdcs.%s", c->forest->dns_name);
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
        s_dsa->other_info->dns_name = tmp_dns_name;
 
-       if (total_object_count) {
-               DEBUG(0,("Partition[%s] objects[%u/%u]\n",
-                       c->partition->nc.dn, object_count, total_object_count));
+       if (nc_object_count) {
+               DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n",
+                       c->partition->nc.dn, object_count, nc_object_count,
+                       linked_attributes_count, nc_linked_attributes_count));
        } else {
-               DEBUG(0,("Partition[%s] objects[%u]\n",
-               c->partition->nc.dn, object_count));
+               DEBUG(0,("Partition[%s] objects[%u] linked_values[%u\n",
+               c->partition->nc.dn, object_count, linked_attributes_count));
        }
 
        status = dsdb_extended_replicated_objects_commit(s->ldb,
@@ -646,13 +510,14 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
                                                         linked_attributes,
                                                         s_dsa,
                                                         uptodateness_vector,
-                                                        s, &objs);
+                                                        c->gensec_skey,
+                                                        s, &objs, &seq_num);
        if (!W_ERROR_IS_OK(status)) {
                DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
                return werror_to_ntstatus(status);
        }
 
-       if (lp_parm_bool(-1, "become dc", "dump objects", False)) {
+       if (lp_parm_bool(s->tctx->lp_ctx, NULL, "become dc", "dump objects", false)) {
                for (i=0; i < objs->num_objects; i++) {
                        struct ldb_ldif ldif;
                        fprintf(stdout, "#\n");
@@ -682,7 +547,7 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
                        return NT_STATUS_FOOBAR;
                }
 
-               if (lp_parm_bool(-1, "become dc", "dump objects", False)) {
+               if (lp_parm_bool(s->tctx->lp_ctx, NULL, "become dc", "dump objects", false)) {
                        DEBUG(0,("# %s\n", sa->lDAPDisplayName));
                        NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute, &linked_attributes[i]);
                        dump_data(0,
@@ -694,159 +559,101 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS test_become_dc_domain_chunk(void *private_data,
-                                          const struct libnet_BecomeDC_StoreChunk *c)
-{
-       struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
-
-       s->computer_dn = talloc_strdup(s, c->dest_dsa->computer_dn_str);
-       NT_STATUS_HAVE_NO_MEMORY(s->computer_dn);
-
-       return test_become_dc_store_chunk(private_data, c);
-}
-
-static BOOL test_become_dc_set_test_passwords(struct test_become_dc_state *s)
+bool torture_net_become_dc(struct torture_context *torture)
 {
+       bool ret = true;
+       NTSTATUS status;
+       struct libnet_BecomeDC b;
+       struct libnet_UnbecomeDC u;
+       struct test_become_dc_state *s;
        struct ldb_message *msg;
-       int ret;
-
-       printf("Set up \"test\" as password for the krbtgt, machine and administrator accounts\n");
-
-       /*
-        * first krbtgt password
-        */
-       msg = ldb_msg_new(s);
-       if (!msg) return False;
-
-       msg->dn = ldb_dn_new_fmt(msg, s->ldb, "CN=krbtgt,CN=Users,%s",
-                                ldb_dn_get_linearized(samdb_base_dn(s->ldb)));
-       if (!msg) return False;
+       int ldb_ret;
+       uint32_t i;
+       char *sam_ldb_path;
+       const char *address;
+       struct nbt_name name;
 
-       ret = ldb_msg_add_string(msg, "sambaPassword", "test");
-       if (ret != LDB_SUCCESS) return False;
+       char *location = NULL;
+       torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location), 
+                                  "torture_temp_dir should return NT_STATUS_OK" );
 
-       ret = samdb_replace(s->ldb, s, msg);
-       if (ret != LDB_SUCCESS) {
-               printf("failed to replace sambaPassword for '%s': %s\n",
-                      ldb_dn_get_linearized(msg->dn),
-                      ldb_strerror(ret));
-               return False;
-       }
-       talloc_free(msg);
-
-       /*
-        * our machine account password
-        */
-       msg = ldb_msg_new(s);
-       if (!msg) return False;
+       s = talloc_zero(torture, struct test_become_dc_state);
+       if (!s) return false;
 
-       msg->dn = ldb_dn_new(msg, s->ldb, s->computer_dn);
-       if (!msg) return False;
+       s->tctx = torture;
+       s->lp_ctx = torture->lp_ctx;
 
-       ret = ldb_msg_add_string(msg, "sambaPassword", "test");
-       if (ret != LDB_SUCCESS) return False;
+       make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));
 
-       ret = samdb_replace(s->ldb, s, msg);
-       if (ret != LDB_SUCCESS) {
-               printf("failed to replace sambaPassword for '%s': %s\n",
-                      ldb_dn_get_linearized(msg->dn),
-                      ldb_strerror(ret));
-               return False;
+       /* do an initial name resolution to find its IP */
+       status = resolve_name(lp_resolve_context(torture->lp_ctx),
+                             &name, torture, &address, torture->ev);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to resolve %s - %s\n",
+                      name.name, nt_errstr(status));
+               return false;
        }
-       talloc_free(msg);
-
-       /*
-        * the Administrator account password
-        */
-       msg = ldb_msg_new(s);
-       if (!msg) return False;
-
-       msg->dn = ldb_dn_new_fmt(msg, s->ldb, "CN=Administrator,CN=Users,%s",
-                                ldb_dn_get_linearized(samdb_base_dn(s->ldb)));
-       if (!msg) return False;
-
-       ret = ldb_msg_add_string(msg, "sambaPassword", "test");
-       if (ret != LDB_SUCCESS) return False;
 
-       ret = samdb_replace(s->ldb, s, msg);
-       if (ret != LDB_SUCCESS) {
-               printf("failed to replace sambaPassword for '%s': %s\n",
-                      ldb_dn_get_linearized(msg->dn),
-                      ldb_strerror(ret));
-               return False;
+       s->netbios_name = lp_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
+       if (!s->netbios_name || !s->netbios_name[0]) {
+               s->netbios_name = "smbtorturedc";
        }
-       talloc_free(msg);
-
-       return True;
-}
-
-BOOL torture_net_become_dc(struct torture_context *torture)
-{
-       BOOL ret = True;
-       NTSTATUS status;
-       struct libnet_BecomeDC b;
-       struct libnet_UnbecomeDC u;
-       struct test_become_dc_state *s;
-       struct ldb_message *msg;
-       int ldb_ret;
-       uint32_t i;
 
-       s = talloc_zero(torture, struct test_become_dc_state);
-       if (!s) return False;
+       s->targetdir = location;
 
        /* Join domain as a member server. */
-       s->tj = torture_join_domain(TORTURE_NETBIOS_NAME,
+       s->tj = torture_join_domain(torture, s->netbios_name,
                                 ACB_WSTRUST,
                                 &s->machine_account);
        if (!s->tj) {
                DEBUG(0, ("%s failed to join domain as workstation\n",
-                         TORTURE_NETBIOS_NAME));
-               return False;
+                         s->netbios_name));
+               return false;
        }
 
-       s->ctx = libnet_context_init(event_context_init(s));
+       s->ctx = libnet_context_init(torture->ev, torture->lp_ctx);
        s->ctx->cred = cmdline_credentials;
 
-       s->ldb = ldb_init(s);
+       s->ldb = ldb_init(s, torture->ev);
 
        ZERO_STRUCT(b);
        b.in.domain_dns_name            = torture_join_dom_dns_name(s->tj);
        b.in.domain_netbios_name        = torture_join_dom_netbios_name(s->tj);
        b.in.domain_sid                 = torture_join_sid(s->tj);
-       b.in.source_dsa_address         = lp_parm_string(-1, "torture", "host");
-       b.in.dest_dsa_netbios_name      = TORTURE_NETBIOS_NAME;
+       b.in.source_dsa_address         = address;
+       b.in.dest_dsa_netbios_name      = s->netbios_name;
 
        b.in.callbacks.private_data     = s;
        b.in.callbacks.check_options    = test_become_dc_check_options;
-       b.in.callbacks.prepare_db       = test_become_dc_prepare_db;
+       b.in.callbacks.prepare_db = test_become_dc_prepare_db;
        b.in.callbacks.schema_chunk     = test_become_dc_schema_chunk;
        b.in.callbacks.config_chunk     = test_become_dc_store_chunk;
-       b.in.callbacks.domain_chunk     = test_become_dc_domain_chunk;
+       b.in.callbacks.domain_chunk     = test_become_dc_store_chunk;
 
        status = libnet_BecomeDC(s->ctx, s, &b);
        if (!NT_STATUS_IS_OK(status)) {
                printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status));
-               ret = False;
+               ret = false;
                goto cleanup;
        }
 
        msg = ldb_msg_new(s);
        if (!msg) {
                printf("ldb_msg_new() failed\n");
-               ret = False;
+               ret = false;
                goto cleanup;
        }
-       msg->dn = ldb_dn_new(msg, s->ldb, "cn=ROOTDSE");
+       msg->dn = ldb_dn_new(msg, s->ldb, "@ROOTDSE");
        if (!msg->dn) {
-               printf("ldb_msg_new(cn=ROOTDSE) failed\n");
-               ret = False;
+               printf("ldb_msg_new(@ROOTDSE) failed\n");
+               ret = false;
                goto cleanup;
        }
 
        ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
        if (ldb_ret != LDB_SUCCESS) {
                printf("ldb_msg_add_string(msg, isSynchronized, TRUE) failed: %d\n", ldb_ret);
-               ret = False;
+               ret = false;
                goto cleanup;
        }
 
@@ -858,7 +665,7 @@ BOOL torture_net_become_dc(struct torture_context *torture)
        ldb_ret = ldb_modify(s->ldb, msg);
        if (ldb_ret != LDB_SUCCESS) {
                printf("ldb_modify() failed: %d\n", ldb_ret);
-               ret = False;
+               ret = false;
                goto cleanup;
        }
        
@@ -866,41 +673,46 @@ BOOL torture_net_become_dc(struct torture_context *torture)
        talloc_free(s->ldb); /* this also free's the s->schema, because dsdb_set_schema() steals it */
        s->schema = NULL;
 
-       DEBUG(0,("Reopen the SAM LDB with system credentials and all replicated data: %s\n", TORTURE_SAMDB_LDB));
-       s->ldb = ldb_wrap_connect(s, TORTURE_SAMDB_LDB,
-                                 system_session(s),
-                                 NULL, 0, NULL);
+       sam_ldb_path = talloc_asprintf(s, "%s/%s", s->targetdir, "private/sam.ldb");
+       DEBUG(0,("Reopen the SAM LDB with system credentials and all replicated data: %s\n", sam_ldb_path));
+       s->ldb = ldb_wrap_connect(s, s->tctx->ev, s->lp_ctx, sam_ldb_path,
+                                 system_session(s->lp_ctx),
+                                 NULL, 0);
        if (!s->ldb) {
                DEBUG(0,("Failed to open '%s'\n",
-                       TORTURE_SAMDB_LDB));
-               ret = False;
+                       sam_ldb_path));
+               ret = false;
                goto cleanup;
        }
 
        s->schema = dsdb_get_schema(s->ldb);
        if (!s->schema) {
                DEBUG(0,("Failed to get loaded dsdb_schema\n"));
-               ret = False;
+               ret = false;
                goto cleanup;
        }
 
-       ret &= test_become_dc_set_test_passwords(s);
+       /* Make sure we get this from the command line */
+       if (lp_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
+               talloc_free(s);
+               return ret;
+       }
 
 cleanup:
        ZERO_STRUCT(u);
        u.in.domain_dns_name            = torture_join_dom_dns_name(s->tj);
        u.in.domain_netbios_name        = torture_join_dom_netbios_name(s->tj);
-       u.in.source_dsa_address         = lp_parm_string(-1, "torture", "host");
-       u.in.dest_dsa_netbios_name      = TORTURE_NETBIOS_NAME;
+       u.in.source_dsa_address         = address;
+       u.in.dest_dsa_netbios_name      = s->netbios_name;
 
        status = libnet_UnbecomeDC(s->ctx, s, &u);
        if (!NT_STATUS_IS_OK(status)) {
                printf("libnet_UnbecomeDC() failed - %s\n", nt_errstr(status));
-               ret = False;
+               ret = false;
        }
 
        /* Leave domain. */                          
-       torture_leave_domain(s->tj);
+       torture_leave_domain(torture, s->tj);
 
        talloc_free(s);
        return ret;