r26238: Add a loadparm context parameter to torture_context, remove more uses of...
[gd/samba-autobuild/.git] / source4 / torture / libnet / libnet_BecomeDC.c
index aec776307c1bbeec084d04ed20074d62ccf75003..cf07c9c611979be667b4d2e7cb68fbb45769679e 100644 (file)
@@ -3,11 +3,11 @@
 
    libnet_BecomeDC() tests
 
 
    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
    
    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,
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -16,8 +16,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    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 "includes.h"
@@ -36,7 +35,7 @@
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "system/time.h"
 #include "auth/auth.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "system/time.h"
 #include "auth/auth.h"
-#include "lib/db_wrap.h"
+#include "lib/ldb_wrap.h"
 #include "lib/appweb/ejs/ejs.h"
 #include "lib/appweb/ejs/ejsInternal.h"
 #include "scripting/ejs/smbcalls.h"
 #include "lib/appweb/ejs/ejs.h"
 #include "lib/appweb/ejs/ejsInternal.h"
 #include "scripting/ejs/smbcalls.h"
@@ -94,11 +93,9 @@ failed:
        return ejs_error;
 }
 
        return ejs_error;
 }
 
-#define TORTURE_NETBIOS_NAME "smbtorturedc"
-#define TORTURE_SAMDB_LDB "test_samdb.ldb"
-
 struct test_become_dc_state {
        struct libnet_context *ctx;
 struct test_become_dc_state {
        struct libnet_context *ctx;
+       const char *netbios_name;
        struct test_join *tj;
        struct cli_credentials *machine_account;
        struct dsdb_schema *self_made_schema;
        struct test_join *tj;
        struct cli_credentials *machine_account;
        struct dsdb_schema *self_made_schema;
@@ -111,12 +108,24 @@ struct test_become_dc_state {
                struct drsuapi_DsReplicaObjectListItemEx *first_object;
                struct drsuapi_DsReplicaObjectListItemEx *last_object;
        } schema_part;
                struct drsuapi_DsReplicaObjectListItemEx *first_object;
                struct drsuapi_DsReplicaObjectListItemEx *last_object;
        } schema_part;
+
+       struct {
+               const char *samdb_ldb;
+               const char *domaindn_ldb;
+               const char *configdn_ldb;
+               const char *schemadn_ldb;
+               const char *secrets_ldb;
+               const char *secrets_keytab;
+       } path;
 };
 
 static NTSTATUS test_become_dc_check_options(void *private_data,
                                             const struct libnet_BecomeDC_CheckOptions *o)
 {
 };
 
 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",
                o->domain->netbios_name, o->domain->dns_name));
 
        DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n",
