summaryrefslogtreecommitdiffstats
path: root/source4/torture/libnet/libnet_BecomeDC.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/torture/libnet/libnet_BecomeDC.c')
-rw-r--r--source4/torture/libnet/libnet_BecomeDC.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/source4/torture/libnet/libnet_BecomeDC.c b/source4/torture/libnet/libnet_BecomeDC.c
new file mode 100644
index 0000000..45d386b
--- /dev/null
+++ b/source4/torture/libnet/libnet_BecomeDC.c
@@ -0,0 +1,191 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ libnet_BecomeDC() tests
+
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "lib/cmdline/cmdline.h"
+#include "torture/rpc/torture_rpc.h"
+#include "libnet/libnet.h"
+#include "dsdb/samdb/samdb.h"
+#include "../lib/util/dlinklist.h"
+#include "librpc/gen_ndr/ndr_drsuapi.h"
+#include "librpc/gen_ndr/ndr_drsblobs.h"
+#include "system/time.h"
+#include "ldb_wrap.h"
+#include "auth/auth.h"
+#include "param/param.h"
+#include "param/provision.h"
+#include "libcli/resolve/resolve.h"
+#include "torture/libnet/proto.h"
+
+bool torture_net_become_dc(struct torture_context *torture)
+{
+ bool ret = true;
+ NTSTATUS status;
+ struct libnet_BecomeDC b;
+ struct libnet_UnbecomeDC u;
+ struct libnet_vampire_cb_state *s;
+ struct ldb_message *msg;
+ int ldb_ret;
+ uint32_t i;
+ char *private_dir;
+ const char *address;
+ struct nbt_name name;
+ const char *netbios_name;
+ struct cli_credentials *machine_account;
+ struct test_join *tj;
+ struct loadparm_context *lp_ctx;
+ struct ldb_context *ldb;
+ struct libnet_context *ctx;
+ struct dsdb_schema *schema;
+
+ char *location = NULL;
+ torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location),
+ "torture_temp_dir should return NT_STATUS_OK" );
+
+ netbios_name = lpcfg_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
+ if (!netbios_name || !netbios_name[0]) {
+ netbios_name = "smbtorturedc";
+ }
+
+ make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));
+
+ /* do an initial name resolution to find its IP */
+ status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx),
+ 0, 0,
+ &name, torture, &address, torture->ev);
+ torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
+ "Failed to resolve %s - %s\n",
+ name.name, nt_errstr(status)));
+
+
+ /* Join domain as a member server. */
+ tj = torture_join_domain(torture, netbios_name,
+ ACB_WSTRUST,
+ &machine_account);
+ torture_assert(torture, tj, talloc_asprintf(torture,
+ "%s failed to join domain as workstation\n",
+ netbios_name));
+
+ s = libnet_vampire_cb_state_init(torture, torture->lp_ctx, torture->ev,
+ netbios_name,
+ torture_join_dom_netbios_name(tj),
+ torture_join_dom_dns_name(tj),
+ location);
+ torture_assert(torture, s, "libnet_vampire_cb_state_init");
+
+ ctx = libnet_context_init(torture->ev, torture->lp_ctx);
+ ctx->cred = samba_cmdline_get_creds();
+
+ ZERO_STRUCT(b);
+ b.in.domain_dns_name = torture_join_dom_dns_name(tj);
+ b.in.domain_netbios_name = torture_join_dom_netbios_name(tj);
+ b.in.domain_sid = torture_join_sid(tj);
+ b.in.source_dsa_address = address;
+ b.in.dest_dsa_netbios_name = netbios_name;
+
+ b.in.callbacks.private_data = s;
+ b.in.callbacks.check_options = libnet_vampire_cb_check_options;
+ b.in.callbacks.prepare_db = libnet_vampire_cb_prepare_db;
+ b.in.callbacks.schema_chunk = libnet_vampire_cb_schema_chunk;
+ b.in.callbacks.config_chunk = libnet_vampire_cb_store_chunk;
+ b.in.callbacks.domain_chunk = libnet_vampire_cb_store_chunk;
+
+ status = libnet_BecomeDC(ctx, s, &b);
+ torture_assert_ntstatus_ok_goto(torture, status, ret, cleanup, talloc_asprintf(torture,
+ "libnet_BecomeDC() failed - %s %s\n",
+ nt_errstr(status), b.out.error_string));
+ ldb = libnet_vampire_cb_ldb(s);
+
+ msg = ldb_msg_new(s);
+ torture_assert_int_equal_goto(torture, (msg?1:0), 1, ret, cleanup,
+ "ldb_msg_new() failed\n");
+ msg->dn = ldb_dn_new(msg, ldb, "@ROOTDSE");
+ torture_assert_int_equal_goto(torture, (msg->dn?1:0), 1, ret, cleanup,
+ "ldb_msg_new(@ROOTDSE) failed\n");
+
+ ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
+ torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
+ "ldb_msg_add_string(msg, isSynchronized, TRUE) failed\n");
+
+ for (i=0; i < msg->num_elements; i++) {
+ msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
+ }
+
+ torture_comment(torture, "mark ROOTDSE with isSynchronized=TRUE\n");
+ ldb_ret = ldb_modify(libnet_vampire_cb_ldb(s), msg);
+ torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
+ "ldb_modify() failed\n");
+
+ /* commit the transaction now we know the secrets were written
+ * out properly
+ */
+ ldb_ret = ldb_transaction_commit(ldb);
+ torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
+ "ldb_transaction_commit() failed\n");
+
+ /* reopen the ldb */
+ talloc_unlink(s, ldb);
+
+ lp_ctx = libnet_vampire_cb_lp_ctx(s);
+ private_dir = talloc_asprintf(s, "%s/%s", location, "private");
+ lpcfg_set_cmdline(lp_ctx, "private dir", private_dir);
+ torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", private_dir);
+ ldb = samdb_connect(s,
+ torture->ev,
+ lp_ctx,
+ system_session(lp_ctx),
+ NULL,
+ 0);
+ torture_assert_goto(torture, ldb != NULL, ret, cleanup,
+ talloc_asprintf(torture,
+ "Failed to open '%s/sam.ldb'\n", private_dir));
+
+ torture_assert_goto(torture, dsdb_uses_global_schema(ldb), ret, cleanup,
+ "Uses global schema");
+
+ schema = dsdb_get_schema(ldb, s);
+ torture_assert_goto(torture, schema != NULL, ret, cleanup,
+ "Failed to get loaded dsdb_schema\n");
+
+ /* Make sure we get this from the command line */
+ if (lpcfg_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(tj);
+ u.in.domain_netbios_name = torture_join_dom_netbios_name(tj);
+ u.in.source_dsa_address = address;
+ u.in.dest_dsa_netbios_name = netbios_name;
+
+ status = libnet_UnbecomeDC(ctx, s, &u);
+ torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
+ "libnet_UnbecomeDC() failed - %s %s\n",
+ nt_errstr(status), u.out.error_string));
+
+ /* Leave domain. */
+ torture_leave_domain(torture, tj);
+
+ talloc_free(s);
+ return ret;
+}