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 "librpc/gen_ndr/ndr_drsuapi_c.h"
26 #include "torture/rpc/torture_rpc.h"
27 #include "param/param.h"
29 #define TEST_MACHINE_NAME "torturetest"
32 * DsBind as sent from W2K8 Client.
33 * This should work regardless of functional level, and accept
36 bool test_DsBind_w2k8(struct torture_context
*tctx
,
37 struct DsPrivate_w2k8
*priv
)
40 struct dcerpc_pipe
*p
= priv
->drs_pipe
;
41 struct drsuapi_DsBind r
;
42 struct drsuapi_DsBindInfo48
*bind_info48
;
43 struct drsuapi_DsBindInfoCtr bind_info_ctr
;
46 ZERO_STRUCT(bind_info_ctr
);
47 bind_info_ctr
.length
= 48;
49 bind_info48
= &bind_info_ctr
.info
.info48
;
50 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_BASE
;
51 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION
;
52 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI
;
53 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2
;
54 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS
;
55 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1
;
56 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION
;
57 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE
;
58 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2
;
59 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION
;
60 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2
;
61 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD
;
62 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND
;
63 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO
;
64 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION
;
65 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01
;
66 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP
;
67 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY
;
68 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3
;
69 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2
;
70 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6
;
71 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS
;
72 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8
;
73 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5
;
74 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6
;
75 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3
;
76 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7
;
77 bind_info48
->supported_extensions
|= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT
;
80 * We wish for DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2,
81 * needed for DsGetDomainControllerInfo level 3
83 bind_info48
->supported_extensions_ext
|= DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2
;
85 GUID_from_string(DRSUAPI_DS_BIND_GUID
, &priv
->bind_guid
);
87 r
.in
.bind_guid
= &priv
->bind_guid
;
88 r
.in
.bind_info
= &bind_info_ctr
;
89 r
.out
.bind_handle
= &priv
->bind_handle
;
91 torture_comment(tctx
, "Testing DsBind W2K8\n");
93 status
= dcerpc_drsuapi_DsBind_r(p
->binding_handle
, tctx
, &r
);
94 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsBind");
96 torture_assert_not_null(tctx
, r
.out
.bind_info
,
97 "DsBind with info48 results in NULL");
99 /* cache server supported extensions, i.e. bind_info */
100 priv
->srv_bind_info
= *r
.out
.bind_info
;
103 * We do not check for length here, because it should be valid to return
110 static bool test_DsGetDomainControllerInfo_w2k8(struct torture_context
*tctx
,
111 struct DsPrivate_w2k8
*priv
)
114 struct dcerpc_pipe
*p
= priv
->drs_pipe
;
115 struct drsuapi_DsGetDomainControllerInfo r
;
116 union drsuapi_DsGetDCInfoCtr ctr
;
117 int32_t level_out
= 0;
118 uint32_t supported_extensions_ext
= 0;
127 .name
= torture_join_dom_netbios_name(priv
->join
),
131 .name
= torture_join_dom_dns_name(priv
->join
),
135 .name
= "__UNKNOWN_DOMAIN__",
136 .expected
= WERR_DS_OBJ_NOT_FOUND
139 .name
= "unknown.domain.samba.example.com",
140 .expected
= WERR_DS_OBJ_NOT_FOUND
144 /* Levels 1 and 2 are tested in standard drsuapi tests */
148 if (!test_DsBind_w2k8(tctx
, priv
)) {
153 * We used DsBind_w2k8, so DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2
154 * should mean support for level 3
158 * We are looking for an extension found in info32 and later
160 switch (priv
->srv_bind_info
.length
) {
162 supported_extensions_ext
= priv
->srv_bind_info
.info
.info32
.supported_extensions_ext
;
165 supported_extensions_ext
= priv
->srv_bind_info
.info
.info48
.supported_extensions_ext
;
168 supported_extensions_ext
= 0;
172 supported_extensions_ext
&= DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2
;
173 torture_assert(tctx
, (supported_extensions_ext
> 0),
174 "Server does not support DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2");
176 for (j
=0; j
< ARRAY_SIZE(names
); j
++) {
177 union drsuapi_DsGetDCInfoRequest req
;
178 r
.in
.bind_handle
= &priv
->bind_handle
;
182 r
.in
.req
->req1
.domain_name
= names
[j
].name
;
183 r
.in
.req
->req1
.level
= level
;
186 r
.out
.level_out
= &level_out
;
188 torture_comment(tctx
,
189 "Testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
190 r
.in
.req
->req1
.level
, r
.in
.req
->req1
.domain_name
);
192 status
= dcerpc_drsuapi_DsGetDomainControllerInfo_r(p
->binding_handle
, tctx
, &r
);
193 torture_assert_ntstatus_ok(tctx
, status
,
194 "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
195 torture_assert_werr_equal(tctx
, r
.out
.result
, names
[j
].expected
,
196 "DsGetDomainControllerInfo level with dns domain failed");
198 if (!W_ERROR_IS_OK(r
.out
.result
)) {
199 /* If this was an error, we can't read the result structure */
203 torture_assert_int_equal(tctx
, r
.in
.req
->req1
.level
, *r
.out
.level_out
,
204 "dcerpc_drsuapi_DsGetDomainControllerInfo in/out level differs");
206 for (k
=0; k
< r
.out
.ctr
->ctr3
.count
; k
++) {
207 if (strcasecmp_m(r
.out
.ctr
->ctr3
.array
[k
].netbios_name
,
208 torture_join_netbios_name(priv
->join
)) == 0) {
210 priv
->dcinfo
= r
.out
.ctr
->ctr3
.array
[k
];
216 torture_assert(tctx
, found
,
217 "dcerpc_drsuapi_DsGetDomainControllerInfo: Failed to find the domain controller we just created during the join");
224 bool test_DsUnbind_w2k8(struct torture_context
*tctx
,
225 struct DsPrivate_w2k8
*priv
)
228 struct dcerpc_pipe
*p
= priv
->drs_pipe
;
229 struct drsuapi_DsUnbind r
;
231 r
.in
.bind_handle
= &priv
->bind_handle
;
232 r
.out
.bind_handle
= &priv
->bind_handle
;
234 torture_comment(tctx
, "Testing DsUnbind W2K8\n");
236 status
= dcerpc_drsuapi_DsUnbind_r(p
->binding_handle
, tctx
, &r
);
237 torture_drsuapi_assert_call(tctx
, p
, status
, &r
, "dcerpc_drsuapi_DsUnbind");
243 * Common test case setup function to be used
244 * in DRS suit of test when appropriate
246 bool torture_drsuapi_w2k8_tcase_setup_common(struct torture_context
*tctx
,
247 struct DsPrivate_w2k8
*priv
)
250 int rnd
= rand() % 1000;
251 char *name
= talloc_asprintf(tctx
, "%s%d", TEST_MACHINE_NAME
, rnd
);
252 struct cli_credentials
*machine_credentials
;
254 torture_assert(tctx
, priv
, "Invalid argument");
256 torture_comment(tctx
, "Create DRSUAPI pipe\n");
257 status
= torture_rpc_connection(tctx
,
260 torture_assert(tctx
, NT_STATUS_IS_OK(status
), "Unable to connect to DRSUAPI pipe");
262 torture_comment(tctx
, "About to join domain with name %s\n", name
);
263 priv
->join
= torture_join_domain(tctx
, name
, ACB_SVRTRUST
,
264 &machine_credentials
);
265 torture_assert(tctx
, priv
->join
, "Failed to join as BDC");
268 * After that every test should use DsBind and DsGetDomainControllerInfo
270 if (!test_DsBind_w2k8(tctx
, priv
)) {
272 torture_drsuapi_w2k8_tcase_teardown_common(tctx
, priv
);
273 torture_fail(tctx
, "Failed execute test_DsBind_w2k8()");
281 * Common test case teardown function to be used
282 * in DRS suit of test when appropriate
284 bool torture_drsuapi_w2k8_tcase_teardown_common(struct torture_context
*tctx
,
285 struct DsPrivate_w2k8
*priv
)
288 torture_leave_domain(tctx
, priv
->join
);
295 * Test case setup for DRSUAPI test case
297 static bool torture_drsuapi_w2k8_tcase_setup(struct torture_context
*tctx
, void **data
)
299 struct DsPrivate_w2k8
*priv
;
301 *data
= priv
= talloc_zero(tctx
, struct DsPrivate_w2k8
);
303 return torture_drsuapi_w2k8_tcase_setup_common(tctx
, priv
);
307 * Test case tear-down for DRSUAPI test case
309 static bool torture_drsuapi_w2k8_tcase_teardown(struct torture_context
*tctx
, void *data
)
312 struct DsPrivate_w2k8
*priv
= talloc_get_type(data
, struct DsPrivate_w2k8
);
314 ret
= torture_drsuapi_w2k8_tcase_teardown_common(tctx
, priv
);
321 * DRSUAPI test case implementation
323 void torture_rpc_drsuapi_w2k8_tcase(struct torture_suite
*suite
)
325 typedef bool (*run_func
) (struct torture_context
*test
, void *tcase_data
);
327 struct torture_tcase
*tcase
= torture_suite_add_tcase(suite
, "drsuapi_w2k8");
329 torture_tcase_set_fixture(tcase
, torture_drsuapi_w2k8_tcase_setup
,
330 torture_drsuapi_w2k8_tcase_teardown
);
332 torture_tcase_add_simple_test(tcase
, "DsBind_W2K8", (run_func
)test_DsBind_w2k8
);
333 torture_tcase_add_simple_test(tcase
, "DsGetDomainControllerInfo_W2K8", (run_func
)test_DsGetDomainControllerInfo_w2k8
);