@@ -152,14 +161,21 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
                GUID_string(s, &p->dest_dsa->ntds_guid),
                GUID_string(s, &p->dest_dsa->invocation_id)));
 
                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,("Pathes under PRIVATEDIR[%s]\n"
+                "SAMDB[%s] SECRETS[%s] KEYTAB[%s]\n",
+               lp_private_dir(global_loadparm),
+               s->path.samdb_ldb,
+               s->path.secrets_ldb,
+               s->path.secrets_keytab));
 
 
-       DEBUG(0,("Config Partition[%s]\n",
-               p->forest->config_dn_str));
+       DEBUG(0,("Schema Partition[%s => %s]\n",
+               p->forest->schema_dn_str, s->path.schemadn_ldb));
 
 
-       DEBUG(0,("Domain Partition[%s]\n",
-               p->domain->dn_str));
+       DEBUG(0,("Config Partition[%s => %s]\n",
+               p->forest->config_dn_str, s->path.configdn_ldb));
+
+       DEBUG(0,("Domain Partition[%s => %s]\n",
+               p->domain->dn_str, s->path.domaindn_ldb));
 
        ejs = talloc_asprintf(s,
                "libinclude(\"base.js\");\n"
 
        ejs = talloc_asprintf(s,
                "libinclude(\"base.js\");\n"
@@ -170,11 +186,11 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
                "var subobj = provision_guess();\n"
                "subobj.ROOTDN       = \"%s\";\n"
                "subobj.DOMAINDN     = \"%s\";\n"
                "var subobj = provision_guess();\n"
                "subobj.ROOTDN       = \"%s\";\n"
                "subobj.DOMAINDN     = \"%s\";\n"
-               "subobj.DOMAINDN_LDB = \"test_domain.ldb\";\n"
+               "subobj.DOMAINDN_LDB = \"%s\";\n"
                "subobj.CONFIGDN     = \"%s\";\n"
                "subobj.CONFIGDN     = \"%s\";\n"
-               "subobj.CONFIGDN_LDB = \"test_config.ldb\";\n"
+               "subobj.CONFIGDN_LDB = \"%s\";\n"
                "subobj.SCHEMADN     = \"%s\";\n"
                "subobj.SCHEMADN     = \"%s\";\n"
-               "subobj.SCHEMADN_LDB = \"test_schema.ldb\";\n"
+               "subobj.SCHEMADN_LDB = \"%s\";\n"
                "subobj.HOSTNAME     = \"%s\";\n"
                "subobj.DNSNAME      = \"%s\";\n"
                "subobj.DEFAULTSITE  = \"%s\";\n"
                "subobj.HOSTNAME     = \"%s\";\n"
                "subobj.DNSNAME      = \"%s\";\n"
                "subobj.DEFAULTSITE  = \"%s\";\n"
@@ -186,33 +202,45 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
                "                                \"extended_dn\",\n"
                "                                \"asq\",\n"
                "                                \"samldb\",\n"
                "                                \"extended_dn\",\n"
                "                                \"asq\",\n"
                "                                \"samldb\",\n"
-               "                                \"password_hash\",\n"
                "                                \"operational\",\n"
                "                                \"objectclass\",\n"
                "                                \"rdn_name\",\n"
                "                                \"operational\",\n"
                "                                \"objectclass\",\n"
                "                                \"rdn_name\",\n"
+               "                                \"show_deleted\",\n"
                "                                \"partition\");\n"
                "subobj.MODULES_LIST = join(\",\", modules_list);\n"
                "                                \"partition\");\n"
                "subobj.MODULES_LIST = join(\",\", modules_list);\n"
-               "subobj.DOMAINDN_MOD = \"repl_meta_data\";\n"
-               "subobj.CONFIGDN_MOD = \"repl_meta_data\";\n"
-               "subobj.SCHEMADN_MOD = \"repl_meta_data\";\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   = \"_NOT_USED_\";\n"
+               "subobj.MACHINEPASS  = \"%s\";\n"
+               "subobj.ADMINPASS    = \"_NOT_USED_\";\n"
                "\n"
                "var paths = provision_default_paths(subobj);\n"
                "paths.samdb = \"%s\";\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"
                "\n"
                "var system_session = system_session();\n"
                "\n"
-               "var ok = provision_become_dc(subobj, message, paths, system_session);\n"
+               "var ok = provision_become_dc(subobj, message, true, paths, system_session);\n"
                "assert(ok);\n"
                "\n"
                "return 0;\n",
                "assert(ok);\n"
                "\n"
                "return 0;\n",
-               p->forest->root_dn_str,
-               p->domain->dn_str,
-               p->forest->config_dn_str,
-               p->forest->schema_dn_str,
-               p->dest_dsa->netbios_name,
-               p->dest_dsa->dns_name,
-               p->dest_dsa->site_name,
-               TORTURE_SAMDB_LDB);
+               p->forest->root_dn_str,         /* subobj.ROOTDN */
+               p->domain->dn_str,              /* subobj.DOMAINDN */
+               s->path.domaindn_ldb,           /* subobj.DOMAINDN_LDB */
+               p->forest->config_dn_str,       /* subobj.CONFIGDN */
+               s->path.configdn_ldb,           /* subobj.CONFIGDN_LDB */
+               p->forest->schema_dn_str,       /* subobj.SCHEMADN */
+               s->path.schemadn_ldb,           /* subobj.SCHEMADN_LDB */
+               p->dest_dsa->netbios_name,      /* subobj.HOSTNAME */
+               p->dest_dsa->dns_name,          /* subobj.DNSNAME */
+               p->dest_dsa->site_name,         /* subobj.DEFAULTSITE */
+               cli_credentials_get_password(s->machine_account),/* subobj.MACHINEPASS */
+               s->path.samdb_ldb,              /* paths.samdb */
+               s->path.secrets_ldb,            /* paths.secrets */
+               s->path.secrets_keytab);        /* paths.keytab */
        NT_STATUS_HAVE_NO_MEMORY(ejs);
 
        ret = test_run_ejs(ejs);
        NT_STATUS_HAVE_NO_MEMORY(ejs);
 
        ret = test_run_ejs(ejs);
