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
, struct torture_context
*tctx
,
33 struct DsPrivate
*priv
)
36 struct drsuapi_DsBind r
;
38 GUID_from_string(DRSUAPI_DS_BIND_GUID
, &priv
->bind_guid
);
40 r
.in
.bind_guid
= &priv
->bind_guid
;
41 r
.in
.bind_info
= NULL
;
42 r
.out
.bind_handle
= &priv
->bind_handle
;
44 torture_comment(tctx
, "testing DsBind\n");
46 status
= dcerpc_drsuapi_DsBind(p
, tctx
, &r
);
47 if (!NT_STATUS_IS_OK(status
)) {
48 const char *errstr
= nt_errstr(status
);
49 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
50 errstr
= dcerpc_errstr(tctx
, p
->last_fault_code
);
52 torture_fail(tctx
, "dcerpc_drsuapi_DsBind failed");
53 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
54 torture_fail(tctx
, "DsBind failed");
60 static bool test_DsGetDomainControllerInfo(struct dcerpc_pipe
*p
, struct torture_context
*torture
,
61 struct DsPrivate
*priv
)
64 struct drsuapi_DsGetDomainControllerInfo r
;
65 union drsuapi_DsGetDCInfoCtr ctr
;
66 int32_t level_out
= 0;
75 .name
= torture_join_dom_netbios_name(priv
->join
),
79 .name
= torture_join_dom_dns_name(priv
->join
),
83 .name
= "__UNKNOWN_DOMAIN__",
84 .expected
= WERR_DS_OBJ_NOT_FOUND
87 .name
= "unknown.domain.samba.example.com",
88 .expected
= WERR_DS_OBJ_NOT_FOUND
91 int levels
[] = {1, 2};
94 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
95 for (j
=0; j
< ARRAY_SIZE(names
); j
++) {
96 union drsuapi_DsGetDCInfoRequest req
;
98 r
.in
.bind_handle
= &priv
->bind_handle
;
102 r
.in
.req
->req1
.domain_name
= names
[j
].name
;
103 r
.in
.req
->req1
.level
= level
;
106 r
.out
.level_out
= &level_out
;
108 torture_comment(torture
,
109 "testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
110 r
.in
.req
->req1
.level
, r
.in
.req
->req1
.domain_name
);
112 status
= dcerpc_drsuapi_DsGetDomainControllerInfo(p
, torture
, &r
);
113 torture_assert_ntstatus_ok(torture
, status
,
114 "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
115 torture_assert_werr_equal(torture
,
116 r
.out
.result
, names
[j
].expected
,
117 "DsGetDomainControllerInfo level with dns domain failed");
119 if (!W_ERROR_IS_OK(r
.out
.result
)) {
120 /* If this was an error, we can't read the result structure */
124 torture_assert_int_equal(torture
,
125 r
.in
.req
->req1
.level
, *r
.out
.level_out
,
126 "dcerpc_drsuapi_DsGetDomainControllerInfo level");
130 for (k
=0; k
< r
.out
.ctr
->ctr1
.count
; k
++) {
131 if (strcasecmp_m(r
.out
.ctr
->ctr1
.array
[k
].netbios_name
,
132 torture_join_netbios_name(priv
->join
)) == 0) {
139 for (k
=0; k
< r
.out
.ctr
->ctr2
.count
; k
++) {
140 if (strcasecmp_m(r
.out
.ctr
->ctr2
.array
[k
].netbios_name
,
141 torture_join_netbios_name(priv
->join
)) == 0) {
143 priv
->dcinfo
= r
.out
.ctr
->ctr2
.array
[k
];
149 torture_assert(torture
, found
,
150 "dcerpc_drsuapi_DsGetDomainControllerInfo: Failed to find the domain controller we just created during the join");
154 r
.in
.bind_handle
= &priv
->bind_handle
;
158 r
.out
.level_out
= &level_out
;
160 r
.in
.req
->req1
.domain_name
= "__UNKNOWN_DOMAIN__"; /* This is clearly ignored for this level */
161 r
.in
.req
->req1
.level
= -1;
163 printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
164 r
.in
.req
->req1
.level
, r
.in
.req
->req1
.domain_name
);
166 status
= dcerpc_drsuapi_DsGetDomainControllerInfo(p
, torture
, &r
);
168 torture_assert_ntstatus_ok(torture
, status
,
169 "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
170 torture_assert_werr_ok(torture
, r
.out
.result
,
171 "DsGetDomainControllerInfo with dns domain failed");
174 const char *dc_account
= talloc_asprintf(torture
, "%s\\%s$",
175 torture_join_dom_netbios_name(priv
->join
),
176 priv
->dcinfo
.netbios_name
);
177 for (k
=0; k
< r
.out
.ctr
->ctr01
.count
; k
++) {
178 if (strcasecmp_m(r
.out
.ctr
->ctr01
.array
[k
].client_account
,
184 torture_assert(torture
, found
,
185 "dcerpc_drsuapi_DsGetDomainControllerInfo level: Failed to find the domain controller in last logon records");
192 static bool test_DsWriteAccountSpn(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
193 struct DsPrivate
*priv
)
196 struct drsuapi_DsWriteAccountSpn r
;
197 union drsuapi_DsWriteAccountSpnRequest req
;
198 struct drsuapi_DsNameString names
[2];
199 union drsuapi_DsWriteAccountSpnResult res
;
203 r
.in
.bind_handle
= &priv
->bind_handle
;
207 printf("testing DsWriteAccountSpn\n");
209 r
.in
.req
->req1
.operation
= DRSUAPI_DS_SPN_OPERATION_ADD
;
210 r
.in
.req
->req1
.unknown1
= 0;
211 r
.in
.req
->req1
.object_dn
= priv
->dcinfo
.computer_dn
;
212 r
.in
.req
->req1
.count
= 2;
213 r
.in
.req
->req1
.spn_names
= names
;
214 names
[0].str
= talloc_asprintf(mem_ctx
, "smbtortureSPN/%s",priv
->dcinfo
.netbios_name
);
215 names
[1].str
= talloc_asprintf(mem_ctx
, "smbtortureSPN/%s",priv
->dcinfo
.dns_name
);
218 r
.out
.level_out
= &level_out
;
220 status
= dcerpc_drsuapi_DsWriteAccountSpn(p
, mem_ctx
, &r
);
221 if (!NT_STATUS_IS_OK(status
)) {
222 const char *errstr
= nt_errstr(status
);
223 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
224 errstr
= dcerpc_errstr(mem_ctx
, p
->last_fault_code
);
226 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr
);
228 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
229 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r
.out
.result
));
233 r
.in
.req
->req1
.operation
= DRSUAPI_DS_SPN_OPERATION_DELETE
;
234 r
.in
.req
->req1
.unknown1
= 0;
236 status
= dcerpc_drsuapi_DsWriteAccountSpn(p
, mem_ctx
, &r
);
237 if (!NT_STATUS_IS_OK(status
)) {
238 const char *errstr
= nt_errstr(status
);
239 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
240 errstr
= dcerpc_errstr(mem_ctx
, p
->last_fault_code
);
242 printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr
);
244 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
245 printf("DsWriteAccountSpn failed - %s\n", win_errstr(r
.out
.result
));
252 static bool test_DsReplicaGetInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
253 struct DsPrivate
*priv
)
256 struct drsuapi_DsReplicaGetInfo r
;
257 union drsuapi_DsReplicaGetInfoRequest req
;
258 union drsuapi_DsReplicaInfo info
;
259 enum drsuapi_DsReplicaInfoType info_type
;
268 DRSUAPI_DS_REPLICA_GET_INFO
,
269 DRSUAPI_DS_REPLICA_INFO_NEIGHBORS
,
272 DRSUAPI_DS_REPLICA_GET_INFO
,
273 DRSUAPI_DS_REPLICA_INFO_CURSORS
,
276 DRSUAPI_DS_REPLICA_GET_INFO
,
277 DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA
,
280 DRSUAPI_DS_REPLICA_GET_INFO
,
281 DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES
,
284 DRSUAPI_DS_REPLICA_GET_INFO
,
285 DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES
,
288 DRSUAPI_DS_REPLICA_GET_INFO
,
289 DRSUAPI_DS_REPLICA_INFO_PENDING_OPS
,
292 DRSUAPI_DS_REPLICA_GET_INFO2
,
293 DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA
,
296 DRSUAPI_DS_REPLICA_GET_INFO2
,
297 DRSUAPI_DS_REPLICA_INFO_CURSORS2
,
300 DRSUAPI_DS_REPLICA_GET_INFO2
,
301 DRSUAPI_DS_REPLICA_INFO_CURSORS3
,
304 DRSUAPI_DS_REPLICA_GET_INFO2
,
305 DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2
,
308 DRSUAPI_DS_REPLICA_GET_INFO2
,
309 DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2
,
312 DRSUAPI_DS_REPLICA_GET_INFO2
,
313 DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02
,
316 DRSUAPI_DS_REPLICA_GET_INFO2
,
317 DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04
,
320 DRSUAPI_DS_REPLICA_GET_INFO2
,
321 DRSUAPI_DS_REPLICA_INFO_CURSORS05
,
324 DRSUAPI_DS_REPLICA_GET_INFO2
,
325 DRSUAPI_DS_REPLICA_INFO_06
,
330 if (torture_setting_bool(tctx
, "samba4", false)) {
331 printf("skipping DsReplicaGetInfo test against Samba4\n");
335 r
.in
.bind_handle
= &priv
->bind_handle
;
338 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
339 const char *object_dn
;
341 printf("testing DsReplicaGetInfo level %d infotype %d\n",
342 array
[i
].level
, array
[i
].infotype
);
344 object_dn
= (array
[i
].obj_dn
? array
[i
].obj_dn
: priv
->domain_obj_dn
);
346 r
.in
.level
= array
[i
].level
;
348 case DRSUAPI_DS_REPLICA_GET_INFO
:
349 r
.in
.req
->req1
.info_type
= array
[i
].infotype
;
350 r
.in
.req
->req1
.object_dn
= object_dn
;
351 ZERO_STRUCT(r
.in
.req
->req1
.guid1
);
353 case DRSUAPI_DS_REPLICA_GET_INFO2
:
354 r
.in
.req
->req2
.info_type
= array
[i
].infotype
;
355 r
.in
.req
->req2
.object_dn
= object_dn
;
356 ZERO_STRUCT(r
.in
.req
->req2
.guid1
);
357 r
.in
.req
->req2
.unknown1
= 0;
358 r
.in
.req
->req2
.string1
= NULL
;
359 r
.in
.req
->req2
.string2
= NULL
;
360 r
.in
.req
->req2
.unknown2
= 0;
365 r
.out
.info_type
= &info_type
;
367 status
= dcerpc_drsuapi_DsReplicaGetInfo(p
, tctx
, &r
);
368 if (!NT_STATUS_IS_OK(status
)) {
369 const char *errstr
= nt_errstr(status
);
370 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
371 errstr
= dcerpc_errstr(tctx
, p
->last_fault_code
);
373 if (p
->last_fault_code
!= DCERPC_FAULT_INVALID_TAG
) {
374 printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr
);
377 printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
378 array
[i
].level
, array
[i
].infotype
);
380 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
381 printf("DsReplicaGetInfo failed - %s\n", win_errstr(r
.out
.result
));
389 static bool test_DsReplicaSync(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
390 struct DsPrivate
*priv
)
395 struct drsuapi_DsReplicaSync r
;
396 struct drsuapi_DsReplicaObjectIdentifier nc
;
397 struct GUID null_guid
;
398 struct dom_sid null_sid
;
407 if (!torture_setting_bool(tctx
, "dangerous", false)) {
408 printf("DsReplicaSync disabled - enable dangerous tests to use\n");
412 if (torture_setting_bool(tctx
, "samba4", false)) {
413 printf("skipping DsReplicaSync test against Samba4\n");
417 ZERO_STRUCT(null_guid
);
418 ZERO_STRUCT(null_sid
);
420 r
.in
.bind_handle
= &priv
->bind_handle
;
422 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
423 printf("testing DsReplicaSync level %d\n",
426 r
.in
.level
= array
[i
].level
;
431 nc
.dn
= priv
->domain_obj_dn
?priv
->domain_obj_dn
:"";
433 r
.in
.req
.req1
.naming_context
= &nc
;
434 r
.in
.req
.req1
.source_dsa_guid
= priv
->dcinfo
.ntds_guid
;
435 r
.in
.req
.req1
.other_info
= NULL
;
436 r
.in
.req
.req1
.options
= 16;
440 status
= dcerpc_drsuapi_DsReplicaSync(p
, tctx
, &r
);
441 if (!NT_STATUS_IS_OK(status
)) {
442 const char *errstr
= nt_errstr(status
);
443 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
444 errstr
= dcerpc_errstr(tctx
, p
->last_fault_code
);
446 printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr
);
448 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
449 printf("DsReplicaSync failed - %s\n", win_errstr(r
.out
.result
));
457 static bool test_DsReplicaUpdateRefs(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
458 struct DsPrivate
*priv
)
463 struct drsuapi_DsReplicaUpdateRefs r
;
464 struct drsuapi_DsReplicaObjectIdentifier nc
;
465 struct GUID null_guid
;
466 struct dom_sid null_sid
;
475 if (torture_setting_bool(tctx
, "samba4", false)) {
476 printf("skipping DsReplicaUpdateRefs test against Samba4\n");
480 ZERO_STRUCT(null_guid
);
481 ZERO_STRUCT(null_sid
);
483 r
.in
.bind_handle
= &priv
->bind_handle
;
485 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
486 printf("testing DsReplicaUpdateRefs level %d\n",
489 r
.in
.level
= array
[i
].level
;
494 nc
.dn
= priv
->domain_obj_dn
?priv
->domain_obj_dn
:"";
496 r
.in
.req
.req1
.naming_context
= &nc
;
497 r
.in
.req
.req1
.dest_dsa_dns_name
= talloc_asprintf(tctx
, "__some_dest_dsa_guid_string._msdn.%s",
498 priv
->domain_dns_name
);
499 r
.in
.req
.req1
.dest_dsa_guid
= null_guid
;
500 r
.in
.req
.req1
.options
= 0;
504 status
= dcerpc_drsuapi_DsReplicaUpdateRefs(p
, tctx
, &r
);
505 if (!NT_STATUS_IS_OK(status
)) {
506 const char *errstr
= nt_errstr(status
);
507 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
508 errstr
= dcerpc_errstr(tctx
, p
->last_fault_code
);
510 printf("dcerpc_drsuapi_DsReplicaUpdateRefs failed - %s\n", errstr
);
512 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
513 printf("DsReplicaUpdateRefs failed - %s\n", win_errstr(r
.out
.result
));
521 static bool test_DsGetNCChanges(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
522 struct DsPrivate
*priv
)
527 struct drsuapi_DsGetNCChanges r
;
528 union drsuapi_DsGetNCChangesRequest req
;
529 union drsuapi_DsGetNCChangesCtr ctr
;
530 struct drsuapi_DsReplicaObjectIdentifier nc
;
531 struct GUID null_guid
;
532 struct dom_sid null_sid
;
545 if (torture_setting_bool(tctx
, "samba4", false)) {
546 printf("skipping DsGetNCChanges test against Samba4\n");
550 ZERO_STRUCT(null_guid
);
551 ZERO_STRUCT(null_sid
);
553 for (i
=0; i
< ARRAY_SIZE(array
); i
++) {
554 printf("testing DsGetNCChanges level %d\n",
557 r
.in
.bind_handle
= &priv
->bind_handle
;
558 r
.in
.level
= array
[i
].level
;
559 r
.out
.level_out
= &level_out
;
562 switch (r
.in
.level
) {
566 nc
.dn
= priv
->domain_obj_dn
?priv
->domain_obj_dn
:"";
569 r
.in
.req
->req5
.destination_dsa_guid
= GUID_random();
570 r
.in
.req
->req5
.source_dsa_invocation_id
= null_guid
;
571 r
.in
.req
->req5
.naming_context
= &nc
;
572 r
.in
.req
->req5
.highwatermark
.tmp_highest_usn
= 0;
573 r
.in
.req
->req5
.highwatermark
.reserved_usn
= 0;
574 r
.in
.req
->req5
.highwatermark
.highest_usn
= 0;
575 r
.in
.req
->req5
.uptodateness_vector
= NULL
;
576 r
.in
.req
->req5
.replica_flags
= 0;
577 if (lp_parm_bool(tctx
->lp_ctx
, NULL
, "drsuapi","compression", false)) {
578 r
.in
.req
->req5
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES
;
580 r
.in
.req
->req5
.max_object_count
= 0;
581 r
.in
.req
->req5
.max_ndr_size
= 0;
582 r
.in
.req
->req5
.extended_op
= DRSUAPI_EXOP_NONE
;
583 r
.in
.req
->req5
.fsmo_info
= 0;
589 nc
.dn
= priv
->domain_obj_dn
?priv
->domain_obj_dn
:"";
592 r
.in
.req
->req8
.destination_dsa_guid
= GUID_random();
593 r
.in
.req
->req8
.source_dsa_invocation_id
= null_guid
;
594 r
.in
.req
->req8
.naming_context
= &nc
;
595 r
.in
.req
->req8
.highwatermark
.tmp_highest_usn
= 0;
596 r
.in
.req
->req8
.highwatermark
.reserved_usn
= 0;
597 r
.in
.req
->req8
.highwatermark
.highest_usn
= 0;
598 r
.in
.req
->req8
.uptodateness_vector
= NULL
;
599 r
.in
.req
->req8
.replica_flags
= 0;
600 if (lp_parm_bool(tctx
->lp_ctx
, NULL
, "drsuapi", "compression", false)) {
601 r
.in
.req
->req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES
;
603 if (lp_parm_bool(tctx
->lp_ctx
, NULL
, "drsuapi", "neighbour_writeable", true)) {
604 r
.in
.req
->req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
;
606 r
.in
.req
->req8
.replica_flags
|= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
607 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
608 | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
609 | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
611 r
.in
.req
->req8
.max_object_count
= 402;
612 r
.in
.req
->req8
.max_ndr_size
= 402116;
613 r
.in
.req
->req8
.extended_op
= DRSUAPI_EXOP_NONE
;
614 r
.in
.req
->req8
.fsmo_info
= 0;
615 r
.in
.req
->req8
.partial_attribute_set
= NULL
;
616 r
.in
.req
->req8
.partial_attribute_set_ex
= NULL
;
617 r
.in
.req
->req8
.mapping_ctr
.num_mappings
= 0;
618 r
.in
.req
->req8
.mapping_ctr
.mappings
= NULL
;
623 status
= dcerpc_drsuapi_DsGetNCChanges(p
, tctx
, &r
);
624 if (!NT_STATUS_IS_OK(status
)) {
625 const char *errstr
= nt_errstr(status
);
626 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
627 errstr
= dcerpc_errstr(tctx
, p
->last_fault_code
);
629 printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr
);
631 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
632 printf("DsGetNCChanges failed - %s\n", win_errstr(r
.out
.result
));
640 bool test_QuerySitesByCost(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
641 struct DsPrivate
*priv
)
644 struct drsuapi_QuerySitesByCost r
;
645 union drsuapi_QuerySitesByCostRequest req
;
648 const char *my_site
= "Default-First-Site-Name";
649 const char *remote_site1
= "smbtorture-nonexisting-site1";
650 const char *remote_site2
= "smbtorture-nonexisting-site2";
652 req
.req1
.site_from
= talloc_strdup(mem_ctx
, my_site
);
653 req
.req1
.num_req
= 2;
654 req
.req1
.site_to
= talloc_zero_array(mem_ctx
, const char *, 2);
655 req
.req1
.site_to
[0] = talloc_strdup(mem_ctx
, remote_site1
);
656 req
.req1
.site_to
[1] = talloc_strdup(mem_ctx
, remote_site2
);
659 r
.in
.bind_handle
= &priv
->bind_handle
;
663 status
= dcerpc_drsuapi_QuerySitesByCost(p
, mem_ctx
, &r
);
664 if (!NT_STATUS_IS_OK(status
)) {
665 const char *errstr
= nt_errstr(status
);
666 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
667 errstr
= dcerpc_errstr(mem_ctx
, p
->last_fault_code
);
669 printf("drsuapi_QuerySitesByCost - %s\n", errstr
);
671 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
672 printf("QuerySitesByCost failed - %s\n", win_errstr(r
.out
.result
));
676 if (W_ERROR_IS_OK(r
.out
.result
)) {
678 if (!W_ERROR_EQUAL(r
.out
.ctr
->ctr1
.info
[0].error_code
, WERR_DS_OBJ_NOT_FOUND
) ||
679 !W_ERROR_EQUAL(r
.out
.ctr
->ctr1
.info
[1].error_code
, WERR_DS_OBJ_NOT_FOUND
)) {
680 printf("expected error_code WERR_DS_OBJ_NOT_FOUND, got %s\n",
681 win_errstr(r
.out
.ctr
->ctr1
.info
[0].error_code
));
685 if ((r
.out
.ctr
->ctr1
.info
[0].site_cost
!= (uint32_t) -1) ||
686 (r
.out
.ctr
->ctr1
.info
[1].site_cost
!= (uint32_t) -1)) {
687 printf("expected site_cost %d, got %d\n",
688 (uint32_t) -1, r
.out
.ctr
->ctr1
.info
[0].site_cost
);
698 bool test_DsUnbind(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
699 struct DsPrivate
*priv
)
702 struct drsuapi_DsUnbind r
;
705 r
.in
.bind_handle
= &priv
->bind_handle
;
706 r
.out
.bind_handle
= &priv
->bind_handle
;
708 printf("testing DsUnbind\n");
710 status
= dcerpc_drsuapi_DsUnbind(p
, mem_ctx
, &r
);
711 if (!NT_STATUS_IS_OK(status
)) {
712 const char *errstr
= nt_errstr(status
);
713 if (NT_STATUS_EQUAL(status
, NT_STATUS_NET_WRITE_FAULT
)) {
714 errstr
= dcerpc_errstr(mem_ctx
, p
->last_fault_code
);
716 printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr
);
718 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
719 printf("DsBind failed - %s\n", win_errstr(r
.out
.result
));
726 bool torture_rpc_drsuapi(struct torture_context
*torture
)
729 struct dcerpc_pipe
*p
;
731 struct DsPrivate priv
;
732 struct cli_credentials
*machine_credentials
;
736 priv
.join
= torture_join_domain(torture
, TEST_MACHINE_NAME
, ACB_SVRTRUST
,
737 &machine_credentials
);
739 torture_fail(torture
, "Failed to join as BDC");
742 status
= torture_rpc_connection(torture
,
745 if (!NT_STATUS_IS_OK(status
)) {
746 torture_leave_domain(torture
, priv
.join
);
747 torture_fail(torture
, "Unable to connect to DRSUAPI pipe");
750 ret
&= test_DsBind(p
, torture
, &priv
);
752 ret
&= test_QuerySitesByCost(p
, torture
, &priv
);
754 ret
&= test_DsGetDomainControllerInfo(p
, torture
, &priv
);
756 ret
&= test_DsCrackNames(torture
, p
, torture
, &priv
);
758 ret
&= test_DsWriteAccountSpn(p
, torture
, &priv
);
760 ret
&= test_DsReplicaGetInfo(p
, torture
, &priv
);
762 ret
&= test_DsReplicaSync(p
, torture
, &priv
);
764 ret
&= test_DsReplicaUpdateRefs(p
, torture
, &priv
);
766 ret
&= test_DsGetNCChanges(p
, torture
, &priv
);
768 ret
&= test_DsUnbind(p
, torture
, &priv
);
770 torture_leave_domain(torture
, priv
.join
);
776 bool torture_rpc_drsuapi_cracknames(struct torture_context
*torture
)
779 struct dcerpc_pipe
*p
;
781 struct DsPrivate priv
;
782 struct cli_credentials
*machine_credentials
;
784 torture_comment(torture
, "Connected to DRSUAPI pipe\n");
788 priv
.join
= torture_join_domain(torture
, TEST_MACHINE_NAME
, ACB_SVRTRUST
,
789 &machine_credentials
);
791 torture_fail(torture
, "Failed to join as BDC\n");
794 status
= torture_rpc_connection(torture
,
797 if (!NT_STATUS_IS_OK(status
)) {
798 torture_leave_domain(torture
, priv
.join
);
799 torture_fail(torture
, "Unable to connect to DRSUAPI pipe");
802 ret
&= test_DsBind(p
, torture
, &priv
);
805 /* We don't care if this fails, we just need some info from it */
806 test_DsGetDomainControllerInfo(p
, torture
, &priv
);
808 ret
&= test_DsCrackNames(torture
, p
, torture
, &priv
);
810 ret
&= test_DsUnbind(p
, torture
, &priv
);
813 torture_leave_domain(torture
, priv
.join
);