Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : DRSUapi tests
5 :
6 : Copyright (C) Andrew Tridgell 2003
7 : Copyright (C) Stefan (metze) Metzmacher 2004
8 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "lib/cmdline/cmdline.h"
26 : #include "librpc/gen_ndr/ndr_drsuapi_c.h"
27 : #include "torture/rpc/torture_rpc.h"
28 : #include "libcli/security/dom_sid.h"
29 : #include "param/param.h"
30 :
31 : #define TEST_MACHINE_NAME "torturetest"
32 :
33 7 : static bool test_DsBind(struct dcerpc_pipe *p,
34 : struct torture_context *tctx,
35 : struct policy_handle *bind_handle,
36 : struct drsuapi_DsBindInfo28 *srv_info28)
37 : {
38 0 : NTSTATUS status;
39 0 : struct drsuapi_DsBind r;
40 0 : struct GUID bind_guid;
41 0 : struct drsuapi_DsBindInfo28 *bind_info28;
42 0 : struct drsuapi_DsBindInfoCtr bind_info_ctr;
43 :
44 7 : ZERO_STRUCT(bind_info_ctr);
45 7 : bind_info_ctr.length = 28;
46 :
47 7 : bind_info28 = &bind_info_ctr.info.info28;
48 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_BASE;
49 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
50 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;
51 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;
52 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;
53 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;
54 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
55 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
56 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
57 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
58 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
59 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
60 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
61 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;
62 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
63 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;
64 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;
65 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;
66 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;
67 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;
68 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;
69 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;
70 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;
71 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;
72 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;
73 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
74 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;
75 7 : bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;
76 :
77 7 : GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid);
78 :
79 7 : r.in.bind_guid = &bind_guid;
80 7 : r.in.bind_info = &bind_info_ctr;
81 7 : r.out.bind_handle = bind_handle;
82 :
83 7 : torture_comment(tctx, "Testing DsBind\n");
84 :
85 7 : status = dcerpc_drsuapi_DsBind_r(p->binding_handle, tctx, &r);
86 7 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsBind");
87 :
88 5 : if (srv_info28 != NULL) {
89 2 : *srv_info28 = r.out.bind_info->info.info28;
90 : }
91 :
92 5 : return true;
93 : }
94 :
95 1 : static bool test_DsGetDomainControllerInfo(struct torture_context *tctx,
96 : struct DsPrivate *priv)
97 : {
98 0 : NTSTATUS status;
99 1 : struct dcerpc_pipe *p = priv->drs_pipe;
100 0 : struct drsuapi_DsGetDomainControllerInfo r;
101 0 : union drsuapi_DsGetDCInfoCtr ctr;
102 0 : union drsuapi_DsGetDCInfoRequest req;
103 1 : int32_t level_out = 0;
104 1 : bool found = false;
105 0 : int i, j, k;
106 :
107 0 : struct {
108 : const char *name;
109 : WERROR expected;
110 2 : } names[] = {
111 : {
112 1 : .name = torture_join_dom_netbios_name(priv->join),
113 : .expected = WERR_OK
114 : },
115 : {
116 1 : .name = torture_join_dom_dns_name(priv->join),
117 : .expected = WERR_OK
118 : },
119 : {
120 : .name = "__UNKNOWN_DOMAIN__",
121 : .expected = WERR_DS_OBJ_NOT_FOUND
122 : },
123 : {
124 : .name = "unknown.domain.samba.example.com",
125 : .expected = WERR_DS_OBJ_NOT_FOUND
126 : },
127 : };
128 1 : int levels[] = {1, 2};
129 0 : int level;
130 :
131 1 : for (i=0; i < ARRAY_SIZE(levels); i++) {
132 3 : for (j=0; j < ARRAY_SIZE(names); j++) {
133 3 : level = levels[i];
134 3 : r.in.bind_handle = &priv->bind_handle;
135 3 : r.in.level = 1;
136 3 : r.in.req = &req;
137 :
138 3 : r.in.req->req1.domain_name = names[j].name;
139 3 : r.in.req->req1.level = level;
140 :
141 3 : r.out.ctr = &ctr;
142 3 : r.out.level_out = &level_out;
143 :
144 3 : torture_comment(tctx,
145 : "Testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
146 3 : r.in.req->req1.level, r.in.req->req1.domain_name);
147 :
148 3 : status = dcerpc_drsuapi_DsGetDomainControllerInfo_r(p->binding_handle, tctx, &r);
149 3 : torture_assert_ntstatus_ok(tctx, status,
150 : "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
151 3 : torture_assert_werr_equal(tctx,
152 : r.out.result, names[j].expected,
153 : "DsGetDomainControllerInfo level with dns domain failed");
154 :
155 2 : if (!W_ERROR_IS_OK(r.out.result)) {
156 : /* If this was an error, we can't read the result structure */
157 0 : continue;
158 : }
159 :
160 2 : torture_assert_int_equal(tctx,
161 : r.in.req->req1.level, *r.out.level_out,
162 : "dcerpc_drsuapi_DsGetDomainControllerInfo in/out level differs");
163 :
164 2 : switch (level) {
165 2 : case 1:
166 2 : for (k=0; k < r.out.ctr->ctr1.count; k++) {
167 2 : if (strcasecmp_m(r.out.ctr->ctr1.array[k].netbios_name,
168 : torture_join_netbios_name(priv->join)) == 0) {
169 2 : found = true;
170 2 : break;
171 : }
172 : }
173 2 : break;
174 0 : case 2:
175 0 : for (k=0; k < r.out.ctr->ctr2.count; k++) {
176 0 : if (strcasecmp_m(r.out.ctr->ctr2.array[k].netbios_name,
177 : torture_join_netbios_name(priv->join)) == 0) {
178 0 : found = true;
179 0 : priv->dcinfo = r.out.ctr->ctr2.array[k];
180 0 : break;
181 : }
182 : }
183 0 : break;
184 : }
185 2 : torture_assert(tctx, found,
186 : "dcerpc_drsuapi_DsGetDomainControllerInfo: Failed to find the domain controller we just created during the join");
187 : }
188 : }
189 :
190 0 : r.in.bind_handle = &priv->bind_handle;
191 0 : r.in.level = 1;
192 :
193 0 : r.out.ctr = &ctr;
194 0 : r.out.level_out = &level_out;
195 :
196 0 : r.in.req->req1.domain_name = "__UNKNOWN_DOMAIN__"; /* This is clearly ignored for this level */
197 0 : r.in.req->req1.level = -1;
198 :
199 0 : torture_comment(tctx, "Testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
200 0 : r.in.req->req1.level, r.in.req->req1.domain_name);
201 :
202 0 : status = dcerpc_drsuapi_DsGetDomainControllerInfo_r(p->binding_handle, tctx, &r);
203 :
204 0 : torture_assert_ntstatus_ok(tctx, status,
205 : "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
206 0 : torture_assert_werr_ok(tctx, r.out.result,
207 : "DsGetDomainControllerInfo with dns domain failed");
208 :
209 : {
210 0 : const char *dc_account = talloc_asprintf(tctx, "%s\\%s$",
211 : torture_join_dom_netbios_name(priv->join),
212 : priv->dcinfo.netbios_name);
213 0 : torture_comment(tctx, "%s: Enum active LDAP sessions searching for %s\n", __func__, dc_account);
214 0 : for (k=0; k < r.out.ctr->ctr01.count; k++) {
215 0 : if (strcasecmp_m(r.out.ctr->ctr01.array[k].client_account,
216 : dc_account)) {
217 0 : found = true;
218 0 : break;
219 : }
220 : }
221 0 : torture_assert(tctx, found,
222 : "dcerpc_drsuapi_DsGetDomainControllerInfo level: Failed to find the domain controller in last logon records");
223 : }
224 :
225 :
226 0 : return true;
227 : }
228 :
229 1 : static bool test_DsWriteAccountSpn(struct torture_context *tctx,
230 : struct DsPrivate *priv)
231 : {
232 0 : NTSTATUS status;
233 1 : struct dcerpc_pipe *p = priv->drs_pipe;
234 0 : struct drsuapi_DsWriteAccountSpn r;
235 0 : union drsuapi_DsWriteAccountSpnRequest req;
236 0 : struct drsuapi_DsNameString names[2];
237 0 : union drsuapi_DsWriteAccountSpnResult res;
238 0 : uint32_t level_out;
239 :
240 1 : r.in.bind_handle = &priv->bind_handle;
241 1 : r.in.level = 1;
242 1 : r.in.req = &req;
243 :
244 1 : torture_comment(tctx, "Testing DsWriteAccountSpn\n");
245 :
246 1 : r.in.req->req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
247 1 : r.in.req->req1.unknown1 = 0;
248 1 : r.in.req->req1.object_dn = priv->dcinfo.computer_dn;
249 1 : r.in.req->req1.count = 2;
250 1 : r.in.req->req1.spn_names = names;
251 1 : names[0].str = talloc_asprintf(tctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
252 1 : names[1].str = talloc_asprintf(tctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
253 :
254 1 : r.out.res = &res;
255 1 : r.out.level_out = &level_out;
256 :
257 1 : status = dcerpc_drsuapi_DsWriteAccountSpn_r(p->binding_handle, tctx, &r);
258 1 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsWriteAccountSpn");
259 :
260 1 : r.in.req->req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
261 1 : r.in.req->req1.unknown1 = 0;
262 :
263 1 : status = dcerpc_drsuapi_DsWriteAccountSpn_r(p->binding_handle, tctx, &r);
264 1 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsWriteAccountSpn");
265 :
266 1 : return true;
267 : }
268 :
269 1 : static bool test_DsReplicaGetInfo(struct torture_context *tctx,
270 : struct DsPrivate *priv)
271 : {
272 0 : NTSTATUS status;
273 1 : struct dcerpc_pipe *p = priv->drs_pipe;
274 0 : struct drsuapi_DsReplicaGetInfo r;
275 0 : union drsuapi_DsReplicaGetInfoRequest req;
276 0 : union drsuapi_DsReplicaInfo info;
277 0 : enum drsuapi_DsReplicaInfoType info_type;
278 0 : int i;
279 0 : struct {
280 : int32_t level;
281 : int32_t infotype;
282 : const char *obj_dn;
283 1 : } array[] = {
284 : {
285 : DRSUAPI_DS_REPLICA_GET_INFO,
286 : DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
287 : NULL
288 : },{
289 : DRSUAPI_DS_REPLICA_GET_INFO,
290 : DRSUAPI_DS_REPLICA_INFO_CURSORS,
291 : NULL
292 : },{
293 : DRSUAPI_DS_REPLICA_GET_INFO,
294 : DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
295 : NULL
296 : },{
297 : DRSUAPI_DS_REPLICA_GET_INFO,
298 : DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
299 : NULL
300 : },{
301 : DRSUAPI_DS_REPLICA_GET_INFO,
302 : DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
303 : NULL
304 : },{
305 : DRSUAPI_DS_REPLICA_GET_INFO,
306 : DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
307 : NULL
308 : },{
309 : DRSUAPI_DS_REPLICA_GET_INFO2,
310 : DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
311 : NULL
312 : },{
313 : DRSUAPI_DS_REPLICA_GET_INFO2,
314 : DRSUAPI_DS_REPLICA_INFO_CURSORS2,
315 : NULL
316 : },{
317 : DRSUAPI_DS_REPLICA_GET_INFO2,
318 : DRSUAPI_DS_REPLICA_INFO_CURSORS3,
319 : NULL
320 : },{
321 : DRSUAPI_DS_REPLICA_GET_INFO2,
322 : DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
323 : NULL
324 : },{
325 : DRSUAPI_DS_REPLICA_GET_INFO2,
326 : DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
327 : NULL
328 : },{
329 : DRSUAPI_DS_REPLICA_GET_INFO2,
330 : DRSUAPI_DS_REPLICA_INFO_REPSTO,
331 : NULL
332 : },{
333 : DRSUAPI_DS_REPLICA_GET_INFO2,
334 : DRSUAPI_DS_REPLICA_INFO_CLIENT_CONTEXTS,
335 : "__IGNORED__"
336 : },{
337 : DRSUAPI_DS_REPLICA_GET_INFO2,
338 : DRSUAPI_DS_REPLICA_INFO_UPTODATE_VECTOR_V1,
339 : NULL
340 : },{
341 : DRSUAPI_DS_REPLICA_GET_INFO2,
342 : DRSUAPI_DS_REPLICA_INFO_SERVER_OUTGOING_CALLS,
343 : NULL
344 : }
345 : };
346 :
347 1 : if (torture_setting_bool(tctx, "samba4", false)) {
348 1 : torture_comment(tctx, "skipping DsReplicaGetInfo test against Samba4\n");
349 1 : return true;
350 : }
351 :
352 0 : r.in.bind_handle = &priv->bind_handle;
353 0 : r.in.req = &req;
354 :
355 0 : for (i=0; i < ARRAY_SIZE(array); i++) {
356 0 : const char *object_dn;
357 :
358 0 : torture_comment(tctx, "Testing DsReplicaGetInfo level %d infotype %d\n",
359 : array[i].level, array[i].infotype);
360 :
361 0 : object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
362 :
363 0 : r.in.level = array[i].level;
364 0 : switch(r.in.level) {
365 0 : case DRSUAPI_DS_REPLICA_GET_INFO:
366 0 : r.in.req->req1.info_type = array[i].infotype;
367 0 : r.in.req->req1.object_dn = object_dn;
368 0 : ZERO_STRUCT(r.in.req->req1.source_dsa_guid);
369 0 : break;
370 0 : case DRSUAPI_DS_REPLICA_GET_INFO2:
371 0 : r.in.req->req2.info_type = array[i].infotype;
372 0 : r.in.req->req2.object_dn = object_dn;
373 0 : ZERO_STRUCT(r.in.req->req2.source_dsa_guid);
374 0 : r.in.req->req2.flags = 0;
375 0 : r.in.req->req2.attribute_name = NULL;
376 0 : r.in.req->req2.value_dn_str = NULL;
377 0 : r.in.req->req2.enumeration_context = 0;
378 0 : break;
379 : }
380 :
381 0 : r.out.info = &info;
382 0 : r.out.info_type = &info_type;
383 :
384 0 : status = dcerpc_drsuapi_DsReplicaGetInfo_r(p->binding_handle, tctx, &r);
385 0 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsReplicaGetInfo");
386 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
387 0 : torture_comment(tctx,
388 : "DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
389 : array[i].level, array[i].infotype);
390 : } else {
391 0 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsReplicaGetInfo");
392 : }
393 : }
394 :
395 0 : return true;
396 : }
397 :
398 1 : static bool test_DsReplicaSync(struct torture_context *tctx,
399 : struct DsPrivate *priv)
400 : {
401 0 : NTSTATUS status;
402 1 : struct dcerpc_pipe *p = priv->drs_pipe;
403 0 : int i;
404 0 : struct drsuapi_DsReplicaSync r;
405 0 : union drsuapi_DsReplicaSyncRequest sync_req;
406 0 : struct drsuapi_DsReplicaObjectIdentifier nc;
407 0 : struct dom_sid null_sid;
408 0 : struct {
409 : int32_t level;
410 1 : } array[] = {
411 : {
412 : 1
413 : }
414 : };
415 :
416 1 : if (!torture_setting_bool(tctx, "dangerous", false)) {
417 1 : torture_comment(tctx, "DsReplicaSync disabled - enable dangerous tests to use\n");
418 1 : return true;
419 : }
420 :
421 0 : if (torture_setting_bool(tctx, "samba4", false)) {
422 0 : torture_comment(tctx, "skipping DsReplicaSync test against Samba4\n");
423 0 : return true;
424 : }
425 :
426 0 : ZERO_STRUCT(null_sid);
427 :
428 0 : r.in.bind_handle = &priv->bind_handle;
429 :
430 0 : for (i=0; i < ARRAY_SIZE(array); i++) {
431 0 : torture_comment(tctx, "Testing DsReplicaSync level %d\n",
432 : array[i].level);
433 :
434 0 : r.in.level = array[i].level;
435 0 : switch(r.in.level) {
436 0 : case 1:
437 0 : nc.guid = GUID_zero();
438 0 : nc.sid = null_sid;
439 0 : nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
440 :
441 0 : sync_req.req1.naming_context = &nc;
442 0 : sync_req.req1.source_dsa_guid = priv->dcinfo.ntds_guid;
443 0 : sync_req.req1.source_dsa_dns = NULL;
444 0 : sync_req.req1.options = 16;
445 :
446 0 : r.in.req = &sync_req;
447 0 : break;
448 : }
449 :
450 0 : status = dcerpc_drsuapi_DsReplicaSync_r(p->binding_handle, tctx, &r);
451 0 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsReplicaSync");
452 : }
453 :
454 0 : return true;
455 : }
456 :
457 1 : static bool test_DsReplicaUpdateRefs(struct torture_context *tctx,
458 : struct DsPrivate *priv)
459 : {
460 0 : NTSTATUS status;
461 1 : struct dcerpc_pipe *p = priv->drs_pipe;
462 0 : struct drsuapi_DsReplicaUpdateRefs r;
463 0 : struct drsuapi_DsReplicaObjectIdentifier nc;
464 0 : struct GUID dest_dsa_guid;
465 0 : const char *dest_dsa_guid_str;
466 0 : struct dom_sid null_sid;
467 :
468 1 : ZERO_STRUCT(null_sid);
469 1 : dest_dsa_guid = GUID_random();
470 1 : dest_dsa_guid_str = GUID_string(tctx, &dest_dsa_guid);
471 :
472 1 : r.in.bind_handle = &priv->bind_handle;
473 1 : r.in.level = 1; /* Only version 1 is defined presently */
474 :
475 : /* setup NC */
476 1 : nc.guid = priv->domain_obj_dn ? GUID_zero():priv->domain_guid;
477 1 : nc.sid = null_sid;
478 1 : nc.dn = priv->domain_obj_dn ? priv->domain_obj_dn : "";
479 :
480 : /* default setup for request */
481 1 : r.in.req.req1.naming_context = &nc;
482 1 : r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(tctx, "%s._msdn.%s",
483 : dest_dsa_guid_str,
484 : priv->domain_dns_name);
485 1 : r.in.req.req1.dest_dsa_guid = dest_dsa_guid;
486 :
487 : /* 1. deleting replica dest should fail */
488 1 : torture_comment(tctx, "delete: %s\n", r.in.req.req1.dest_dsa_dns_name);
489 1 : r.in.req.req1.options = DRSUAPI_DRS_DEL_REF;
490 1 : status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
491 1 : torture_drsuapi_assert_call_werr(tctx, p,
492 : status, WERR_DS_DRA_REF_NOT_FOUND, &r,
493 : "dcerpc_drsuapi_DsReplicaUpdateRefs");
494 :
495 : /* 2. hopefully adding random replica dest should succeed */
496 1 : torture_comment(tctx, "add : %s\n", r.in.req.req1.dest_dsa_dns_name);
497 1 : r.in.req.req1.options = DRSUAPI_DRS_ADD_REF;
498 1 : status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
499 1 : torture_drsuapi_assert_call_werr(tctx, p,
500 : status, WERR_OK, &r,
501 : "dcerpc_drsuapi_DsReplicaUpdateRefs");
502 :
503 : /* 3. try adding same replica dest - should fail */
504 1 : torture_comment(tctx, "add : %s\n", r.in.req.req1.dest_dsa_dns_name);
505 1 : r.in.req.req1.options = DRSUAPI_DRS_ADD_REF;
506 1 : status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
507 1 : torture_drsuapi_assert_call_werr(tctx, p,
508 : status, WERR_DS_DRA_REF_ALREADY_EXISTS, &r,
509 : "dcerpc_drsuapi_DsReplicaUpdateRefs");
510 :
511 : /* 4. try resetting same replica dest - should succeed */
512 1 : torture_comment(tctx, "reset : %s\n", r.in.req.req1.dest_dsa_dns_name);
513 1 : r.in.req.req1.options = DRSUAPI_DRS_DEL_REF | DRSUAPI_DRS_ADD_REF;
514 1 : status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
515 1 : torture_drsuapi_assert_call_werr(tctx, p,
516 : status, WERR_OK, &r,
517 : "dcerpc_drsuapi_DsReplicaUpdateRefs");
518 :
519 : /* 5. delete random replicate added at step 2. */
520 1 : torture_comment(tctx, "delete : %s\n", r.in.req.req1.dest_dsa_dns_name);
521 1 : r.in.req.req1.options = DRSUAPI_DRS_DEL_REF;
522 1 : status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
523 1 : torture_drsuapi_assert_call_werr(tctx, p,
524 : status, WERR_OK, &r,
525 : "dcerpc_drsuapi_DsReplicaUpdateRefs");
526 :
527 : /* 6. try replace on non-existing replica dest - should succeed */
528 1 : torture_comment(tctx, "replace: %s\n", r.in.req.req1.dest_dsa_dns_name);
529 1 : r.in.req.req1.options = DRSUAPI_DRS_DEL_REF | DRSUAPI_DRS_ADD_REF;
530 1 : status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
531 1 : torture_drsuapi_assert_call_werr(tctx, p,
532 : status, WERR_OK, &r,
533 : "dcerpc_drsuapi_DsReplicaUpdateRefs");
534 :
535 : /* 7. delete random replicate added at step 6. */
536 1 : torture_comment(tctx, "delete : %s\n", r.in.req.req1.dest_dsa_dns_name);
537 1 : r.in.req.req1.options = DRSUAPI_DRS_DEL_REF;
538 1 : status = dcerpc_drsuapi_DsReplicaUpdateRefs_r(p->binding_handle, tctx, &r);
539 1 : torture_drsuapi_assert_call_werr(tctx, p,
540 : status, WERR_OK, &r,
541 : "dcerpc_drsuapi_DsReplicaUpdateRefs");
542 :
543 1 : return true;
544 : }
545 :
546 1 : static bool test_DsGetNCChanges(struct torture_context *tctx,
547 : struct DsPrivate *priv)
548 : {
549 0 : NTSTATUS status;
550 1 : struct dcerpc_pipe *p = priv->drs_pipe;
551 0 : int i;
552 0 : struct drsuapi_DsGetNCChanges r;
553 0 : union drsuapi_DsGetNCChangesRequest req;
554 0 : union drsuapi_DsGetNCChangesCtr ctr;
555 0 : struct drsuapi_DsReplicaObjectIdentifier nc;
556 0 : struct dom_sid null_sid;
557 0 : uint32_t level_out;
558 0 : struct {
559 : uint32_t level;
560 1 : } array[] = {
561 : {
562 : 5
563 : },
564 : {
565 : 8
566 : }
567 : };
568 :
569 1 : if (torture_setting_bool(tctx, "samba4", false)) {
570 1 : torture_comment(tctx, "skipping DsGetNCChanges test against Samba4\n");
571 1 : return true;
572 : }
573 :
574 0 : ZERO_STRUCT(null_sid);
575 :
576 0 : for (i=0; i < ARRAY_SIZE(array); i++) {
577 0 : torture_comment(tctx,
578 : "Testing DsGetNCChanges level %d\n",
579 : array[i].level);
580 :
581 0 : r.in.bind_handle = &priv->bind_handle;
582 0 : r.in.level = array[i].level;
583 0 : r.out.level_out = &level_out;
584 0 : r.out.ctr = &ctr;
585 :
586 0 : switch (r.in.level) {
587 0 : case 5:
588 0 : nc.guid = GUID_zero();
589 0 : nc.sid = null_sid;
590 0 : nc.dn = priv->domain_obj_dn ? priv->domain_obj_dn : "";
591 :
592 0 : r.in.req = &req;
593 0 : r.in.req->req5.destination_dsa_guid = GUID_random();
594 0 : r.in.req->req5.source_dsa_invocation_id = GUID_zero();
595 0 : r.in.req->req5.naming_context = &nc;
596 0 : r.in.req->req5.highwatermark.tmp_highest_usn = 0;
597 0 : r.in.req->req5.highwatermark.reserved_usn = 0;
598 0 : r.in.req->req5.highwatermark.highest_usn = 0;
599 0 : r.in.req->req5.uptodateness_vector = NULL;
600 0 : r.in.req->req5.replica_flags = 0;
601 0 : if (lpcfg_parm_bool(tctx->lp_ctx, NULL, "drsuapi", "compression", false)) {
602 0 : r.in.req->req5.replica_flags |= DRSUAPI_DRS_USE_COMPRESSION;
603 : }
604 0 : r.in.req->req5.max_object_count = 0;
605 0 : r.in.req->req5.max_ndr_size = 0;
606 0 : r.in.req->req5.extended_op = DRSUAPI_EXOP_NONE;
607 0 : r.in.req->req5.fsmo_info = 0;
608 :
609 0 : break;
610 0 : case 8:
611 0 : nc.guid = GUID_zero();
612 0 : nc.sid = null_sid;
613 0 : nc.dn = priv->domain_obj_dn ? priv->domain_obj_dn : "";
614 :
615 0 : r.in.req = &req;
616 0 : r.in.req->req8.destination_dsa_guid = GUID_random();
617 0 : r.in.req->req8.source_dsa_invocation_id = GUID_zero();
618 0 : r.in.req->req8.naming_context = &nc;
619 0 : r.in.req->req8.highwatermark.tmp_highest_usn = 0;
620 0 : r.in.req->req8.highwatermark.reserved_usn = 0;
621 0 : r.in.req->req8.highwatermark.highest_usn = 0;
622 0 : r.in.req->req8.uptodateness_vector = NULL;
623 0 : r.in.req->req8.replica_flags = 0;
624 0 : if (lpcfg_parm_bool(tctx->lp_ctx, NULL, "drsuapi", "compression", false)) {
625 0 : r.in.req->req8.replica_flags |= DRSUAPI_DRS_USE_COMPRESSION;
626 : }
627 0 : if (lpcfg_parm_bool(tctx->lp_ctx, NULL, "drsuapi", "neighbour_writeable", true)) {
628 0 : r.in.req->req8.replica_flags |= DRSUAPI_DRS_WRIT_REP;
629 : }
630 0 : r.in.req->req8.replica_flags |= DRSUAPI_DRS_INIT_SYNC
631 : | DRSUAPI_DRS_PER_SYNC
632 : | DRSUAPI_DRS_GET_ANC
633 : | DRSUAPI_DRS_NEVER_SYNCED
634 : ;
635 0 : r.in.req->req8.max_object_count = 402;
636 0 : r.in.req->req8.max_ndr_size = 402116;
637 0 : r.in.req->req8.extended_op = DRSUAPI_EXOP_NONE;
638 0 : r.in.req->req8.fsmo_info = 0;
639 0 : r.in.req->req8.partial_attribute_set = NULL;
640 0 : r.in.req->req8.partial_attribute_set_ex = NULL;
641 0 : r.in.req->req8.mapping_ctr.num_mappings = 0;
642 0 : r.in.req->req8.mapping_ctr.mappings = NULL;
643 :
644 0 : break;
645 : }
646 :
647 0 : status = dcerpc_drsuapi_DsGetNCChanges_r(p->binding_handle, tctx, &r);
648 0 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsGetNCChanges");
649 : }
650 :
651 0 : return true;
652 : }
653 :
654 0 : bool test_QuerySitesByCost(struct torture_context *tctx,
655 : struct DsPrivate *priv)
656 : {
657 0 : NTSTATUS status;
658 0 : struct dcerpc_pipe *p = priv->drs_pipe;
659 0 : struct drsuapi_QuerySitesByCost r;
660 0 : union drsuapi_QuerySitesByCostRequest req;
661 :
662 0 : const char *my_site = "Default-First-Site-Name";
663 0 : const char *remote_site1 = "smbtorture-nonexisting-site1";
664 0 : const char *remote_site2 = "smbtorture-nonexisting-site2";
665 :
666 0 : req.req1.site_from = talloc_strdup(tctx, my_site);
667 0 : req.req1.num_req = 2;
668 0 : req.req1.site_to = talloc_zero_array(tctx, const char *, 2);
669 0 : req.req1.site_to[0] = talloc_strdup(tctx, remote_site1);
670 0 : req.req1.site_to[1] = talloc_strdup(tctx, remote_site2);
671 0 : req.req1.flags = 0;
672 :
673 0 : r.in.bind_handle = &priv->bind_handle;
674 0 : r.in.level = 1;
675 0 : r.in.req = &req;
676 :
677 0 : status = dcerpc_drsuapi_QuerySitesByCost_r(p->binding_handle, tctx, &r);
678 0 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_QuerySitesByCost");
679 :
680 0 : if (W_ERROR_IS_OK(r.out.result)) {
681 0 : torture_assert_werr_equal(tctx,
682 : r.out.ctr->ctr1.info[0].error_code, WERR_DS_OBJ_NOT_FOUND,
683 : "dcerpc_drsuapi_QuerySitesByCost");
684 0 : torture_assert_werr_equal(tctx,
685 : r.out.ctr->ctr1.info[1].error_code, WERR_DS_OBJ_NOT_FOUND,
686 : "dcerpc_drsuapi_QuerySitesByCost expected error_code WERR_DS_OBJ_NOT_FOUND");
687 :
688 0 : torture_assert_int_equal(tctx,
689 : r.out.ctr->ctr1.info[0].site_cost, -1,
690 : "dcerpc_drsuapi_QuerySitesByCost");
691 0 : torture_assert_int_equal(tctx,
692 : r.out.ctr->ctr1.info[1].site_cost, -1,
693 : "dcerpc_drsuapi_QuerySitesByCost expected site cost");
694 : }
695 :
696 0 : return true;
697 :
698 :
699 : }
700 :
701 0 : bool test_DsUnbind(struct dcerpc_pipe *p,
702 : struct torture_context *tctx,
703 : struct DsPrivate *priv)
704 : {
705 0 : NTSTATUS status;
706 0 : struct drsuapi_DsUnbind r;
707 :
708 0 : r.in.bind_handle = &priv->bind_handle;
709 0 : r.out.bind_handle = &priv->bind_handle;
710 :
711 0 : torture_comment(tctx, "Testing DsUnbind\n");
712 :
713 0 : status = dcerpc_drsuapi_DsUnbind_r(p->binding_handle, tctx, &r);
714 0 : torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsUnbind");
715 :
716 0 : return true;
717 : }
718 :
719 :
720 : /**
721 : * Helper func to collect DC information for testing purposes.
722 : * This function is almost identical to test_DsGetDomainControllerInfo
723 : */
724 2 : bool torture_rpc_drsuapi_get_dcinfo(struct torture_context *torture,
725 : struct DsPrivate *priv)
726 : {
727 0 : NTSTATUS status;
728 2 : int32_t level_out = 0;
729 0 : struct drsuapi_DsGetDomainControllerInfo r;
730 0 : union drsuapi_DsGetDCInfoCtr ctr;
731 0 : int j, k;
732 4 : const char *names[] = {
733 2 : torture_join_dom_netbios_name(priv->join),
734 2 : torture_join_dom_dns_name(priv->join)};
735 :
736 2 : for (j=0; j < ARRAY_SIZE(names); j++) {
737 0 : union drsuapi_DsGetDCInfoRequest req;
738 2 : struct dcerpc_binding_handle *b = priv->drs_pipe->binding_handle;
739 2 : r.in.bind_handle = &priv->bind_handle;
740 2 : r.in.level = 1;
741 2 : r.in.req = &req;
742 :
743 2 : r.in.req->req1.domain_name = names[j];
744 2 : r.in.req->req1.level = 2;
745 :
746 2 : r.out.ctr = &ctr;
747 2 : r.out.level_out = &level_out;
748 :
749 2 : status = dcerpc_drsuapi_DsGetDomainControllerInfo_r(b, torture, &r);
750 2 : if (!NT_STATUS_IS_OK(status)) {
751 0 : continue;
752 : }
753 2 : if (!W_ERROR_IS_OK(r.out.result)) {
754 : /* If this was an error, we can't read the result structure */
755 0 : continue;
756 : }
757 :
758 2 : for (k=0; k < r.out.ctr->ctr2.count; k++) {
759 2 : if (strcasecmp_m(r.out.ctr->ctr2.array[k].netbios_name,
760 : torture_join_netbios_name(priv->join)) == 0) {
761 2 : priv->dcinfo = r.out.ctr->ctr2.array[k];
762 2 : return true;
763 : }
764 : }
765 : }
766 :
767 0 : return false;
768 : }
769 :
770 : /**
771 : * Common test case setup function to be used
772 : * in DRS suit of test when appropriate
773 : */
774 4 : bool torture_drsuapi_tcase_setup_common(struct torture_context *tctx, struct DsPrivate *priv)
775 : {
776 0 : NTSTATUS status;
777 4 : int rnd = rand() % 1000;
778 4 : char *name = talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, rnd);
779 :
780 4 : torture_assert(tctx, priv, "Invalid argument");
781 :
782 4 : priv->admin_credentials = samba_cmdline_get_creds();
783 :
784 4 : torture_comment(tctx, "Create DRSUAPI pipe\n");
785 4 : status = torture_rpc_connection(tctx,
786 : &priv->drs_pipe,
787 : &ndr_table_drsuapi);
788 4 : torture_assert(tctx, NT_STATUS_IS_OK(status), "Unable to connect to DRSUAPI pipe");
789 :
790 4 : torture_comment(tctx, "About to join domain with name %s\n", name);
791 4 : priv->join = torture_join_domain(tctx, name, ACB_SVRTRUST,
792 : &priv->dc_credentials);
793 4 : torture_assert(tctx, priv->join, "Failed to join as BDC");
794 :
795 4 : if (!test_DsBind(priv->drs_pipe, tctx,
796 : &priv->bind_handle,
797 : &priv->srv_bind_info))
798 : {
799 : /* clean up */
800 2 : torture_drsuapi_tcase_teardown_common(tctx, priv);
801 2 : torture_fail(tctx, "Failed execute test_DsBind()");
802 : }
803 :
804 : /* try collect some information for testing */
805 2 : torture_rpc_drsuapi_get_dcinfo(tctx, priv);
806 :
807 2 : return true;
808 : }
809 :
810 : /**
811 : * Common test case teardown function to be used
812 : * in DRS suit of test when appropriate
813 : */
814 4 : bool torture_drsuapi_tcase_teardown_common(struct torture_context *tctx, struct DsPrivate *priv)
815 : {
816 4 : if (priv->join) {
817 4 : torture_leave_domain(tctx, priv->join);
818 : }
819 :
820 4 : return true;
821 : }
822 :
823 : /**
824 : * Test case setup for DRSUAPI test case
825 : */
826 3 : static bool torture_drsuapi_tcase_setup(struct torture_context *tctx, void **data)
827 : {
828 0 : struct DsPrivate *priv;
829 :
830 3 : *data = priv = talloc_zero(tctx, struct DsPrivate);
831 :
832 3 : return torture_drsuapi_tcase_setup_common(tctx, priv);
833 : }
834 :
835 : /**
836 : * Test case tear-down for DRSUAPI test case
837 : */
838 1 : static bool torture_drsuapi_tcase_teardown(struct torture_context *tctx, void *data)
839 : {
840 0 : bool ret;
841 1 : struct DsPrivate *priv = talloc_get_type(data, struct DsPrivate);
842 :
843 1 : ret = torture_drsuapi_tcase_teardown_common(tctx, priv);
844 :
845 1 : talloc_free(priv);
846 1 : return ret;
847 : }
848 :
849 3 : static bool __test_DsBind_assoc_group(struct torture_context *tctx,
850 : const char *testname,
851 : struct DsPrivate *priv,
852 : struct cli_credentials *creds)
853 : {
854 0 : NTSTATUS status;
855 0 : const char *err_msg;
856 0 : struct drsuapi_DsCrackNames r;
857 0 : union drsuapi_DsNameRequest req;
858 0 : uint32_t level_out;
859 0 : union drsuapi_DsNameCtr ctr;
860 0 : struct drsuapi_DsNameString names[1];
861 3 : const char *dom_sid = NULL;
862 3 : struct dcerpc_pipe *p1 = NULL;
863 3 : struct dcerpc_pipe *p2 = NULL;
864 3 : TALLOC_CTX *mem_ctx = priv;
865 3 : struct dcerpc_binding *binding = NULL;
866 3 : struct policy_handle ds_bind_handle = { .handle_type = 0, };
867 :
868 3 : torture_comment(tctx, "%s: starting...\n", testname);
869 :
870 3 : torture_assert_ntstatus_ok(tctx,
871 : torture_rpc_binding(tctx, &binding),
872 : "torture_rpc_binding");
873 :
874 3 : torture_assert_ntstatus_ok(tctx,
875 : dcerpc_pipe_connect_b(tctx,
876 : &p1,
877 : binding,
878 : &ndr_table_drsuapi,
879 : creds,
880 : tctx->ev,
881 : tctx->lp_ctx),
882 : "connect p1");
883 :
884 3 : torture_assert_ntstatus_ok(tctx,
885 : dcerpc_pipe_connect_b(tctx,
886 : &p2,
887 : p1->binding,
888 : &ndr_table_drsuapi,
889 : creds,
890 : tctx->ev,
891 : tctx->lp_ctx),
892 : "connect p2");
893 :
894 3 : torture_assert(tctx, test_DsBind(p1, tctx, &ds_bind_handle, NULL), "DsBind");
895 :
896 3 : ZERO_STRUCT(r);
897 3 : r.in.bind_handle = &ds_bind_handle;
898 3 : r.in.level = 1;
899 3 : r.in.req = &req;
900 3 : r.in.req->req1.codepage = 1252; /* german */
901 3 : r.in.req->req1.language = 0x00000407; /* german */
902 3 : r.in.req->req1.count = 1;
903 3 : r.in.req->req1.names = names;
904 3 : r.in.req->req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
905 :
906 3 : r.in.req->req1.format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
907 3 : r.in.req->req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
908 :
909 3 : r.out.level_out = &level_out;
910 3 : r.out.ctr = &ctr;
911 :
912 3 : dom_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join));
913 :
914 3 : names[0].str = dom_sid;
915 :
916 3 : torture_comment(tctx, "Testing DsCrackNames on p1 with name '%s'"
917 : " offered format: %d desired format:%d\n",
918 : names[0].str,
919 3 : r.in.req->req1.format_offered,
920 3 : r.in.req->req1.format_desired);
921 3 : status = dcerpc_drsuapi_DsCrackNames_r(p1->binding_handle, mem_ctx, &r);
922 3 : if (!NT_STATUS_IS_OK(status)) {
923 0 : const char *errstr = nt_errstr(status);
924 0 : err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
925 0 : torture_fail(tctx, err_msg);
926 3 : } else if (!W_ERROR_IS_OK(r.out.result)) {
927 0 : err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
928 0 : torture_fail(tctx, err_msg);
929 3 : } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
930 0 : err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
931 0 : r.out.ctr->ctr1->array[0].status);
932 0 : torture_fail(tctx, err_msg);
933 : }
934 :
935 3 : torture_comment(tctx, "Testing DsCrackNames on p2 with name '%s'"
936 : " offered format: %d desired format:%d\n",
937 : names[0].str,
938 3 : r.in.req->req1.format_offered,
939 3 : r.in.req->req1.format_desired);
940 3 : status = dcerpc_drsuapi_DsCrackNames_r(p2->binding_handle, mem_ctx, &r);
941 3 : if (!NT_STATUS_IS_OK(status)) {
942 0 : const char *errstr = nt_errstr(status);
943 0 : err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
944 0 : torture_fail(tctx, err_msg);
945 3 : } else if (!W_ERROR_IS_OK(r.out.result)) {
946 0 : err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
947 0 : torture_fail(tctx, err_msg);
948 3 : } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
949 0 : err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
950 0 : r.out.ctr->ctr1->array[0].status);
951 0 : torture_fail(tctx, err_msg);
952 : }
953 :
954 3 : TALLOC_FREE(p1);
955 :
956 3 : torture_comment(tctx, "Testing DsCrackNames on p2 (with p1 closed) with name '%s'"
957 : " offered format: %d desired format:%d\n",
958 : names[0].str,
959 3 : r.in.req->req1.format_offered,
960 3 : r.in.req->req1.format_desired);
961 3 : status = dcerpc_drsuapi_DsCrackNames_r(p2->binding_handle, mem_ctx, &r);
962 3 : if (!NT_STATUS_IS_OK(status)) {
963 0 : const char *errstr = nt_errstr(status);
964 0 : err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
965 0 : torture_fail(tctx, err_msg);
966 3 : } else if (!W_ERROR_IS_OK(r.out.result)) {
967 0 : err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
968 0 : torture_fail(tctx, err_msg);
969 3 : } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
970 0 : err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
971 0 : r.out.ctr->ctr1->array[0].status);
972 0 : torture_fail(tctx, err_msg);
973 : }
974 :
975 3 : torture_comment(tctx, "%s: ... finished\n", testname);
976 3 : return true;
977 : }
978 :
979 1 : static bool test_DsBindAssocGroupAdmin(struct torture_context *tctx,
980 : struct DsPrivate *priv,
981 : struct cli_credentials *creds)
982 : {
983 1 : return __test_DsBind_assoc_group(tctx, __func__, priv,
984 : priv->admin_credentials);
985 : }
986 :
987 1 : static bool test_DsBindAssocGroupDC(struct torture_context *tctx,
988 : struct DsPrivate *priv,
989 : struct cli_credentials *creds)
990 : {
991 1 : return __test_DsBind_assoc_group(tctx, __func__, priv,
992 : priv->dc_credentials);
993 : }
994 :
995 1 : static bool test_DsBindAssocGroupWS(struct torture_context *tctx,
996 : struct DsPrivate *priv,
997 : struct cli_credentials *creds)
998 : {
999 1 : struct test_join *wks_join = NULL;
1000 1 : struct cli_credentials *wks_credentials = NULL;
1001 1 : int rnd = rand() % 1000;
1002 1 : char *wks_name = talloc_asprintf(tctx, "WKS%s%d", TEST_MACHINE_NAME, rnd);
1003 0 : bool ret;
1004 :
1005 1 : torture_comment(tctx, "%s: About to join workstation with name %s\n",
1006 : __func__, wks_name);
1007 1 : wks_join = torture_join_domain(tctx, wks_name, ACB_WSTRUST,
1008 : &wks_credentials);
1009 1 : torture_assert(tctx, wks_join, "Failed to join as WORKSTATION");
1010 1 : ret = __test_DsBind_assoc_group(tctx, __func__, priv,
1011 : wks_credentials);
1012 1 : torture_leave_domain(tctx, wks_join);
1013 1 : return ret;
1014 : }
1015 :
1016 : /**
1017 : * DRSUAPI test case implementation
1018 : */
1019 2354 : void torture_rpc_drsuapi_tcase(struct torture_suite *suite)
1020 : {
1021 125 : typedef bool (*run_func) (struct torture_context *test, void *tcase_data);
1022 :
1023 2354 : struct torture_tcase *tcase = torture_suite_add_tcase(suite, "drsuapi");
1024 :
1025 2354 : torture_tcase_set_fixture(tcase, torture_drsuapi_tcase_setup,
1026 : torture_drsuapi_tcase_teardown);
1027 :
1028 : #if 0
1029 : test = torture_tcase_add_simple_test(tcase, "QuerySitesByCost", (run_func)test_QuerySitesByCost);
1030 : #endif
1031 :
1032 2354 : torture_tcase_add_simple_test(tcase, "DsGetDomainControllerInfo", (run_func)test_DsGetDomainControllerInfo);
1033 :
1034 2354 : torture_tcase_add_simple_test(tcase, "DsCrackNames", (run_func)test_DsCrackNames);
1035 :
1036 2354 : torture_tcase_add_simple_test(tcase, "DsWriteAccountSpn", (run_func)test_DsWriteAccountSpn);
1037 :
1038 2354 : torture_tcase_add_simple_test(tcase, "DsReplicaGetInfo", (run_func)test_DsReplicaGetInfo);
1039 :
1040 2354 : torture_tcase_add_simple_test(tcase, "DsReplicaSync", (run_func)test_DsReplicaSync);
1041 :
1042 2354 : torture_tcase_add_simple_test(tcase, "DsReplicaUpdateRefs", (run_func)test_DsReplicaUpdateRefs);
1043 :
1044 2354 : torture_tcase_add_simple_test(tcase, "DsGetNCChanges", (run_func)test_DsGetNCChanges);
1045 :
1046 2354 : torture_tcase_add_simple_test(tcase, "DsBindAssocGroupAdmin", (run_func)test_DsBindAssocGroupAdmin);
1047 2354 : torture_tcase_add_simple_test(tcase, "DsBindAssocGroupDC", (run_func)test_DsBindAssocGroupDC);
1048 2354 : torture_tcase_add_simple_test(tcase, "DsBindAssocGroupWS", (run_func)test_DsBindAssocGroupWS);
1049 2354 : }
|