@@ -226,12 +254,14 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
 
        talloc_free(s->ldb);
 
 
        talloc_free(s->ldb);
 
-       s->ldb = ldb_wrap_connect(s, TORTURE_SAMDB_LDB,
+       DEBUG(0,("Open the SAM LDB with system credentials: %s\n", s->path.samdb_ldb));
+
+       s->ldb = ldb_wrap_connect(s, global_loadparm, s->path.samdb_ldb,
                                  system_session(s),
                                  NULL, 0, NULL);
        if (!s->ldb) {
                DEBUG(0,("Failed to open '%s'\n",
                                  system_session(s),
                                  NULL, 0, NULL);
        if (!s->ldb) {
                DEBUG(0,("Failed to open '%s'\n",
-                       TORTURE_SAMDB_LDB));
+                       s->path.samdb_ldb));
                return NT_STATUS_INTERNAL_DB_ERROR;
        }
 
                return NT_STATUS_INTERNAL_DB_ERROR;
        }
 
@@ -264,8 +294,15 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
        struct dsdb_extended_replicated_objects *objs;
        struct repsFromTo1 *s_dsa;
        char *tmp_dns_name;
        struct dsdb_extended_replicated_objects *objs;
        struct repsFromTo1 *s_dsa;
        char *tmp_dns_name;
+       struct ldb_message *msg;
+       struct ldb_val prefixMap_val;
+       struct ldb_message_element *prefixMap_el;
+       struct ldb_val schemaInfo_val;
        uint32_t i;
        int ret;
        uint32_t i;
        int ret;
+       bool ok;
+
+       DEBUG(0,("Analyze and apply schema objects\n"));
 
        s_dsa                   = talloc_zero(s, struct repsFromTo1);
        NT_STATUS_HAVE_NO_MEMORY(s_dsa);
 
        s_dsa                   = talloc_zero(s, struct repsFromTo1);
        NT_STATUS_HAVE_NO_MEMORY(s_dsa);
@@ -308,7 +345,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    = 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;
 
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
        s_dsa->other_info->dns_name = tmp_dns_name;
 
@@ -398,13 +435,14 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
                                                         linked_attributes,
                                                         s_dsa,
                                                         uptodateness_vector,
                                                         linked_attributes,
                                                         s_dsa,
                                                         uptodateness_vector,
+                                                        c->gensec_skey,
                                                         s, &objs);
        if (!W_ERROR_IS_OK(status)) {
                DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
                return werror_to_ntstatus(status);
        }
 
                                                         s, &objs);
        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(global_loadparm, NULL, "become dc", "dump objects", false)) {
                for (i=0; i < objs->num_objects; i++) {
                        struct ldb_ldif ldif;
                        fprintf(stdout, "#\n");
                for (i=0; i < objs->num_objects; i++) {
                        struct ldb_ldif ldif;
                        fprintf(stdout, "#\n");
@@ -415,8 +453,63 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
                }
        }
 
                }
        }
 
