Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : libnet_BecomeDC() tests
5 :
6 : Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "lib/cmdline/cmdline.h"
24 : #include "torture/rpc/torture_rpc.h"
25 : #include "libnet/libnet.h"
26 : #include "dsdb/samdb/samdb.h"
27 : #include "../lib/util/dlinklist.h"
28 : #include "librpc/gen_ndr/ndr_drsuapi.h"
29 : #include "librpc/gen_ndr/ndr_drsblobs.h"
30 : #include "system/time.h"
31 : #include "ldb_wrap.h"
32 : #include "auth/auth.h"
33 : #include "param/param.h"
34 : #include "param/provision.h"
35 : #include "libcli/resolve/resolve.h"
36 : #include "torture/libnet/proto.h"
37 :
38 4 : bool torture_net_become_dc(struct torture_context *torture)
39 : {
40 4 : bool ret = true;
41 0 : NTSTATUS status;
42 0 : struct libnet_BecomeDC b;
43 0 : struct libnet_UnbecomeDC u;
44 0 : struct libnet_vampire_cb_state *s;
45 0 : struct ldb_message *msg;
46 0 : int ldb_ret;
47 0 : uint32_t i;
48 0 : char *private_dir;
49 0 : const char *address;
50 0 : struct nbt_name name;
51 0 : const char *netbios_name;
52 0 : struct cli_credentials *machine_account;
53 0 : struct test_join *tj;
54 0 : struct loadparm_context *lp_ctx;
55 0 : struct ldb_context *ldb;
56 0 : struct libnet_context *ctx;
57 0 : struct dsdb_schema *schema;
58 :
59 4 : char *location = NULL;
60 4 : torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location),
61 : "torture_temp_dir should return NT_STATUS_OK" );
62 :
63 4 : netbios_name = lpcfg_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
64 4 : if (!netbios_name || !netbios_name[0]) {
65 4 : netbios_name = "smbtorturedc";
66 : }
67 :
68 4 : make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));
69 :
70 : /* do an initial name resolution to find its IP */
71 4 : status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx),
72 : 0, 0,
73 : &name, torture, &address, torture->ev);
74 4 : torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
75 : "Failed to resolve %s - %s\n",
76 : name.name, nt_errstr(status)));
77 :
78 :
79 : /* Join domain as a member server. */
80 4 : tj = torture_join_domain(torture, netbios_name,
81 : ACB_WSTRUST,
82 : &machine_account);
83 4 : torture_assert(torture, tj, talloc_asprintf(torture,
84 : "%s failed to join domain as workstation\n",
85 : netbios_name));
86 :
87 4 : s = libnet_vampire_cb_state_init(torture, torture->lp_ctx, torture->ev,
88 : netbios_name,
89 : torture_join_dom_netbios_name(tj),
90 : torture_join_dom_dns_name(tj),
91 : location);
92 4 : torture_assert(torture, s, "libnet_vampire_cb_state_init");
93 :
94 4 : ctx = libnet_context_init(torture->ev, torture->lp_ctx);
95 4 : ctx->cred = samba_cmdline_get_creds();
96 :
97 4 : ZERO_STRUCT(b);
98 4 : b.in.domain_dns_name = torture_join_dom_dns_name(tj);
99 4 : b.in.domain_netbios_name = torture_join_dom_netbios_name(tj);
100 4 : b.in.domain_sid = torture_join_sid(tj);
101 4 : b.in.source_dsa_address = address;
102 4 : b.in.dest_dsa_netbios_name = netbios_name;
103 :
104 4 : b.in.callbacks.private_data = s;
105 4 : b.in.callbacks.check_options = libnet_vampire_cb_check_options;
106 4 : b.in.callbacks.prepare_db = libnet_vampire_cb_prepare_db;
107 4 : b.in.callbacks.schema_chunk = libnet_vampire_cb_schema_chunk;
108 4 : b.in.callbacks.config_chunk = libnet_vampire_cb_store_chunk;
109 4 : b.in.callbacks.domain_chunk = libnet_vampire_cb_store_chunk;
110 :
111 4 : status = libnet_BecomeDC(ctx, s, &b);
112 4 : torture_assert_ntstatus_ok_goto(torture, status, ret, cleanup, talloc_asprintf(torture,
113 : "libnet_BecomeDC() failed - %s %s\n",
114 : nt_errstr(status), b.out.error_string));
115 4 : ldb = libnet_vampire_cb_ldb(s);
116 :
117 4 : msg = ldb_msg_new(s);
118 4 : torture_assert_int_equal_goto(torture, (msg?1:0), 1, ret, cleanup,
119 : "ldb_msg_new() failed\n");
120 4 : msg->dn = ldb_dn_new(msg, ldb, "@ROOTDSE");
121 4 : torture_assert_int_equal_goto(torture, (msg->dn?1:0), 1, ret, cleanup,
122 : "ldb_msg_new(@ROOTDSE) failed\n");
123 :
124 4 : ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
125 4 : torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
126 : "ldb_msg_add_string(msg, isSynchronized, TRUE) failed\n");
127 :
128 8 : for (i=0; i < msg->num_elements; i++) {
129 4 : msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
130 : }
131 :
132 4 : torture_comment(torture, "mark ROOTDSE with isSynchronized=TRUE\n");
133 4 : ldb_ret = ldb_modify(libnet_vampire_cb_ldb(s), msg);
134 4 : torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
135 : "ldb_modify() failed\n");
136 :
137 : /* commit the transaction now we know the secrets were written
138 : * out properly
139 : */
140 4 : ldb_ret = ldb_transaction_commit(ldb);
141 4 : torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
142 : "ldb_transaction_commit() failed\n");
143 :
144 : /* reopen the ldb */
145 4 : talloc_unlink(s, ldb);
146 :
147 4 : lp_ctx = libnet_vampire_cb_lp_ctx(s);
148 4 : private_dir = talloc_asprintf(s, "%s/%s", location, "private");
149 4 : lpcfg_set_cmdline(lp_ctx, "private dir", private_dir);
150 4 : torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", private_dir);
151 4 : ldb = samdb_connect(s,
152 : torture->ev,
153 : lp_ctx,
154 : system_session(lp_ctx),
155 : NULL,
156 : 0);
157 4 : torture_assert_goto(torture, ldb != NULL, ret, cleanup,
158 : talloc_asprintf(torture,
159 : "Failed to open '%s/sam.ldb'\n", private_dir));
160 :
161 4 : torture_assert_goto(torture, dsdb_uses_global_schema(ldb), ret, cleanup,
162 : "Uses global schema");
163 :
164 4 : schema = dsdb_get_schema(ldb, s);
165 4 : torture_assert_goto(torture, schema != NULL, ret, cleanup,
166 : "Failed to get loaded dsdb_schema\n");
167 :
168 : /* Make sure we get this from the command line */
169 4 : if (lpcfg_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
170 0 : talloc_free(s);
171 0 : return ret;
172 : }
173 :
174 4 : cleanup:
175 4 : ZERO_STRUCT(u);
176 4 : u.in.domain_dns_name = torture_join_dom_dns_name(tj);
177 4 : u.in.domain_netbios_name = torture_join_dom_netbios_name(tj);
178 4 : u.in.source_dsa_address = address;
179 4 : u.in.dest_dsa_netbios_name = netbios_name;
180 :
181 4 : status = libnet_UnbecomeDC(ctx, s, &u);
182 4 : torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
183 : "libnet_UnbecomeDC() failed - %s %s\n",
184 : nt_errstr(status), u.out.error_string));
185 :
186 : /* Leave domain. */
187 4 : torture_leave_domain(torture, tj);
188 :
189 4 : talloc_free(s);
190 4 : return ret;
191 : }
|