2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Stefan (metze) Metzmacher 2004
8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006
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.
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.
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/>.
25 #include "torture/torture.h"
26 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
27 #include "torture/rpc/rpc.h"
28 #include "param/param.h"
30 #define TEST_MACHINE_NAME "torturetest"
32 bool test_DsBind(struct dcerpc_pipe
*p
,
33 struct torture_context
*tctx
,
34 struct DsPrivate
*priv
)
37 struct drsuapi_DsBind r
;
39 GUID_from_string(DRSUAPI_DS_BIND_GUID
, &priv
->bind_guid
);
41 r
.in
.bind_guid
= &priv
->bind_guid
;
42 r
.in
.bind_info
= NULL
;
43 r
.out
.bind_handle
= &priv
->bind_handle
;
45 torture_comment(tctx
, "testing DsBind\n");
47 status
= dcerpc_drsuapi_DsBind(p
, tctx
, &r
);
48 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsBind");
53 static bool test_DsGetDomainControllerInfo(struct dcerpc_pipe
*p
,
54 struct torture_context
*tctx
,
55 struct DsPrivate
*priv
)
58 struct drsuapi_DsGetDomainControllerInfo r
;
59 union drsuapi_DsGetDCInfoCtr ctr
;
60 int32_t level_out
= 0;
69 .name
= torture_join_dom_netbios_name(priv
->join
),
73 .name
= torture_join_dom_dns_name(priv
->join
),
77 .name
= "__UNKNOWN_DOMAIN__",
78 .expected
= WERR_DS_OBJ_NOT_FOUND
81 .name
= "unknown.domain.samba.example.com",
82 .expected
= WERR_DS_OBJ_NOT_FOUND
85 int levels
[] = {1, 2};
88 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
89 for (j
=0; j
< ARRAY_SIZE(names
); j
++) {
90 union drsuapi_DsGetDCInfoRequest req
;
92 r
.in
.bind_handle
= &priv
->bind_handle
;
96 r
.in
.req
->req1
.domain_name
= names
[j
].name
;
97 r
.in
.req
->req1
.level
= level
;
100 r
.out
.level_out
= &level_out
;
102 torture_comment(tctx
,
103 "testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
104 r
.in
.req
->req1
.level
, r
.in
.req
->req1
.domain_name
);
106 status
= dcerpc_drsuapi_DsGetDomainControllerInfo(p
, tctx
, &r
);
107 torture_assert_ntstatus_ok(tctx
, status
,
108 "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
109 torture_assert_werr_equal(tctx
,
110 r
.out
.result
, names
[j
].expected
,
111 "DsGetDomainControllerInfo level with dns domain failed");
113 if (!W_ERROR_IS_OK(r
.out
.result
)) {
114 /* If this was an error, we can't read the result structure */
118 torture_assert_int_equal(tctx
,
119 r
.in
.req
->req1
.level
, *r
.out
.level_out
,
120 "dcerpc_drsuapi_DsGetDomainControllerInfo in/out level differs");
124 for (k
=0; k
< r
.out
.ctr
->ctr1
.count
; k
++) {
125 if (strcasecmp_m(r
.out
.ctr
->ctr1
.array
[k
].netbios_name
,
126 torture_join_netbios_name(priv
->join
)) == 0) {
133 for (k
=0; k
< r
.out
.ctr
->ctr2
.count
; k
++) {
134 if (strcasecmp_m(r
.out
.ctr
->ctr2
.array
[k
].netbios_name
,
135 torture_join_netbios_name(priv
->join
)) == 0) {
137 priv
->dcinfo
= r
.out
.ctr
->ctr2
.array
[k
];
143 torture_assert(tctx
, found
,
144 "dcerpc_drsuapi_DsGetDomainControllerInfo: Failed to find the domain controller we just created during the join");
148 r
.in
.bind_handle
= &priv
->bind_handle
;
152 r
.out
.level_out
= &level_out
;
154 r
.in
.req
->req1
.domain_name
= "__UNKNOWN_DOMAIN__"; /* This is clearly ignored for this level */
155 r
.in
.req
->req1
.level
= -1;
157 torture_comment(tctx
, "testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
158 r
.in
.req
->req1
.level
, r
.in
.req
->req1
.domain_name
);
160 status
= dcerpc_drsuapi_DsGetDomainControllerInfo(p
, tctx
, &r
);
162 torture_assert_ntstatus_ok(tctx
, status
,
163 "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
164 torture_assert_werr_ok(tctx
, r
.out
.result
,
165 "DsGetDomainControllerInfo with dns domain failed");
168 const char *dc_account
= talloc_asprintf(tctx
, "%s\\%s$",
169 torture_join_dom_netbios_name(priv
->join
),
170 priv
->dcinfo
.netbios_name
);
171 torture_comment(tctx
, "%s: Enum active LDAP sessions searching for %s\n", __func__
, dc_account
);
172 for (k
=0; k
< r
.out
.ctr
->ctr01
.count
; k
++) {
173 if (strcasecmp_m(r
.out
.ctr
->ctr01
.array
[k
].client_account
,
179 torture_assert(tctx
, found
,
180 "dcerpc_drsuapi_DsGetDomainControllerInfo level: Failed to find the domain controller in last logon records");
187 static bool test_DsWriteAccountSpn(struct dcerpc_pipe
*p
,
188 struct torture_context
*tctx
,
189 struct DsPrivate
*priv
)
192 struct drsuapi_DsWriteAccountSpn r
;
193 union drsuapi_DsWriteAccountSpnRequest req
;
194 struct drsuapi_DsNameString names
[2];
195 union drsuapi_DsWriteAccountSpnResult res
;
198 r
.in
.bind_handle
= &priv
->bind_handle
;
202 torture_comment(tctx
, "testing DsWriteAccountSpn\n");
204 r
.in
.req
->req1
.operation
= DRSUAPI_DS_SPN_OPERATION_ADD
;
205 r
.in
.req
->req1
.unknown1
= 0;
206 r
.in
.req
->req1
.object_dn
= priv
->dcinfo
.computer_dn
;
207 r
.in
.req
->req1
.count
= 2;
208 r
.in
.req
->req1
.spn_names
= names
;
209 names
[0].str
= talloc_asprintf(tctx
, "smbtortureSPN/%s",priv
->dcinfo
.netbios_name
);
210 names
[1].str
= talloc_asprintf(tctx
, "smbtortureSPN/%s",priv
->dcinfo
.dns_name
);
213 r
.out
.level_out
= &level_out
;
215 status
= dcerpc_drsuapi_DsWriteAccountSpn(p
, tctx
, &r
);
216 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsWriteAccountSpn");
218 r
.in
.req
->req1
.operation
= DRSUAPI_DS_SPN_OPERATION_DELETE
;
219 r
.in
.req
->req1
.unknown1
= 0;
221 status
= dcerpc_drsuapi_DsWriteAccountSpn(p
, tctx
, &r
);
222 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsWriteAccountSpn");
227 static bool test_DsReplicaGetInfo(struct dcerpc_pipe
*p
,
228 struct torture_context
*tctx
,
229 struct DsPrivate
*priv
)
232 struct drsuapi_DsReplicaGetInfo r
;
233 union drsuapi_DsReplicaGetInfoRequest req
;
234 union drsuapi_DsReplicaInfo info
;
235 enum drsuapi_DsReplicaInfoType info_type
;
243 DRSUAPI_DS_REPLICA_GET_INFO
,
244 DRSUAPI_DS_REPLICA_INFO_NEIGHBORS
,
247 DRSUAPI_DS_REPLICA_GET_INFO
,
248 DRSUAPI_DS_REPLICA_INFO_CURSORS
,
251 DRSUAPI_DS_REPLICA_GET_INFO
,
252 DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA
,
255 DRSUAPI_DS_REPLICA_GET_INFO
,
256 DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES
,
259 DRSUAPI_DS_REPLICA_GET_INFO
,
260 DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES
,
263 DRSUAPI_DS_REPLICA_GET_INFO
,
264 DRSUAPI_DS_REPLICA_INFO_PENDING_OPS
,
267 DRSUAPI_DS_REPLICA_GET_INFO2
,
268 DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA
,
271 DRSUAPI_DS_REPLICA_GET_INFO2
,
272 DRSUAPI_DS_REPLICA_INFO_CURSORS2
,
275 DRSUAPI_DS_REPLICA_GET_INFO2
,
276 DRSUAPI_DS_REPLICA_INFO_CURSORS3
,
279 DRSUAPI_DS_REPLICA_GET_INFO2
,
280 DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2
,
283 DRSUAPI_DS_REPLICA_GET_INFO2
,
284 DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2
,
287 DRSUAPI_DS_REPLICA_GET_INFO2
,
288 DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02
,
291 DRSUAPI_DS_REPLICA_GET_INFO2
,
292 DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04
,
295 DRSUAPI_DS_REPLICA_GET_INFO2
,
296 DRSUAPI_DS_REPLICA_INFO_CURSORS05
,
299 DRSUAPI_DS_REPLICA_GET_INFO2
,
300 DRSUAPI_DS_REPLICA_INFO_06
,
305 if (torture_setting_bool(tctx
, "samba4", false)) {
306 torture_comment(tctx
, "skipping DsReplicaGetInfo test against Samba4\n");
310 r
.in
.bind_handle
= &priv
->bind_handle
;
313 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
314 const char *object_dn
;
316 torture_comment(tctx
, "testing DsReplicaGetInfo level %d infotype %d\n",
317 array
[i
].level
, array
[i
].infotype
);
319 object_dn
= (array
[i
].obj_dn
? array
[i
].obj_dn
: priv
->domain_obj_dn
);
321 r
.in
.level
= array
[i
].level
;
323 case DRSUAPI_DS_REPLICA_GET_INFO
:
324 r
.in
.req
->req1
.info_type
= array
[i
].infotype
;
325 r
.in
.req
->req1
.object_dn
= object_dn
;
326 ZERO_STRUCT(r
.in
.req
->req1
.guid1
);
328 case DRSUAPI_DS_REPLICA_GET_INFO2
:
329 r
.in
.req
->req2
.info_type
= array
[i
].infotype
;
330 r
.in
.req
->req2
.object_dn
= object_dn
;
331 ZERO_STRUCT(r
.in
.req
->req2
.guid1
);
332 r
.in
.req
->req2
.unknown1
= 0;
333 r
.in
.req
->req2
.string1
= NULL
;
334 r
.in
.req
->req2
.string2
= NULL
;
335 r
.in
.req
->req2
.unknown2
= 0;
340 r
.out
.info_type
= &info_type
;
342 status
= dcerpc_drsuapi_DsReplicaGetInfo(p
, tctx
, &r
);
343 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsReplicaGetInfo");
344 if (!NT_STATUS_IS_OK(status
) && p
->last_fault_code
== DCERPC_FAULT_INVALID_TAG
) {
345 torture_comment(tctx
,
346 "DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
347 array
[i
].level
, array
[i
].infotype
);
349 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsReplicaGetInfo");
356 static bool test_DsReplicaSync(struct dcerpc_pipe
*p
,
357 struct torture_context
*tctx
,
358 struct DsPrivate
*priv
)
362 struct drsuapi_DsReplicaSync r
;
363 struct drsuapi_DsReplicaObjectIdentifier nc
;
364 struct GUID null_guid
;
365 struct dom_sid null_sid
;
374 if (!torture_setting_bool(tctx
, "dangerous", false)) {
375 torture_comment(tctx
, "DsReplicaSync disabled - enable dangerous tests to use\n");
379 if (torture_setting_bool(tctx
, "samba4", false)) {
380 torture_comment(tctx
, "skipping DsReplicaSync test against Samba4\n");
384 ZERO_STRUCT(null_guid
);
385 ZERO_STRUCT(null_sid
);
387 r
.in
.bind_handle
= &priv
->bind_handle
;
389 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
390 torture_comment(tctx
, "testing DsReplicaSync level %d\n",
393 r
.in
.level
= array
[i
].level
;
398 nc
.dn
= priv
->domain_obj_dn
?priv
->domain_obj_dn
:"";
400 r
.in
.req
.req1
.naming_context
= &nc
;
401 r
.in
.req
.req1
.source_dsa_guid
= priv
->dcinfo
.ntds_guid
;
402 r
.in
.req
.req1
.other_info
= NULL
;
403 r
.in
.req
.req1
.options
= 16;
407 status
= dcerpc_drsuapi_DsReplicaSync(p
, tctx
, &r
);
408 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsReplicaSync");
414 static bool test_DsReplicaUpdateRefs(struct dcerpc_pipe
*p
,
415 struct torture_context
*tctx
,
416 struct DsPrivate
*priv
)
420 struct drsuapi_DsReplicaUpdateRefs r
;
421 struct drsuapi_DsReplicaObjectIdentifier nc
;
422 struct GUID null_guid
;
423 struct dom_sid null_sid
;
432 if (torture_setting_bool(tctx
, "samba4", false)) {
433 torture_comment(tctx
, "skipping DsReplicaUpdateRefs test against Samba4\n");
437 ZERO_STRUCT(null_guid
);
438 ZERO_STRUCT(null_sid
);
440 r
.in
.bind_handle
= &priv
->bind_handle
;
442 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
443 torture_comment(tctx
, "testing DsReplicaUpdateRefs level %d\n",
446 r
.in
.level
= array
[i
].level
;
451 nc
.dn
= priv
->domain_obj_dn
? priv
->domain_obj_dn
: "";
453 r
.in
.req
.req1
.naming_context
= &nc
;
454 r
.in
.req
.req1
.dest_dsa_dns_name
= talloc_asprintf(tctx
, "__some_dest_dsa_guid_string._msdn.%s",
455 priv
->domain_dns_name
);
456 r
.in
.req
.req1
.dest_dsa_guid
= null_guid
;
457 r
.in
.req
.req1
.options
= 0;
461 status
= dcerpc_drsuapi_DsReplicaUpdateRefs(p
, tctx
, &r
);
462 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsReplicaUpdateRefs");
468 static bool test_DsGetNCChanges(struct dcerpc_pipe
*p
,
469 struct torture_context
*tctx
,
470 struct DsPrivate
*priv
)
474 struct drsuapi_DsGetNCChanges r
;
475 union drsuapi_DsGetNCChangesRequest req
;
476 union drsuapi_DsGetNCChangesCtr ctr
;
477 struct drsuapi_DsReplicaObjectIdentifier nc
;
478 struct GUID null_guid
;
479 struct dom_sid null_sid
;
492 if (torture_setting_bool(tctx
, "samba4", false)) {
493 torture_comment(tctx
, "skipping DsGetNCChanges test against Samba4\n");
497 ZERO_STRUCT(null_guid
);
498 ZERO_STRUCT(null_sid
);
500 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
501 torture_comment(tctx
,
502 "testing DsGetNCChanges level %d\n",
505 r
.in
.bind_handle
= &priv
->bind_handle
;
506 r
.in
.level
= array
[i
].level
;
507 r
.out
.level_out
= &level_out
;
510 switch (r
.in
.level
) {
514 nc
.dn
= priv
->domain_obj_dn
? priv
->domain_obj_dn
: "";
517 r
.in
.req
->req5
.destination_dsa_guid
= GUID_random();
518 r
.in
.req
->req5
.source_dsa_invocation_id
= null_guid
;
519 r
.in
.req
->req5
.naming_context
= &nc
;
520 r
.in
.req
->req5
.highwatermark
.tmp_highest_usn
= 0;
521 r
.in
.req
->req5
.highwatermark
.reserved_usn
= 0;
522 r
.in
.req
->req5
.highwatermark
.highest_usn
= 0;
523 r
.in
.req
->req5
.uptodateness_vector
= NULL
;
524 r
.in
.req
->req5
.replica_flags
= 0;
525 if (lp_parm_bool(tctx
->lp_ctx
, NULL
, "drsuapi", "compression", false)) {
526 r
.in
.req
->req5
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES
;
528 r
.in
.req
->req5
.max_object_count
= 0;
529 r
.in
.req
->req5
.max_ndr_size
= 0;
530 r
.in
.req
->req5
.extended_op
= DRSUAPI_EXOP_NONE
;
531 r
.in
.req
->req5
.fsmo_info
= 0;
537 nc
.dn
= priv
->domain_obj_dn
? priv
->domain_obj_dn
: "";
540 r
.in
.req
->req8
.destination_dsa_guid
= GUID_random();
541 r
.in
.req
->req8
.source_dsa_invocation_id
= null_guid
;
542 r
.in
.req
->req8
.naming_context
= &nc
;
543 r
.in
.req
->req8
.highwatermark
.tmp_highest_usn
= 0;
544 r
.in
.req
->req8
.highwatermark
.reserved_usn
= 0;
545 r
.in
.req
->req8
.highwatermark
.highest_usn
= 0;
546 r
.in
.req
->req8
.uptodateness_vector
= NULL
;
547 r
.in
.req
->req8
.replica_flags
= 0;
548 if (lp_parm_bool(tctx
->lp_ctx
, NULL
, "drsuapi", "compression", false)) {
549 r
.in
.req
->req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES
;
551 if (lp_parm_bool(tctx
->lp_ctx
, NULL
, "drsuapi", "neighbour_writeable", true)) {
552 r
.in
.req
->req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
;
554 r
.in
.req
->req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
555 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
556 | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
557 | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
559 r
.in
.req
->req8
.max_object_count
= 402;
560 r
.in
.req
->req8
.max_ndr_size
= 402116;
561 r
.in
.req
->req8
.extended_op
= DRSUAPI_EXOP_NONE
;
562 r
.in
.req
->req8
.fsmo_info
= 0;
563 r
.in
.req
->req8
.partial_attribute_set
= NULL
;
564 r
.in
.req
->req8
.partial_attribute_set_ex
= NULL
;
565 r
.in
.req
->req8
.mapping_ctr
.num_mappings
= 0;
566 r
.in
.req
->req8
.mapping_ctr
.mappings
= NULL
;
571 status
= dcerpc_drsuapi_DsGetNCChanges(p
, tctx
, &r
);
572 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsGetNCChanges");
578 bool test_QuerySitesByCost(struct dcerpc_pipe
*p
,
579 struct torture_context
*tctx
,
580 struct DsPrivate
*priv
)
583 struct drsuapi_QuerySitesByCost r
;
584 union drsuapi_QuerySitesByCostRequest req
;
586 const char *my_site
= "Default-First-Site-Name";
587 const char *remote_site1
= "smbtorture-nonexisting-site1";
588 const char *remote_site2
= "smbtorture-nonexisting-site2";
590 req
.req1
.site_from
= talloc_strdup(tctx
, my_site
);
591 req
.req1
.num_req
= 2;
592 req
.req1
.site_to
= talloc_zero_array(tctx
, const char *, 2);
593 req
.req1
.site_to
[0] = talloc_strdup(tctx
, remote_site1
);
594 req
.req1
.site_to
[1] = talloc_strdup(tctx
, remote_site2
);
597 r
.in
.bind_handle
= &priv
->bind_handle
;
601 status
= dcerpc_drsuapi_QuerySitesByCost(p
, tctx
, &r
);
602 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_QuerySitesByCost");
604 if (W_ERROR_IS_OK(r
.out
.result
)) {
605 torture_assert_werr_equal(tctx
,
606 r
.out
.ctr
->ctr1
.info
[0].error_code
, WERR_DS_OBJ_NOT_FOUND
,
607 "dcerpc_drsuapi_QuerySitesByCost");
608 torture_assert_werr_equal(tctx
,
609 r
.out
.ctr
->ctr1
.info
[1].error_code
, WERR_DS_OBJ_NOT_FOUND
,
610 "dcerpc_drsuapi_QuerySitesByCost expected error_code WERR_DS_OBJ_NOT_FOUND");
612 torture_assert_int_equal(tctx
,
613 r
.out
.ctr
->ctr1
.info
[0].site_cost
, -1,
614 "dcerpc_drsuapi_QuerySitesByCost");
615 torture_assert_int_equal(tctx
,
616 r
.out
.ctr
->ctr1
.info
[1].site_cost
, -1,
617 "dcerpc_drsuapi_QuerySitesByCost exptected site cost");
625 bool test_DsUnbind(struct dcerpc_pipe
*p
,
626 struct torture_context
*tctx
,
627 struct DsPrivate
*priv
)
630 struct drsuapi_DsUnbind r
;
632 r
.in
.bind_handle
= &priv
->bind_handle
;
633 r
.out
.bind_handle
= &priv
->bind_handle
;
635 torture_comment(tctx
, "testing DsUnbind\n");
637 status
= dcerpc_drsuapi_DsUnbind(p
, tctx
, &r
);
638 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsUnbind");
643 bool torture_rpc_drsuapi(struct torture_context
*torture
)
646 struct dcerpc_pipe
*p
;
648 struct DsPrivate
*priv
;
649 struct cli_credentials
*machine_credentials
;
651 priv
= talloc_zero(torture
, struct DsPrivate
);
653 priv
->join
= torture_join_domain(torture
, TEST_MACHINE_NAME
, ACB_SVRTRUST
,
654 &machine_credentials
);
656 torture_fail(torture
, "Failed to join as BDC");
659 status
= torture_rpc_connection(torture
,
662 if (!NT_STATUS_IS_OK(status
)) {
663 torture_leave_domain(torture
, priv
->join
);
664 torture_fail(torture
, "Unable to connect to DRSUAPI pipe");
667 /* cache pipe handle */
670 ret
&= test_DsBind(p
, torture
, priv
);
672 ret
&= test_QuerySitesByCost(p
, torture
, priv
);
674 ret
&= test_DsGetDomainControllerInfo(p
, torture
, priv
);
676 ret
&= test_DsCrackNames(torture
, priv
);
678 ret
&= test_DsWriteAccountSpn(p
, torture
, priv
);
680 ret
&= test_DsReplicaGetInfo(p
, torture
, priv
);
682 ret
&= test_DsReplicaSync(p
, torture
, priv
);
684 ret
&= test_DsReplicaUpdateRefs(p
, torture
, priv
);
686 ret
&= test_DsGetNCChanges(p
, torture
, priv
);
688 ret
&= test_DsUnbind(p
, torture
, priv
);
690 torture_leave_domain(torture
, priv
->join
);
698 * Helper func to collect DC information for testing purposes.
699 * This function is almost identical to test_DsGetDomainControllerInfo
701 bool torture_rpc_drsuapi_get_dcinfo(struct torture_context
*torture
,
702 struct DsPrivate
*priv
)
705 int32_t level_out
= 0;
706 struct drsuapi_DsGetDomainControllerInfo r
;
707 union drsuapi_DsGetDCInfoCtr ctr
;
709 const char *names
[] = {
710 torture_join_dom_netbios_name(priv
->join
),
711 torture_join_dom_dns_name(priv
->join
)};
713 for (j
=0; j
< ARRAY_SIZE(names
); j
++) {
714 union drsuapi_DsGetDCInfoRequest req
;
715 r
.in
.bind_handle
= &priv
->bind_handle
;
719 r
.in
.req
->req1
.domain_name
= names
[j
];
720 r
.in
.req
->req1
.level
= 2;
723 r
.out
.level_out
= &level_out
;
725 status
= dcerpc_drsuapi_DsGetDomainControllerInfo(priv
->pipe
, torture
, &r
);
726 if (!NT_STATUS_IS_OK(status
)) {
729 if (!W_ERROR_IS_OK(r
.out
.result
)) {
730 /* If this was an error, we can't read the result structure */
734 for (k
=0; k
< r
.out
.ctr
->ctr2
.count
; k
++) {
735 if (strcasecmp_m(r
.out
.ctr
->ctr2
.array
[k
].netbios_name
,
736 torture_join_netbios_name(priv
->join
)) == 0) {
737 priv
->dcinfo
= r
.out
.ctr
->ctr2
.array
[k
];
747 * Common test case setup function to be used
748 * in DRS suit of test when appropriate
750 bool torture_drsuapi_tcase_setup_common(struct torture_context
*tctx
, struct DsPrivate
*priv
)
753 struct cli_credentials
*machine_credentials
;
755 torture_assert(tctx
, priv
, "Invalid argument");
757 torture_comment(tctx
, "Create DRSUAPI pipe\n");
758 status
= torture_rpc_connection(tctx
,
761 torture_assert(tctx
, NT_STATUS_IS_OK(status
), "Unable to connect to DRSUAPI pipe");
763 torture_comment(tctx
, "About to join domain\n");
764 priv
->join
= torture_join_domain(tctx
, TEST_MACHINE_NAME
, ACB_SVRTRUST
,
765 &machine_credentials
);
766 torture_assert(tctx
, priv
->join
, "Failed to join as BDC");
768 if (!test_DsBind(priv
->pipe
, tctx
, priv
)) {
770 torture_drsuapi_tcase_teardown_common(tctx
, priv
);
771 torture_fail(tctx
, "Failed execute test_DsBind()");
774 /* try collect some information for testing */
775 torture_rpc_drsuapi_get_dcinfo(tctx
, priv
);
781 * Common test case teardown function to be used
782 * in DRS suit of test when appropriate
784 bool torture_drsuapi_tcase_teardown_common(struct torture_context
*tctx
, struct DsPrivate
*priv
)
787 torture_leave_domain(tctx
, priv
->join
);