+       msg = ldb_msg_new(objs);
+       NT_STATUS_HAVE_NO_MEMORY(msg);
+       msg->dn = objs->partition_dn;
+
+       status = dsdb_get_oid_mappings_ldb(s->schema, msg, &prefixMap_val, &schemaInfo_val);
+       if (!W_ERROR_IS_OK(status)) {
+               DEBUG(0,("Failed dsdb_get_oid_mappings_ldb(%s)\n", win_errstr(status)));
+               return werror_to_ntstatus(status);
+       }
+
+       /* we only add prefixMap here, because schemaInfo is a replicated attribute and already applied */
+       ret = ldb_msg_add_value(msg, "prefixMap", &prefixMap_val, &prefixMap_el);
+       if (ret != LDB_SUCCESS) {
+               return NT_STATUS_FOOBAR;
+       }
+       prefixMap_el->flags = LDB_FLAG_MOD_REPLACE;
+
+       ret = ldb_modify(s->ldb, msg);
+       if (ret != LDB_SUCCESS) {
+               DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret)));
+               return NT_STATUS_FOOBAR;
+       }
+
        talloc_free(s_dsa);
        talloc_free(objs);
        talloc_free(s_dsa);
        talloc_free(objs);
+
+       /* reopen the ldb */
+       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", s->path.samdb_ldb));
+       s->ldb = ldb_wrap_connect(s, global_loadparm, s->path.samdb_ldb,
+                                 system_session(s),
+                                 NULL, 0, NULL);
+       if (!s->ldb) {
+               DEBUG(0,("Failed to open '%s'\n",
+                       s->path.samdb_ldb));
+               return NT_STATUS_INTERNAL_DB_ERROR;
+       }
+
+       ok = samdb_set_ntds_invocation_id(s->ldb, &c->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, &c->dest_dsa->ntds_guid);
+       if (!ok) {
+               DEBUG(0,("Failed to set cached ntds objectGUID\n"));
+               return NT_STATUS_FOOBAR;
+       }
+
+       s->schema = dsdb_get_schema(s->ldb);
+       if (!s->schema) {
+               DEBUG(0,("Failed to get loaded dsdb_schema\n"));
+               return NT_STATUS_FOOBAR;
+       }
+
        return NT_STATUS_OK;
 }
 
        return NT_STATUS_OK;
 }
 
@@ -549,7 +642,7 @@ 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    = 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;
 
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
        s_dsa->other_info->dns_name = tmp_dns_name;
 
@@ -570,13 +663,14 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
                                                         linked_attributes,
                                                         s_dsa,
                                                         uptodateness_vector,
                                                         linked_attributes,
                                                         s_dsa,
                                                         uptodateness_vector,
