372311e5c1159aa0fb599d1933f9bf5f55ce8f99
[gd/samba-autobuild/.git] / source4 / torture / libnet / libnet_BecomeDC.c
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/popt_common.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 bool torture_net_become_dc(struct torture_context *torture)
39 {
40         bool ret = true;
41         NTSTATUS status;
42         struct libnet_BecomeDC b;
43         struct libnet_UnbecomeDC u;
44         struct libnet_vampire_cb_state *s;
45         struct ldb_message *msg;
46         int ldb_ret;
47         uint32_t i;
48         char *private_dir;
49         const char *address;
50         struct nbt_name name;
51         const char *netbios_name;
52         struct cli_credentials *machine_account;
53         struct test_join *tj;
54         struct loadparm_context *lp_ctx;
55         struct ldb_context *ldb;
56         struct libnet_context *ctx;
57         struct dsdb_schema *schema;
58
59         char *location = NULL;
60         torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location), 
61                                    "torture_temp_dir should return NT_STATUS_OK" );
62
63         netbios_name = lpcfg_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
64         if (!netbios_name || !netbios_name[0]) {
65                 netbios_name = "smbtorturedc";
66         }
67
68         make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));
69
70         /* do an initial name resolution to find its IP */
71         status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx),
72                                  0, 0,
73                                  &name, torture, &address, torture->ev);
74         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         tj = torture_join_domain(torture, netbios_name,
81                                  ACB_WSTRUST,
82                                  &machine_account);
83         torture_assert(torture, tj, talloc_asprintf(torture,
84                                                     "%s failed to join domain as workstation\n",
85                                                     netbios_name));
86
87         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         torture_assert(torture, s, "libnet_vampire_cb_state_init");
93
94         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
95         ctx->cred = cmdline_credentials;
96
97         ZERO_STRUCT(b);
98         b.in.domain_dns_name            = torture_join_dom_dns_name(tj);
99         b.in.domain_netbios_name        = torture_join_dom_netbios_name(tj);
100         b.in.domain_sid                 = torture_join_sid(tj);
101         b.in.source_dsa_address         = address;
102         b.in.dest_dsa_netbios_name      = netbios_name;
103
104         b.in.callbacks.private_data     = s;
105         b.in.callbacks.check_options    = libnet_vampire_cb_check_options;
106         b.in.callbacks.prepare_db       = libnet_vampire_cb_prepare_db;
107         b.in.callbacks.schema_chunk     = libnet_vampire_cb_schema_chunk;
108         b.in.callbacks.config_chunk     = libnet_vampire_cb_store_chunk;
109         b.in.callbacks.domain_chunk     = libnet_vampire_cb_store_chunk;
110
111         status = libnet_BecomeDC(ctx, s, &b);
112         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         ldb = libnet_vampire_cb_ldb(s);
116
117         msg = ldb_msg_new(s);
118         torture_assert_int_equal_goto(torture, (msg?1:0), 1, ret, cleanup,
119                                       "ldb_msg_new() failed\n");
120         msg->dn = ldb_dn_new(msg, ldb, "@ROOTDSE");
121         torture_assert_int_equal_goto(torture, (msg->dn?1:0), 1, ret, cleanup,
122                                       "ldb_msg_new(@ROOTDSE) failed\n");
123
124         ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
125         torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
126                                       "ldb_msg_add_string(msg, isSynchronized, TRUE) failed\n");
127
128         for (i=0; i < msg->num_elements; i++) {
129                 msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
130         }
131
132         torture_comment(torture, "mark ROOTDSE with isSynchronized=TRUE\n");
133         ldb_ret = ldb_modify(libnet_vampire_cb_ldb(s), msg);
134         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         ldb_ret = ldb_transaction_commit(ldb);
141         torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
142                                       "ldb_transaction_commit() failed\n");
143
144         /* reopen the ldb */
145         talloc_unlink(s, ldb);
146
147         lp_ctx = libnet_vampire_cb_lp_ctx(s);
148         private_dir = talloc_asprintf(s, "%s/%s", location, "private");
149         lpcfg_set_cmdline(lp_ctx, "private dir", private_dir);
150         torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", private_dir);
151         ldb = samdb_connect(s, torture->ev, lp_ctx, system_session(lp_ctx), 0);
152         torture_assert_goto(torture, ldb != NULL, ret, cleanup,
153                                       talloc_asprintf(torture,
154                                       "Failed to open '%s/sam.ldb'\n", private_dir));
155
156         torture_assert_goto(torture, dsdb_uses_global_schema(ldb), ret, cleanup,
157                                                 "Uses global schema");
158
159         schema = dsdb_get_schema(ldb, s);
160         torture_assert_goto(torture, schema != NULL, ret, cleanup,
161                                       "Failed to get loaded dsdb_schema\n");
162
163         /* Make sure we get this from the command line */
164         if (lpcfg_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
165                 talloc_free(s);
166                 return ret;
167         }
168
169 cleanup:
170         ZERO_STRUCT(u);
171         u.in.domain_dns_name            = torture_join_dom_dns_name(tj);
172         u.in.domain_netbios_name        = torture_join_dom_netbios_name(tj);
173         u.in.source_dsa_address         = address;
174         u.in.dest_dsa_netbios_name      = netbios_name;
175
176         status = libnet_UnbecomeDC(ctx, s, &u);
177         torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
178                                    "libnet_UnbecomeDC() failed - %s %s\n",
179                                    nt_errstr(status), u.out.error_string));
180
181         /* Leave domain. */
182         torture_leave_domain(torture, tj);
183
184         talloc_free(s);
185         return ret;
186 }