+                                                        c->gensec_skey,
                                                         s, &objs);
        if (!W_ERROR_IS_OK(status)) {
                DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
                return werror_to_ntstatus(status);
        }
 
                                                         s, &objs);
        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(global_loadparm, NULL, "become dc", "dump objects", false)) {
                for (i=0; i < objs->num_objects; i++) {
                        struct ldb_ldif ldif;
                        fprintf(stdout, "#\n");
                for (i=0; i < objs->num_objects; i++) {
                        struct ldb_ldif ldif;
                        fprintf(stdout, "#\n");
@@ -606,7 +700,7 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
                        return NT_STATUS_FOOBAR;
                }
 
                        return NT_STATUS_FOOBAR;
                }
 
-               if (lp_parm_bool(-1, "become dc", "dump objects", False)) {
+               if (lp_parm_bool(global_loadparm, NULL, "become dc", "dump objects", false)) {
                        DEBUG(0,("# %s\n", sa->lDAPDisplayName));
                        NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute, &linked_attributes[i]);
                        dump_data(0,
                        DEBUG(0,("# %s\n", sa->lDAPDisplayName));
                        NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute, &linked_attributes[i]);
                        dump_data(0,
@@ -618,28 +712,49 @@ static NTSTATUS test_become_dc_store_chunk(void *private_data,
        return NT_STATUS_OK;
 }
 
        return NT_STATUS_OK;
 }
 
-BOOL torture_net_become_dc(struct torture_context *torture)
+bool torture_net_become_dc(struct torture_context *torture)
 {
 {
-       BOOL ret = True;
+       bool ret = true;
        NTSTATUS status;
        struct libnet_BecomeDC b;
        struct libnet_UnbecomeDC u;
        struct test_become_dc_state *s;
        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);
 
        s = talloc_zero(torture, struct test_become_dc_state);
-       if (!s) return False;
+       if (!s) return false;
+
+       s->netbios_name = lp_parm_string(global_loadparm, NULL, "become dc", "smbtorture dc");
+       if (!s->netbios_name || !s->netbios_name[0]) {
+               s->netbios_name = "smbtorturedc";
+       }
+
+       s->path.samdb_ldb       = talloc_asprintf(s, "%s_samdb.ldb", s->netbios_name);
+       if (!s->path.samdb_ldb) return false;
+       s->path.domaindn_ldb    = talloc_asprintf(s, "%s_domain.ldb", s->netbios_name);
+       if (!s->path.domaindn_ldb) return false;
+       s->path.configdn_ldb    = talloc_asprintf(s, "%s_config.ldb", s->netbios_name);
+       if (!s->path.configdn_ldb) return false;
+       s->path.schemadn_ldb    = talloc_asprintf(s, "%s_schema.ldb", s->netbios_name);
+       if (!s->path.schemadn_ldb) return false;
+       s->path.secrets_ldb     = talloc_asprintf(s, "%s_secrets.ldb", s->netbios_name);
+       if (!s->path.secrets_ldb) return false;
+       s->path.secrets_keytab  = talloc_asprintf(s, "%s_secrets.keytab", s->netbios_name);
+       if (!s->path.secrets_keytab) return false;
 
        /* Join domain as a member server. */
 
        /* Join domain as a member server. */
-       s->tj = torture_join_domain(TORTURE_NETBIOS_NAME,
+       s->tj = torture_join_domain(s->netbios_name,
                                 ACB_WSTRUST,
                                 &s->machine_account);
        if (!s->tj) {
                DEBUG(0, ("%s failed to join domain as workstation\n",
                                 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);
        s->ctx->cred = cmdline_credentials;
 
        s->ldb = ldb_init(s);
        s->ctx->cred = cmdline_credentials;
 
        s->ldb = ldb_init(s);
@@ -648,8 +763,8 @@ BOOL torture_net_become_dc(struct torture_context *torture)
        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.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         = torture_setting_string(torture, "host", NULL);
+       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.private_data     = s;
        b.in.callbacks.check_options    = test_become_dc_check_options;
@@ -661,19 +776,80 @@ BOOL torture_net_become_dc(struct torture_context *torture)
        status = libnet_BecomeDC(s->ctx, s, &b);
        if (!NT_STATUS_IS_OK(status)) {
                printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status));
        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;
+               goto cleanup;
+       }
+       msg->dn = ldb_dn_new(msg, s->ldb, "@ROOTDSE");
+       if (!msg->dn) {
+               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;
+               goto cleanup;
+       }
+
+       for (i=0; i < msg->num_elements; i++) {
+               msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
+       }
+
+       printf("mark ROOTDSE with isSynchronized=TRUE\n");
+       ldb_ret = ldb_modify(s->ldb, msg);
+       if (ldb_ret != LDB_SUCCESS) {
+               printf("ldb_modify() failed: %d\n", ldb_ret);
+               ret = false;
+               goto cleanup;
+       }
+       
+       /* reopen the ldb */
+       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", s->path.samdb_ldb));
+       s->ldb = ldb_wrap_connect(s, torture->lp_ctx, s->path.samdb_ldb,
+                                 system_session(s),
+                                 NULL, 0, NULL);
+       if (!s->ldb) {
+               DEBUG(0,("Failed to open '%s'\n",
+                       s->path.samdb_ldb));
+               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;
+               goto cleanup;
+       }
+
+       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);
        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         = torture_setting_string(torture, "host", NULL);
+       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));
 
        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. */                          
        }
 
        /* Leave domain. */