2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
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.
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.
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/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31 #include "param/param.h"
33 #define TEST_ACCOUNT_NAME "samrtorturetest"
34 #define TEST_ALIASNAME "samrtorturetestalias"
35 #define TEST_GROUPNAME "samrtorturetestgroup"
36 #define TEST_MACHINENAME "samrtestmach$"
37 #define TEST_DOMAINNAME "samrtestdom$"
39 enum torture_samr_choice {
40 TORTURE_SAMR_PASSWORDS,
41 TORTURE_SAMR_USER_ATTRIBUTES,
45 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
46 struct policy_handle *handle);
48 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
49 struct policy_handle *handle);
51 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
52 struct policy_handle *handle);
54 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55 const char *acct_name,
56 struct policy_handle *domain_handle, char **password);
58 static void init_lsa_String(struct lsa_String *string, const char *s)
63 bool test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
64 struct policy_handle *handle)
70 r.out.handle = handle;
72 status = dcerpc_samr_Close(p, mem_ctx, &r);
73 if (!NT_STATUS_IS_OK(status)) {
74 printf("Close handle failed - %s\n", nt_errstr(status));
81 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
82 struct policy_handle *handle)
85 struct samr_Shutdown r;
87 if (!torture_setting_bool(tctx, "dangerous", false)) {
88 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
92 r.in.connect_handle = handle;
94 printf("testing samr_Shutdown\n");
96 status = dcerpc_samr_Shutdown(p, tctx, &r);
97 if (!NT_STATUS_IS_OK(status)) {
98 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
118 E_md4hash("TeSTDSRM123", hash.hash);
120 init_lsa_String(&string, "Administrator");
126 printf("testing samr_SetDsrmPassword\n");
128 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
129 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
130 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
138 static bool test_QuerySecurity(struct dcerpc_pipe *p,
139 struct torture_context *tctx,
140 struct policy_handle *handle)
143 struct samr_QuerySecurity r;
144 struct samr_SetSecurity s;
146 r.in.handle = handle;
149 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
150 if (!NT_STATUS_IS_OK(status)) {
151 printf("QuerySecurity failed - %s\n", nt_errstr(status));
155 if (r.out.sdbuf == NULL) {
159 s.in.handle = handle;
161 s.in.sdbuf = r.out.sdbuf;
163 if (torture_setting_bool(tctx, "samba4", false)) {
164 printf("skipping SetSecurity test against Samba4\n");
168 status = dcerpc_samr_SetSecurity(p, tctx, &s);
169 if (!NT_STATUS_IS_OK(status)) {
170 printf("SetSecurity failed - %s\n", nt_errstr(status));
174 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
175 if (!NT_STATUS_IS_OK(status)) {
176 printf("QuerySecurity failed - %s\n", nt_errstr(status));
184 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
185 struct policy_handle *handle, uint32_t base_acct_flags,
186 const char *base_account_name)
189 struct samr_SetUserInfo s;
190 struct samr_SetUserInfo2 s2;
191 struct samr_QueryUserInfo q;
192 struct samr_QueryUserInfo q0;
193 union samr_UserInfo u;
195 const char *test_account_name;
197 uint32_t user_extra_flags = 0;
198 if (base_acct_flags == ACB_NORMAL) {
199 /* When created, accounts are expired by default */
200 user_extra_flags = ACB_PW_EXPIRED;
203 s.in.user_handle = handle;
206 s2.in.user_handle = handle;
209 q.in.user_handle = handle;
213 #define TESTCALL(call, r) \
214 status = dcerpc_samr_ ##call(p, tctx, &r); \
215 if (!NT_STATUS_IS_OK(status)) { \
216 printf(#call " level %u failed - %s (%s)\n", \
217 r.in.level, nt_errstr(status), __location__); \
222 #define STRING_EQUAL(s1, s2, field) \
223 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
224 printf("Failed to set %s to '%s' (%s)\n", \
225 #field, s2, __location__); \
230 #define INT_EQUAL(i1, i2, field) \
232 printf("Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
233 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
238 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
239 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
241 TESTCALL(QueryUserInfo, q) \
243 s2.in.level = lvl1; \
246 ZERO_STRUCT(u.info21); \
247 u.info21.fields_present = fpval; \
249 init_lsa_String(&u.info ## lvl1.field1, value); \
250 TESTCALL(SetUserInfo, s) \
251 TESTCALL(SetUserInfo2, s2) \
252 init_lsa_String(&u.info ## lvl1.field1, ""); \
253 TESTCALL(QueryUserInfo, q); \
255 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
257 TESTCALL(QueryUserInfo, q) \
259 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
262 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
263 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
265 TESTCALL(QueryUserInfo, q) \
267 s2.in.level = lvl1; \
270 uint8_t *bits = u.info21.logon_hours.bits; \
271 ZERO_STRUCT(u.info21); \
272 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
273 u.info21.logon_hours.units_per_week = 168; \
274 u.info21.logon_hours.bits = bits; \
276 u.info21.fields_present = fpval; \
278 u.info ## lvl1.field1 = value; \
279 TESTCALL(SetUserInfo, s) \
280 TESTCALL(SetUserInfo2, s2) \
281 u.info ## lvl1.field1 = 0; \
282 TESTCALL(QueryUserInfo, q); \
284 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
286 TESTCALL(QueryUserInfo, q) \
288 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
291 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
292 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
296 do { TESTCALL(QueryUserInfo, q0) } while (0);
298 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
299 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
300 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
303 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
304 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
305 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
306 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
307 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
308 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
309 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
310 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
311 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
312 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
313 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
314 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
315 test_account_name = base_account_name;
316 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
317 SAMR_FIELD_ACCOUNT_NAME);
319 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
323 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
324 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
325 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
326 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
327 SAMR_FIELD_FULL_NAME);
329 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
333 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
334 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
335 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
336 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
337 SAMR_FIELD_FULL_NAME);
339 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
340 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
341 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
342 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
343 SAMR_FIELD_LOGON_SCRIPT);
345 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
346 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
347 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
348 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
349 SAMR_FIELD_PROFILE_PATH);
351 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
352 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
353 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
354 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
355 SAMR_FIELD_HOME_DIRECTORY);
356 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
357 SAMR_FIELD_HOME_DIRECTORY);
359 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
360 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
361 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
362 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
363 SAMR_FIELD_HOME_DRIVE);
364 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
365 SAMR_FIELD_HOME_DRIVE);
367 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
368 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
369 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
370 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
371 SAMR_FIELD_DESCRIPTION);
373 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
374 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
375 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
376 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
377 SAMR_FIELD_WORKSTATIONS);
378 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
379 SAMR_FIELD_WORKSTATIONS);
380 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
381 SAMR_FIELD_WORKSTATIONS);
382 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
383 SAMR_FIELD_WORKSTATIONS);
385 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
386 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
387 SAMR_FIELD_PARAMETERS);
388 TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
389 SAMR_FIELD_PARAMETERS);
391 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
392 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
393 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
394 SAMR_FIELD_COUNTRY_CODE);
395 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
396 SAMR_FIELD_COUNTRY_CODE);
398 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
399 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
400 SAMR_FIELD_CODE_PAGE);
401 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
402 SAMR_FIELD_CODE_PAGE);
404 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
405 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
406 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
407 SAMR_FIELD_ACCT_EXPIRY);
408 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
409 SAMR_FIELD_ACCT_EXPIRY);
410 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
411 SAMR_FIELD_ACCT_EXPIRY);
413 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
414 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
415 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
416 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
417 SAMR_FIELD_LOGON_HOURS);
419 if (torture_setting_bool(tctx, "samba4", false)) {
420 printf("skipping Set Account Flag tests against Samba4\n");
424 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
425 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
426 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
428 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
429 (base_acct_flags | ACB_DISABLED),
430 (base_acct_flags | ACB_DISABLED | user_extra_flags),
433 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
434 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
435 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
436 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
438 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
440 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
444 /* The 'autolock' flag doesn't stick - check this */
445 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
446 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
447 (base_acct_flags | ACB_DISABLED | user_extra_flags),
450 /* Removing the 'disabled' flag doesn't stick - check this */
451 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
453 (base_acct_flags | ACB_DISABLED | user_extra_flags),
456 /* The 'store plaintext' flag does stick */
457 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
458 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
459 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
461 /* The 'use DES' flag does stick */
462 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
463 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
464 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
466 /* The 'don't require kerberos pre-authentication flag does stick */
467 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
468 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
469 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
471 /* The 'no kerberos PAC required' flag sticks */
472 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
473 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
474 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
477 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
478 (base_acct_flags | ACB_DISABLED),
479 (base_acct_flags | ACB_DISABLED | user_extra_flags),
480 SAMR_FIELD_ACCT_FLAGS);
483 /* these fail with win2003 - it appears you can't set the primary gid?
484 the set succeeds, but the gid isn't changed. Very weird! */
485 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
486 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
487 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
488 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
495 generate a random password for password change tests
497 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
499 size_t len = MAX(8, min_len) + (random() % 6);
500 char *s = generate_random_str(mem_ctx, len);
501 printf("Generated password '%s'\n", s);
506 generate a random password for password change tests (fixed length)
508 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
510 char *s = generate_random_str(mem_ctx, len);
511 printf("Generated password '%s'\n", s);
515 static bool test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
516 struct policy_handle *handle, char **password)
519 struct samr_SetUserInfo s;
520 union samr_UserInfo u;
522 DATA_BLOB session_key;
524 struct samr_GetUserPwInfo pwp;
525 int policy_min_pw_len = 0;
526 pwp.in.user_handle = handle;
528 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
529 if (NT_STATUS_IS_OK(status)) {
530 policy_min_pw_len = pwp.out.info.min_password_length;
532 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
534 s.in.user_handle = handle;
538 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
539 /* w2k3 ignores this length */
540 u.info24.pw_len = strlen_m(newpass) * 2;
542 status = dcerpc_fetch_session_key(p, &session_key);
543 if (!NT_STATUS_IS_OK(status)) {
544 printf("SetUserInfo level %u - no session key - %s\n",
545 s.in.level, nt_errstr(status));
549 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
551 printf("Testing SetUserInfo level 24 (set password)\n");
553 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
554 if (!NT_STATUS_IS_OK(status)) {
555 printf("SetUserInfo level %u failed - %s\n",
556 s.in.level, nt_errstr(status));
566 static bool test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
567 struct policy_handle *handle, uint32_t fields_present,
571 struct samr_SetUserInfo s;
572 union samr_UserInfo u;
574 DATA_BLOB session_key;
576 struct samr_GetUserPwInfo pwp;
577 int policy_min_pw_len = 0;
578 pwp.in.user_handle = handle;
580 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
581 if (NT_STATUS_IS_OK(status)) {
582 policy_min_pw_len = pwp.out.info.min_password_length;
584 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
586 s.in.user_handle = handle;
592 u.info23.info.fields_present = fields_present;
594 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
596 status = dcerpc_fetch_session_key(p, &session_key);
597 if (!NT_STATUS_IS_OK(status)) {
598 printf("SetUserInfo level %u - no session key - %s\n",
599 s.in.level, nt_errstr(status));
603 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
605 printf("Testing SetUserInfo level 23 (set password)\n");
607 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
608 if (!NT_STATUS_IS_OK(status)) {
609 printf("SetUserInfo level %u failed - %s\n",
610 s.in.level, nt_errstr(status));
616 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
618 status = dcerpc_fetch_session_key(p, &session_key);
619 if (!NT_STATUS_IS_OK(status)) {
620 printf("SetUserInfo level %u - no session key - %s\n",
621 s.in.level, nt_errstr(status));
625 /* This should break the key nicely */
626 session_key.length--;
627 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
629 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
631 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
632 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
633 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
634 s.in.level, nt_errstr(status));
642 static bool test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
643 struct policy_handle *handle, bool makeshort,
647 struct samr_SetUserInfo s;
648 union samr_UserInfo u;
650 DATA_BLOB session_key;
651 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
652 uint8_t confounder[16];
654 struct MD5Context ctx;
655 struct samr_GetUserPwInfo pwp;
656 int policy_min_pw_len = 0;
657 pwp.in.user_handle = handle;
659 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
660 if (NT_STATUS_IS_OK(status)) {
661 policy_min_pw_len = pwp.out.info.min_password_length;
663 if (makeshort && policy_min_pw_len) {
664 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
666 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
669 s.in.user_handle = handle;
673 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
674 u.info26.pw_len = strlen(newpass);
676 status = dcerpc_fetch_session_key(p, &session_key);
677 if (!NT_STATUS_IS_OK(status)) {
678 printf("SetUserInfo level %u - no session key - %s\n",
679 s.in.level, nt_errstr(status));
683 generate_random_buffer((uint8_t *)confounder, 16);
686 MD5Update(&ctx, confounder, 16);
687 MD5Update(&ctx, session_key.data, session_key.length);
688 MD5Final(confounded_session_key.data, &ctx);
690 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
691 memcpy(&u.info26.password.data[516], confounder, 16);
693 printf("Testing SetUserInfo level 26 (set password ex)\n");
695 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
696 if (!NT_STATUS_IS_OK(status)) {
697 printf("SetUserInfo level %u failed - %s\n",
698 s.in.level, nt_errstr(status));
704 /* This should break the key nicely */
705 confounded_session_key.data[0]++;
707 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
708 memcpy(&u.info26.password.data[516], confounder, 16);
710 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
712 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
713 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
714 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
715 s.in.level, nt_errstr(status));
724 static bool test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
725 struct policy_handle *handle, uint32_t fields_present,
729 struct samr_SetUserInfo s;
730 union samr_UserInfo u;
732 DATA_BLOB session_key;
733 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
734 struct MD5Context ctx;
735 uint8_t confounder[16];
737 struct samr_GetUserPwInfo pwp;
738 int policy_min_pw_len = 0;
739 pwp.in.user_handle = handle;
741 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
742 if (NT_STATUS_IS_OK(status)) {
743 policy_min_pw_len = pwp.out.info.min_password_length;
745 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
747 s.in.user_handle = handle;
753 u.info25.info.fields_present = fields_present;
755 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
757 status = dcerpc_fetch_session_key(p, &session_key);
758 if (!NT_STATUS_IS_OK(status)) {
759 printf("SetUserInfo level %u - no session key - %s\n",
760 s.in.level, nt_errstr(status));
764 generate_random_buffer((uint8_t *)confounder, 16);
767 MD5Update(&ctx, confounder, 16);
768 MD5Update(&ctx, session_key.data, session_key.length);
769 MD5Final(confounded_session_key.data, &ctx);
771 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
772 memcpy(&u.info25.password.data[516], confounder, 16);
774 printf("Testing SetUserInfo level 25 (set password ex)\n");
776 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
777 if (!NT_STATUS_IS_OK(status)) {
778 printf("SetUserInfo level %u failed - %s\n",
779 s.in.level, nt_errstr(status));
785 /* This should break the key nicely */
786 confounded_session_key.data[0]++;
788 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
789 memcpy(&u.info25.password.data[516], confounder, 16);
791 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
793 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
794 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
795 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
796 s.in.level, nt_errstr(status));
803 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
804 struct policy_handle *handle)
807 struct samr_SetAliasInfo r;
808 struct samr_QueryAliasInfo q;
809 uint16_t levels[] = {2, 3};
813 /* Ignoring switch level 1, as that includes the number of members for the alias
814 * and setting this to a wrong value might have negative consequences
817 for (i=0;i<ARRAY_SIZE(levels);i++) {
818 printf("Testing SetAliasInfo level %u\n", levels[i]);
820 r.in.alias_handle = handle;
821 r.in.level = levels[i];
822 r.in.info = talloc(tctx, union samr_AliasInfo);
823 switch (r.in.level) {
824 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
825 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
826 "Test Description, should test I18N as well"); break;
829 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
830 if (!NT_STATUS_IS_OK(status)) {
831 printf("SetAliasInfo level %u failed - %s\n",
832 levels[i], nt_errstr(status));
836 q.in.alias_handle = handle;
837 q.in.level = levels[i];
839 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
840 if (!NT_STATUS_IS_OK(status)) {
841 printf("QueryAliasInfo level %u failed - %s\n",
842 levels[i], nt_errstr(status));
850 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
851 struct policy_handle *user_handle)
853 struct samr_GetGroupsForUser r;
857 printf("testing GetGroupsForUser\n");
859 r.in.user_handle = user_handle;
861 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
862 if (!NT_STATUS_IS_OK(status)) {
863 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
871 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
872 struct lsa_String *domain_name)
875 struct samr_GetDomPwInfo r;
878 r.in.domain_name = domain_name;
879 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
881 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
882 if (!NT_STATUS_IS_OK(status)) {
883 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
887 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
888 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
890 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
891 if (!NT_STATUS_IS_OK(status)) {
892 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
896 r.in.domain_name->string = "\\\\__NONAME__";
897 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
899 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
900 if (!NT_STATUS_IS_OK(status)) {
901 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
905 r.in.domain_name->string = "\\\\Builtin";
906 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
908 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
909 if (!NT_STATUS_IS_OK(status)) {
910 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
918 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
919 struct policy_handle *handle)
922 struct samr_GetUserPwInfo r;
925 printf("Testing GetUserPwInfo\n");
927 r.in.user_handle = handle;
929 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
930 if (!NT_STATUS_IS_OK(status)) {
931 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
938 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
939 struct policy_handle *domain_handle, const char *name,
943 struct samr_LookupNames n;
944 struct lsa_String sname[2];
946 init_lsa_String(&sname[0], name);
948 n.in.domain_handle = domain_handle;
951 status = dcerpc_samr_LookupNames(p, tctx, &n);
952 if (NT_STATUS_IS_OK(status)) {
953 *rid = n.out.rids.ids[0];
958 init_lsa_String(&sname[1], "xxNONAMExx");
960 status = dcerpc_samr_LookupNames(p, tctx, &n);
961 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
962 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
963 if (NT_STATUS_IS_OK(status)) {
964 return NT_STATUS_UNSUCCESSFUL;
970 status = dcerpc_samr_LookupNames(p, tctx, &n);
971 if (!NT_STATUS_IS_OK(status)) {
972 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
976 init_lsa_String(&sname[0], "xxNONAMExx");
978 status = dcerpc_samr_LookupNames(p, tctx, &n);
979 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
980 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
981 if (NT_STATUS_IS_OK(status)) {
982 return NT_STATUS_UNSUCCESSFUL;
987 init_lsa_String(&sname[0], "xxNONAMExx");
988 init_lsa_String(&sname[1], "xxNONAME2xx");
990 status = dcerpc_samr_LookupNames(p, tctx, &n);
991 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
992 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
993 if (NT_STATUS_IS_OK(status)) {
994 return NT_STATUS_UNSUCCESSFUL;
1002 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1003 struct policy_handle *domain_handle,
1004 const char *name, struct policy_handle *user_handle)
1007 struct samr_OpenUser r;
1010 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1011 if (!NT_STATUS_IS_OK(status)) {
1015 r.in.domain_handle = domain_handle;
1016 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1018 r.out.user_handle = user_handle;
1019 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1020 if (!NT_STATUS_IS_OK(status)) {
1021 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1028 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1029 struct policy_handle *handle)
1032 struct samr_ChangePasswordUser r;
1034 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1035 struct policy_handle user_handle;
1036 char *oldpass = "test";
1037 char *newpass = "test2";
1038 uint8_t old_nt_hash[16], new_nt_hash[16];
1039 uint8_t old_lm_hash[16], new_lm_hash[16];
1041 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1042 if (!NT_STATUS_IS_OK(status)) {
1046 printf("Testing ChangePasswordUser for user 'testuser'\n");
1048 printf("old password: %s\n", oldpass);
1049 printf("new password: %s\n", newpass);
1051 E_md4hash(oldpass, old_nt_hash);
1052 E_md4hash(newpass, new_nt_hash);
1053 E_deshash(oldpass, old_lm_hash);
1054 E_deshash(newpass, new_lm_hash);
1056 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1057 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1058 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1059 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1060 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1061 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1063 r.in.handle = &user_handle;
1064 r.in.lm_present = 1;
1065 r.in.old_lm_crypted = &hash1;
1066 r.in.new_lm_crypted = &hash2;
1067 r.in.nt_present = 1;
1068 r.in.old_nt_crypted = &hash3;
1069 r.in.new_nt_crypted = &hash4;
1070 r.in.cross1_present = 1;
1071 r.in.nt_cross = &hash5;
1072 r.in.cross2_present = 1;
1073 r.in.lm_cross = &hash6;
1075 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1076 if (!NT_STATUS_IS_OK(status)) {
1077 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1081 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1089 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1090 const char *acct_name,
1091 struct policy_handle *handle, char **password)
1094 struct samr_ChangePasswordUser r;
1096 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1097 struct policy_handle user_handle;
1099 uint8_t old_nt_hash[16], new_nt_hash[16];
1100 uint8_t old_lm_hash[16], new_lm_hash[16];
1101 bool changed = true;
1104 struct samr_GetUserPwInfo pwp;
1105 int policy_min_pw_len = 0;
1107 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1108 if (!NT_STATUS_IS_OK(status)) {
1111 pwp.in.user_handle = &user_handle;
1113 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1114 if (NT_STATUS_IS_OK(status)) {
1115 policy_min_pw_len = pwp.out.info.min_password_length;
1117 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1119 printf("Testing ChangePasswordUser\n");
1122 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1126 oldpass = *password;
1128 E_md4hash(oldpass, old_nt_hash);
1129 E_md4hash(newpass, new_nt_hash);
1130 E_deshash(oldpass, old_lm_hash);
1131 E_deshash(newpass, new_lm_hash);
1133 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1134 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1135 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1136 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1137 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1138 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1140 r.in.user_handle = &user_handle;
1141 r.in.lm_present = 1;
1142 /* Break the LM hash */
1144 r.in.old_lm_crypted = &hash1;
1145 r.in.new_lm_crypted = &hash2;
1146 r.in.nt_present = 1;
1147 r.in.old_nt_crypted = &hash3;
1148 r.in.new_nt_crypted = &hash4;
1149 r.in.cross1_present = 1;
1150 r.in.nt_cross = &hash5;
1151 r.in.cross2_present = 1;
1152 r.in.lm_cross = &hash6;
1154 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1155 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1156 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1160 /* Unbreak the LM hash */
1163 r.in.user_handle = &user_handle;
1164 r.in.lm_present = 1;
1165 r.in.old_lm_crypted = &hash1;
1166 r.in.new_lm_crypted = &hash2;
1167 /* Break the NT hash */
1169 r.in.nt_present = 1;
1170 r.in.old_nt_crypted = &hash3;
1171 r.in.new_nt_crypted = &hash4;
1172 r.in.cross1_present = 1;
1173 r.in.nt_cross = &hash5;
1174 r.in.cross2_present = 1;
1175 r.in.lm_cross = &hash6;
1177 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1178 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1179 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1183 /* Unbreak the NT hash */
1186 r.in.user_handle = &user_handle;
1187 r.in.lm_present = 1;
1188 r.in.old_lm_crypted = &hash1;
1189 r.in.new_lm_crypted = &hash2;
1190 r.in.nt_present = 1;
1191 r.in.old_nt_crypted = &hash3;
1192 r.in.new_nt_crypted = &hash4;
1193 r.in.cross1_present = 1;
1194 r.in.nt_cross = &hash5;
1195 r.in.cross2_present = 1;
1196 /* Break the LM cross */
1198 r.in.lm_cross = &hash6;
1200 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1201 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1202 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1206 /* Unbreak the LM cross */
1209 r.in.user_handle = &user_handle;
1210 r.in.lm_present = 1;
1211 r.in.old_lm_crypted = &hash1;
1212 r.in.new_lm_crypted = &hash2;
1213 r.in.nt_present = 1;
1214 r.in.old_nt_crypted = &hash3;
1215 r.in.new_nt_crypted = &hash4;
1216 r.in.cross1_present = 1;
1217 /* Break the NT cross */
1219 r.in.nt_cross = &hash5;
1220 r.in.cross2_present = 1;
1221 r.in.lm_cross = &hash6;
1223 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1224 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1225 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1229 /* Unbreak the NT cross */
1233 /* Reset the hashes to not broken values */
1234 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1235 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1236 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1237 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1238 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1239 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1241 r.in.user_handle = &user_handle;
1242 r.in.lm_present = 1;
1243 r.in.old_lm_crypted = &hash1;
1244 r.in.new_lm_crypted = &hash2;
1245 r.in.nt_present = 1;
1246 r.in.old_nt_crypted = &hash3;
1247 r.in.new_nt_crypted = &hash4;
1248 r.in.cross1_present = 1;
1249 r.in.nt_cross = &hash5;
1250 r.in.cross2_present = 0;
1251 r.in.lm_cross = NULL;
1253 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1254 if (NT_STATUS_IS_OK(status)) {
1256 *password = newpass;
1257 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1258 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1263 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1265 E_md4hash(oldpass, old_nt_hash);
1266 E_md4hash(newpass, new_nt_hash);
1267 E_deshash(oldpass, old_lm_hash);
1268 E_deshash(newpass, new_lm_hash);
1271 /* Reset the hashes to not broken values */
1272 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1273 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1274 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1275 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1276 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1277 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1279 r.in.user_handle = &user_handle;
1280 r.in.lm_present = 1;
1281 r.in.old_lm_crypted = &hash1;
1282 r.in.new_lm_crypted = &hash2;
1283 r.in.nt_present = 1;
1284 r.in.old_nt_crypted = &hash3;
1285 r.in.new_nt_crypted = &hash4;
1286 r.in.cross1_present = 0;
1287 r.in.nt_cross = NULL;
1288 r.in.cross2_present = 1;
1289 r.in.lm_cross = &hash6;
1291 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1292 if (NT_STATUS_IS_OK(status)) {
1294 *password = newpass;
1295 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1296 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1301 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1303 E_md4hash(oldpass, old_nt_hash);
1304 E_md4hash(newpass, new_nt_hash);
1305 E_deshash(oldpass, old_lm_hash);
1306 E_deshash(newpass, new_lm_hash);
1309 /* Reset the hashes to not broken values */
1310 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1311 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1312 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1313 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1314 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1315 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1317 r.in.user_handle = &user_handle;
1318 r.in.lm_present = 1;
1319 r.in.old_lm_crypted = &hash1;
1320 r.in.new_lm_crypted = &hash2;
1321 r.in.nt_present = 1;
1322 r.in.old_nt_crypted = &hash3;
1323 r.in.new_nt_crypted = &hash4;
1324 r.in.cross1_present = 1;
1325 r.in.nt_cross = &hash5;
1326 r.in.cross2_present = 1;
1327 r.in.lm_cross = &hash6;
1329 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1330 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1331 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1332 } else if (!NT_STATUS_IS_OK(status)) {
1333 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1337 *password = newpass;
1340 r.in.user_handle = &user_handle;
1341 r.in.lm_present = 1;
1342 r.in.old_lm_crypted = &hash1;
1343 r.in.new_lm_crypted = &hash2;
1344 r.in.nt_present = 1;
1345 r.in.old_nt_crypted = &hash3;
1346 r.in.new_nt_crypted = &hash4;
1347 r.in.cross1_present = 1;
1348 r.in.nt_cross = &hash5;
1349 r.in.cross2_present = 1;
1350 r.in.lm_cross = &hash6;
1353 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1354 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1355 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1356 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1357 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1363 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1371 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1372 const char *acct_name,
1373 struct policy_handle *handle, char **password)
1376 struct samr_OemChangePasswordUser2 r;
1378 struct samr_Password lm_verifier;
1379 struct samr_CryptPassword lm_pass;
1380 struct lsa_AsciiString server, account, account_bad;
1383 uint8_t old_lm_hash[16], new_lm_hash[16];
1385 struct samr_GetDomPwInfo dom_pw_info;
1386 int policy_min_pw_len = 0;
1388 struct lsa_String domain_name;
1390 domain_name.string = "";
1391 dom_pw_info.in.domain_name = &domain_name;
1393 printf("Testing OemChangePasswordUser2\n");
1396 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1400 oldpass = *password;
1402 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1403 if (NT_STATUS_IS_OK(status)) {
1404 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1407 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1409 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1410 account.string = acct_name;
1412 E_deshash(oldpass, old_lm_hash);
1413 E_deshash(newpass, new_lm_hash);
1415 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1416 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1417 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1419 r.in.server = &server;
1420 r.in.account = &account;
1421 r.in.password = &lm_pass;
1422 r.in.hash = &lm_verifier;
1424 /* Break the verification */
1425 lm_verifier.hash[0]++;
1427 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1429 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1430 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1431 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1436 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1437 /* Break the old password */
1439 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1440 /* unbreak it for the next operation */
1442 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1444 r.in.server = &server;
1445 r.in.account = &account;
1446 r.in.password = &lm_pass;
1447 r.in.hash = &lm_verifier;
1449 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1451 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1452 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1453 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1458 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1459 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1461 r.in.server = &server;
1462 r.in.account = &account;
1463 r.in.password = &lm_pass;
1466 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1468 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1469 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1470 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1475 /* This shouldn't be a valid name */
1476 account_bad.string = TEST_ACCOUNT_NAME "XX";
1477 r.in.account = &account_bad;
1479 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1481 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1482 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1487 /* This shouldn't be a valid name */
1488 account_bad.string = TEST_ACCOUNT_NAME "XX";
1489 r.in.account = &account_bad;
1490 r.in.password = &lm_pass;
1491 r.in.hash = &lm_verifier;
1493 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1495 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1496 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1501 /* This shouldn't be a valid name */
1502 account_bad.string = TEST_ACCOUNT_NAME "XX";
1503 r.in.account = &account_bad;
1504 r.in.password = NULL;
1505 r.in.hash = &lm_verifier;
1507 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1509 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1510 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1515 E_deshash(oldpass, old_lm_hash);
1516 E_deshash(newpass, new_lm_hash);
1518 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1519 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1520 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1522 r.in.server = &server;
1523 r.in.account = &account;
1524 r.in.password = &lm_pass;
1525 r.in.hash = &lm_verifier;
1527 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1528 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1529 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1530 } else if (!NT_STATUS_IS_OK(status)) {
1531 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1534 *password = newpass;
1541 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1542 const char *acct_name,
1544 char *newpass, bool allow_password_restriction)
1547 struct samr_ChangePasswordUser2 r;
1549 struct lsa_String server, account;
1550 struct samr_CryptPassword nt_pass, lm_pass;
1551 struct samr_Password nt_verifier, lm_verifier;
1553 uint8_t old_nt_hash[16], new_nt_hash[16];
1554 uint8_t old_lm_hash[16], new_lm_hash[16];
1556 struct samr_GetDomPwInfo dom_pw_info;
1558 struct lsa_String domain_name;
1560 domain_name.string = "";
1561 dom_pw_info.in.domain_name = &domain_name;
1563 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1566 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1569 oldpass = *password;
1572 int policy_min_pw_len = 0;
1573 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1574 if (NT_STATUS_IS_OK(status)) {
1575 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1578 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1581 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1582 init_lsa_String(&account, acct_name);
1584 E_md4hash(oldpass, old_nt_hash);
1585 E_md4hash(newpass, new_nt_hash);
1587 E_deshash(oldpass, old_lm_hash);
1588 E_deshash(newpass, new_lm_hash);
1590 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1591 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1592 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1594 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1595 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1596 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1598 r.in.server = &server;
1599 r.in.account = &account;
1600 r.in.nt_password = &nt_pass;
1601 r.in.nt_verifier = &nt_verifier;
1603 r.in.lm_password = &lm_pass;
1604 r.in.lm_verifier = &lm_verifier;
1606 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1607 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1608 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1609 } else if (!NT_STATUS_IS_OK(status)) {
1610 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1613 *password = newpass;
1620 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1621 const char *account_string,
1622 int policy_min_pw_len,
1624 const char *newpass,
1625 NTTIME last_password_change,
1626 bool handle_reject_reason)
1629 struct samr_ChangePasswordUser3 r;
1631 struct lsa_String server, account, account_bad;
1632 struct samr_CryptPassword nt_pass, lm_pass;
1633 struct samr_Password nt_verifier, lm_verifier;
1635 uint8_t old_nt_hash[16], new_nt_hash[16];
1636 uint8_t old_lm_hash[16], new_lm_hash[16];
1639 printf("Testing ChangePasswordUser3\n");
1641 if (newpass == NULL) {
1643 if (policy_min_pw_len == 0) {
1644 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1646 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1648 } while (check_password_quality(newpass) == false);
1650 printf("Using password '%s'\n", newpass);
1654 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1658 oldpass = *password;
1659 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1660 init_lsa_String(&account, account_string);
1662 E_md4hash(oldpass, old_nt_hash);
1663 E_md4hash(newpass, new_nt_hash);
1665 E_deshash(oldpass, old_lm_hash);
1666 E_deshash(newpass, new_lm_hash);
1668 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1669 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1670 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1672 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1673 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1674 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1676 /* Break the verification */
1677 nt_verifier.hash[0]++;
1679 r.in.server = &server;
1680 r.in.account = &account;
1681 r.in.nt_password = &nt_pass;
1682 r.in.nt_verifier = &nt_verifier;
1684 r.in.lm_password = &lm_pass;
1685 r.in.lm_verifier = &lm_verifier;
1686 r.in.password3 = NULL;
1688 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1689 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1690 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1691 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1696 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1697 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1698 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1700 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1701 /* Break the NT hash */
1703 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1704 /* Unbreak it again */
1706 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1708 r.in.server = &server;
1709 r.in.account = &account;
1710 r.in.nt_password = &nt_pass;
1711 r.in.nt_verifier = &nt_verifier;
1713 r.in.lm_password = &lm_pass;
1714 r.in.lm_verifier = &lm_verifier;
1715 r.in.password3 = NULL;
1717 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1718 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1719 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1720 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1725 /* This shouldn't be a valid name */
1726 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1728 r.in.account = &account_bad;
1729 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1730 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1731 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1736 E_md4hash(oldpass, old_nt_hash);
1737 E_md4hash(newpass, new_nt_hash);
1739 E_deshash(oldpass, old_lm_hash);
1740 E_deshash(newpass, new_lm_hash);
1742 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1743 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1744 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1746 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1747 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1748 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1750 r.in.server = &server;
1751 r.in.account = &account;
1752 r.in.nt_password = &nt_pass;
1753 r.in.nt_verifier = &nt_verifier;
1755 r.in.lm_password = &lm_pass;
1756 r.in.lm_verifier = &lm_verifier;
1757 r.in.password3 = NULL;
1759 unix_to_nt_time(&t, time(NULL));
1761 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1763 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1766 && handle_reject_reason
1767 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1768 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1770 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1771 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1772 SAMR_REJECT_OTHER, r.out.reject->reason);
1777 /* We tested the order of precendence which is as follows:
1786 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1787 (last_password_change + r.out.dominfo->min_password_age > t)) {
1789 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1790 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1791 SAMR_REJECT_OTHER, r.out.reject->reason);
1795 } else if ((r.out.dominfo->min_password_length > 0) &&
1796 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1798 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1799 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1800 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1804 } else if ((r.out.dominfo->password_history_length > 0) &&
1805 strequal(oldpass, newpass)) {
1807 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1808 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1809 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1812 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1814 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1815 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1816 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1822 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1823 /* retry with adjusted size */
1824 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1825 r.out.dominfo->min_password_length,
1826 password, NULL, 0, false);
1830 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1831 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1832 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1833 SAMR_REJECT_OTHER, r.out.reject->reason);
1836 /* Perhaps the server has a 'min password age' set? */
1838 } else if (!NT_STATUS_IS_OK(status)) {
1839 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1842 *password = talloc_strdup(mem_ctx, newpass);
1849 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1850 struct policy_handle *alias_handle)
1852 struct samr_GetMembersInAlias r;
1853 struct lsa_SidArray sids;
1857 printf("Testing GetMembersInAlias\n");
1859 r.in.alias_handle = alias_handle;
1862 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1863 if (!NT_STATUS_IS_OK(status)) {
1864 printf("GetMembersInAlias failed - %s\n",
1872 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1873 struct policy_handle *alias_handle,
1874 const struct dom_sid *domain_sid)
1876 struct samr_AddAliasMember r;
1877 struct samr_DeleteAliasMember d;
1880 struct dom_sid *sid;
1882 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1884 printf("testing AddAliasMember\n");
1885 r.in.alias_handle = alias_handle;
1888 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1889 if (!NT_STATUS_IS_OK(status)) {
1890 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1894 d.in.alias_handle = alias_handle;
1897 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1898 if (!NT_STATUS_IS_OK(status)) {
1899 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1906 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1907 struct policy_handle *alias_handle)
1909 struct samr_AddMultipleMembersToAlias a;
1910 struct samr_RemoveMultipleMembersFromAlias r;
1913 struct lsa_SidArray sids;
1915 printf("testing AddMultipleMembersToAlias\n");
1916 a.in.alias_handle = alias_handle;
1920 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1922 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1923 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1924 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1926 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1927 if (!NT_STATUS_IS_OK(status)) {
1928 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1933 printf("testing RemoveMultipleMembersFromAlias\n");
1934 r.in.alias_handle = alias_handle;
1937 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1938 if (!NT_STATUS_IS_OK(status)) {
1939 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1943 /* strange! removing twice doesn't give any error */
1944 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1945 if (!NT_STATUS_IS_OK(status)) {
1946 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1950 /* but removing an alias that isn't there does */
1951 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1953 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1954 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1955 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1962 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1963 struct policy_handle *user_handle)
1965 struct samr_TestPrivateFunctionsUser r;
1969 printf("Testing TestPrivateFunctionsUser\n");
1971 r.in.user_handle = user_handle;
1973 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1974 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1975 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1983 static bool test_user_ops(struct dcerpc_pipe *p,
1984 struct torture_context *tctx,
1985 struct policy_handle *user_handle,
1986 struct policy_handle *domain_handle,
1987 uint32_t base_acct_flags,
1988 const char *base_acct_name, enum torture_samr_choice which_ops)
1990 char *password = NULL;
1994 const uint32_t password_fields[] = {
1995 SAMR_FIELD_PASSWORD,
1996 SAMR_FIELD_PASSWORD2,
1997 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2001 switch (which_ops) {
2002 case TORTURE_SAMR_USER_ATTRIBUTES:
2003 if (!test_QuerySecurity(p, tctx, user_handle)) {
2007 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2011 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2015 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2020 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2024 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2028 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2032 case TORTURE_SAMR_PASSWORDS:
2033 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2034 char simple_pass[9];
2035 char *v = generate_random_str(tctx, 1);
2037 ZERO_STRUCT(simple_pass);
2038 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2040 printf("Testing machine account password policy rules\n");
2042 /* Workstation trust accounts don't seem to need to honour password quality policy */
2043 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2047 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2051 /* reset again, to allow another 'user' password change */
2052 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2056 /* Try a 'short' password */
2057 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2063 for (i = 0; password_fields[i]; i++) {
2064 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2068 /* check it was set right */
2069 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2074 for (i = 0; password_fields[i]; i++) {
2075 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2079 /* check it was set right */
2080 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2085 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2089 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2094 case TORTURE_SAMR_OTHER:
2095 /* We just need the account to exist */
2101 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2102 struct policy_handle *alias_handle,
2103 const struct dom_sid *domain_sid)
2107 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2111 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2115 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2119 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2123 if (torture_setting_bool(tctx, "samba4", false)) {
2124 printf("skipping MultipleMembers Alias tests against Samba4\n");
2128 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2136 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2137 struct policy_handle *user_handle)
2139 struct samr_DeleteUser d;
2142 printf("Testing DeleteUser\n");
2144 d.in.user_handle = user_handle;
2145 d.out.user_handle = user_handle;
2147 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2148 if (!NT_STATUS_IS_OK(status)) {
2149 printf("DeleteUser failed - %s\n", nt_errstr(status));
2156 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2157 struct policy_handle *handle, const char *name)
2160 struct samr_DeleteUser d;
2161 struct policy_handle user_handle;
2164 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2165 if (!NT_STATUS_IS_OK(status)) {
2169 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2170 if (!NT_STATUS_IS_OK(status)) {
2174 d.in.user_handle = &user_handle;
2175 d.out.user_handle = &user_handle;
2176 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2177 if (!NT_STATUS_IS_OK(status)) {
2184 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2189 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2190 struct policy_handle *handle, const char *name)
2193 struct samr_OpenGroup r;
2194 struct samr_DeleteDomainGroup d;
2195 struct policy_handle group_handle;
2198 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2199 if (!NT_STATUS_IS_OK(status)) {
2203 r.in.domain_handle = handle;
2204 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2206 r.out.group_handle = &group_handle;
2207 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2208 if (!NT_STATUS_IS_OK(status)) {
2212 d.in.group_handle = &group_handle;
2213 d.out.group_handle = &group_handle;
2214 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2215 if (!NT_STATUS_IS_OK(status)) {
2222 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2227 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2228 struct policy_handle *domain_handle, const char *name)
2231 struct samr_OpenAlias r;
2232 struct samr_DeleteDomAlias d;
2233 struct policy_handle alias_handle;
2236 printf("testing DeleteAlias_byname\n");
2238 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2239 if (!NT_STATUS_IS_OK(status)) {
2243 r.in.domain_handle = domain_handle;
2244 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2246 r.out.alias_handle = &alias_handle;
2247 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2248 if (!NT_STATUS_IS_OK(status)) {
2252 d.in.alias_handle = &alias_handle;
2253 d.out.alias_handle = &alias_handle;
2254 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2255 if (!NT_STATUS_IS_OK(status)) {
2262 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2266 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2267 struct policy_handle *alias_handle)
2269 struct samr_DeleteDomAlias d;
2272 printf("Testing DeleteAlias\n");
2274 d.in.alias_handle = alias_handle;
2275 d.out.alias_handle = alias_handle;
2277 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2278 if (!NT_STATUS_IS_OK(status)) {
2279 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2286 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2287 struct policy_handle *domain_handle,
2288 struct policy_handle *alias_handle,
2289 const struct dom_sid *domain_sid)
2292 struct samr_CreateDomAlias r;
2293 struct lsa_String name;
2297 init_lsa_String(&name, TEST_ALIASNAME);
2298 r.in.domain_handle = domain_handle;
2299 r.in.alias_name = &name;
2300 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2301 r.out.alias_handle = alias_handle;
2304 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2306 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2308 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2309 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2313 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2314 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2317 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2320 if (!NT_STATUS_IS_OK(status)) {
2321 printf("CreateAlias failed - %s\n", nt_errstr(status));
2325 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2332 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2333 const char *acct_name,
2334 struct policy_handle *domain_handle, char **password)
2342 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2346 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2350 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2354 /* test what happens when setting the old password again */
2355 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2360 char simple_pass[9];
2361 char *v = generate_random_str(mem_ctx, 1);
2363 ZERO_STRUCT(simple_pass);
2364 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2366 /* test what happens when picking a simple password */
2367 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2372 /* set samr_SetDomainInfo level 1 with min_length 5 */
2374 struct samr_QueryDomainInfo r;
2375 struct samr_SetDomainInfo s;
2376 uint16_t len_old, len;
2377 uint32_t pwd_prop_old;
2378 int64_t min_pwd_age_old;
2383 r.in.domain_handle = domain_handle;
2386 printf("testing samr_QueryDomainInfo level 1\n");
2387 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2388 if (!NT_STATUS_IS_OK(status)) {
2392 s.in.domain_handle = domain_handle;
2394 s.in.info = r.out.info;
2396 /* remember the old min length, so we can reset it */
2397 len_old = s.in.info->info1.min_password_length;
2398 s.in.info->info1.min_password_length = len;
2399 pwd_prop_old = s.in.info->info1.password_properties;
2400 /* turn off password complexity checks for this test */
2401 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2403 min_pwd_age_old = s.in.info->info1.min_password_age;
2404 s.in.info->info1.min_password_age = 0;
2406 printf("testing samr_SetDomainInfo level 1\n");
2407 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2408 if (!NT_STATUS_IS_OK(status)) {
2412 printf("calling test_ChangePasswordUser3 with too short password\n");
2414 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2418 s.in.info->info1.min_password_length = len_old;
2419 s.in.info->info1.password_properties = pwd_prop_old;
2420 s.in.info->info1.min_password_age = min_pwd_age_old;
2422 printf("testing samr_SetDomainInfo level 1\n");
2423 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2424 if (!NT_STATUS_IS_OK(status)) {
2432 struct samr_OpenUser r;
2433 struct samr_QueryUserInfo q;
2434 struct samr_LookupNames n;
2435 struct policy_handle user_handle;
2437 n.in.domain_handle = domain_handle;
2439 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2440 n.in.names[0].string = acct_name;
2442 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2443 if (!NT_STATUS_IS_OK(status)) {
2444 printf("LookupNames failed - %s\n", nt_errstr(status));
2448 r.in.domain_handle = domain_handle;
2449 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2450 r.in.rid = n.out.rids.ids[0];
2451 r.out.user_handle = &user_handle;
2453 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2454 if (!NT_STATUS_IS_OK(status)) {
2455 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2459 q.in.user_handle = &user_handle;
2462 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2463 if (!NT_STATUS_IS_OK(status)) {
2464 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2468 printf("calling test_ChangePasswordUser3 with too early password change\n");
2470 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2471 q.out.info->info5.last_password_change, true)) {
2476 /* we change passwords twice - this has the effect of verifying
2477 they were changed correctly for the final call */
2478 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2482 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2489 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2490 struct policy_handle *domain_handle,
2491 struct policy_handle *user_handle_out,
2492 enum torture_samr_choice which_ops)
2495 TALLOC_CTX *user_ctx;
2498 struct samr_CreateUser r;
2499 struct samr_QueryUserInfo q;
2500 struct samr_DeleteUser d;
2503 /* This call creates a 'normal' account - check that it really does */
2504 const uint32_t acct_flags = ACB_NORMAL;
2505 struct lsa_String name;
2508 struct policy_handle user_handle;
2509 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2510 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2512 r.in.domain_handle = domain_handle;
2513 r.in.account_name = &name;
2514 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2515 r.out.user_handle = &user_handle;
2518 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2520 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2522 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2523 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2524 talloc_free(user_ctx);
2528 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2529 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2530 talloc_free(user_ctx);
2533 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2535 if (!NT_STATUS_IS_OK(status)) {
2536 talloc_free(user_ctx);
2537 printf("CreateUser failed - %s\n", nt_errstr(status));
2540 q.in.user_handle = &user_handle;
2543 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2544 if (!NT_STATUS_IS_OK(status)) {
2545 printf("QueryUserInfo level %u failed - %s\n",
2546 q.in.level, nt_errstr(status));
2549 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2550 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2551 q.out.info->info16.acct_flags,
2557 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2558 acct_flags, name.string, which_ops)) {
2562 if (user_handle_out) {
2563 *user_handle_out = user_handle;
2565 printf("Testing DeleteUser (createuser test)\n");
2567 d.in.user_handle = &user_handle;
2568 d.out.user_handle = &user_handle;
2570 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2571 if (!NT_STATUS_IS_OK(status)) {
2572 printf("DeleteUser failed - %s\n", nt_errstr(status));
2579 talloc_free(user_ctx);
2585 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2586 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2589 struct samr_CreateUser2 r;
2590 struct samr_QueryUserInfo q;
2591 struct samr_DeleteUser d;
2592 struct policy_handle user_handle;
2594 struct lsa_String name;
2599 uint32_t acct_flags;
2600 const char *account_name;
2602 } account_types[] = {
2603 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2604 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2605 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2606 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2607 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2608 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2609 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2610 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2611 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2612 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2613 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2614 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2615 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2616 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2617 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2620 for (i = 0; account_types[i].account_name; i++) {
2621 TALLOC_CTX *user_ctx;
2622 uint32_t acct_flags = account_types[i].acct_flags;
2623 uint32_t access_granted;
2624 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2625 init_lsa_String(&name, account_types[i].account_name);
2627 r.in.domain_handle = domain_handle;
2628 r.in.account_name = &name;
2629 r.in.acct_flags = acct_flags;
2630 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2631 r.out.user_handle = &user_handle;
2632 r.out.access_granted = &access_granted;
2635 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2637 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2639 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2640 talloc_free(user_ctx);
2641 printf("Server refused create of '%s'\n", r.in.account_name->string);
2644 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2645 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2646 talloc_free(user_ctx);
2650 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2653 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2654 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2655 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2659 if (NT_STATUS_IS_OK(status)) {
2660 q.in.user_handle = &user_handle;
2663 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2664 if (!NT_STATUS_IS_OK(status)) {
2665 printf("QueryUserInfo level %u failed - %s\n",
2666 q.in.level, nt_errstr(status));
2669 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2670 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2671 q.out.info->info5.acct_flags,
2675 switch (acct_flags) {
2677 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2678 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2679 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2684 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2685 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2686 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2691 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2692 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2693 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2700 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2701 acct_flags, name.string, which_ops)) {
2705 printf("Testing DeleteUser (createuser2 test)\n");
2707 d.in.user_handle = &user_handle;
2708 d.out.user_handle = &user_handle;
2710 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2711 if (!NT_STATUS_IS_OK(status)) {
2712 printf("DeleteUser failed - %s\n", nt_errstr(status));
2716 talloc_free(user_ctx);
2722 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2723 struct policy_handle *handle)
2726 struct samr_QueryAliasInfo r;
2727 uint16_t levels[] = {1, 2, 3};
2731 for (i=0;i<ARRAY_SIZE(levels);i++) {
2732 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2734 r.in.alias_handle = handle;
2735 r.in.level = levels[i];
2737 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2738 if (!NT_STATUS_IS_OK(status)) {
2739 printf("QueryAliasInfo level %u failed - %s\n",
2740 levels[i], nt_errstr(status));
2748 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2749 struct policy_handle *handle)
2752 struct samr_QueryGroupInfo r;
2753 uint16_t levels[] = {1, 2, 3, 4, 5};
2757 for (i=0;i<ARRAY_SIZE(levels);i++) {
2758 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2760 r.in.group_handle = handle;
2761 r.in.level = levels[i];
2763 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2764 if (!NT_STATUS_IS_OK(status)) {
2765 printf("QueryGroupInfo level %u failed - %s\n",
2766 levels[i], nt_errstr(status));
2774 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2775 struct policy_handle *handle)
2778 struct samr_QueryGroupMember r;
2781 printf("Testing QueryGroupMember\n");
2783 r.in.group_handle = handle;
2785 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2786 if (!NT_STATUS_IS_OK(status)) {
2787 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2795 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2796 struct policy_handle *handle)
2799 struct samr_QueryGroupInfo r;
2800 struct samr_SetGroupInfo s;
2801 uint16_t levels[] = {1, 2, 3, 4};
2802 uint16_t set_ok[] = {0, 1, 1, 1};
2806 for (i=0;i<ARRAY_SIZE(levels);i++) {
2807 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2809 r.in.group_handle = handle;
2810 r.in.level = levels[i];
2812 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2813 if (!NT_STATUS_IS_OK(status)) {
2814 printf("QueryGroupInfo level %u failed - %s\n",
2815 levels[i], nt_errstr(status));
2819 printf("Testing SetGroupInfo level %u\n", levels[i]);
2821 s.in.group_handle = handle;
2822 s.in.level = levels[i];
2823 s.in.info = r.out.info;
2826 /* disabled this, as it changes the name only from the point of view of samr,
2827 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2828 the name is still reserved, so creating the old name fails, but deleting by the old name
2830 if (s.in.level == 2) {
2831 init_lsa_String(&s.in.info->string, "NewName");
2835 if (s.in.level == 4) {
2836 init_lsa_String(&s.in.info->description, "test description");
2839 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2841 if (!NT_STATUS_IS_OK(status)) {
2842 printf("SetGroupInfo level %u failed - %s\n",
2843 r.in.level, nt_errstr(status));
2848 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2849 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2850 r.in.level, nt_errstr(status));
2860 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2861 struct policy_handle *handle)
2864 struct samr_QueryUserInfo r;
2865 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2866 11, 12, 13, 14, 16, 17, 20, 21};
2870 for (i=0;i<ARRAY_SIZE(levels);i++) {
2871 printf("Testing QueryUserInfo level %u\n", levels[i]);
2873 r.in.user_handle = handle;
2874 r.in.level = levels[i];
2876 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2877 if (!NT_STATUS_IS_OK(status)) {
2878 printf("QueryUserInfo level %u failed - %s\n",
2879 levels[i], nt_errstr(status));
2887 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2888 struct policy_handle *handle)
2891 struct samr_QueryUserInfo2 r;
2892 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2893 11, 12, 13, 14, 16, 17, 20, 21};
2897 for (i=0;i<ARRAY_SIZE(levels);i++) {
2898 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2900 r.in.user_handle = handle;
2901 r.in.level = levels[i];
2903 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2904 if (!NT_STATUS_IS_OK(status)) {
2905 printf("QueryUserInfo2 level %u failed - %s\n",
2906 levels[i], nt_errstr(status));
2914 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2915 struct policy_handle *handle, uint32_t rid)
2918 struct samr_OpenUser r;
2919 struct policy_handle user_handle;
2922 printf("Testing OpenUser(%u)\n", rid);
2924 r.in.domain_handle = handle;
2925 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2927 r.out.user_handle = &user_handle;
2929 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2930 if (!NT_STATUS_IS_OK(status)) {
2931 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2935 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2939 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2943 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2947 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2951 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2955 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2962 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2963 struct policy_handle *handle, uint32_t rid)
2966 struct samr_OpenGroup r;
2967 struct policy_handle group_handle;
2970 printf("Testing OpenGroup(%u)\n", rid);
2972 r.in.domain_handle = handle;
2973 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2975 r.out.group_handle = &group_handle;
2977 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2978 if (!NT_STATUS_IS_OK(status)) {
2979 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2983 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2987 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2991 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2995 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3002 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3003 struct policy_handle *handle, uint32_t rid)
3006 struct samr_OpenAlias r;
3007 struct policy_handle alias_handle;
3010 printf("Testing OpenAlias(%u)\n", rid);
3012 r.in.domain_handle = handle;
3013 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3015 r.out.alias_handle = &alias_handle;
3017 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3018 if (!NT_STATUS_IS_OK(status)) {
3019 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3023 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3027 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3031 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3035 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3042 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3043 struct policy_handle *handle, uint32_t rid,
3044 uint32_t acct_flag_mask)
3047 struct samr_OpenUser r;
3048 struct samr_QueryUserInfo q;
3049 struct policy_handle user_handle;
3052 printf("Testing OpenUser(%u)\n", rid);
3054 r.in.domain_handle = handle;
3055 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3057 r.out.user_handle = &user_handle;
3059 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3060 if (!NT_STATUS_IS_OK(status)) {
3061 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3065 q.in.user_handle = &user_handle;
3068 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3069 if (!NT_STATUS_IS_OK(status)) {
3070 printf("QueryUserInfo level 16 failed - %s\n",
3074 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3075 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3076 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3081 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3088 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3089 struct policy_handle *handle)
3091 NTSTATUS status = STATUS_MORE_ENTRIES;
3092 struct samr_EnumDomainUsers r;
3093 uint32_t mask, resume_handle=0;
3096 struct samr_LookupNames n;
3097 struct samr_LookupRids lr ;
3098 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3099 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3100 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3103 printf("Testing EnumDomainUsers\n");
3105 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3106 r.in.domain_handle = handle;
3107 r.in.resume_handle = &resume_handle;
3108 r.in.acct_flags = mask = masks[mask_idx];
3109 r.in.max_size = (uint32_t)-1;
3110 r.out.resume_handle = &resume_handle;
3112 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3113 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3114 !NT_STATUS_IS_OK(status)) {
3115 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3120 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3124 if (r.out.sam->count == 0) {
3128 for (i=0;i<r.out.sam->count;i++) {
3130 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3133 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3139 printf("Testing LookupNames\n");
3140 n.in.domain_handle = handle;
3141 n.in.num_names = r.out.sam->count;
3142 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3143 for (i=0;i<r.out.sam->count;i++) {
3144 n.in.names[i].string = r.out.sam->entries[i].name.string;
3146 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3147 if (!NT_STATUS_IS_OK(status)) {
3148 printf("LookupNames failed - %s\n", nt_errstr(status));
3153 printf("Testing LookupRids\n");
3154 lr.in.domain_handle = handle;
3155 lr.in.num_rids = r.out.sam->count;
3156 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3157 for (i=0;i<r.out.sam->count;i++) {
3158 lr.in.rids[i] = r.out.sam->entries[i].idx;
3160 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3161 if (!NT_STATUS_IS_OK(status)) {
3162 printf("LookupRids failed - %s\n", nt_errstr(status));
3170 try blasting the server with a bunch of sync requests
3172 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx,
3173 struct policy_handle *handle)
3176 struct samr_EnumDomainUsers r;
3177 uint32_t resume_handle=0;
3179 #define ASYNC_COUNT 100
3180 struct rpc_request *req[ASYNC_COUNT];
3182 if (!torture_setting_bool(tctx, "dangerous", false)) {
3183 printf("samr async test disabled - enable dangerous tests to use\n");
3187 printf("Testing EnumDomainUsers_async\n");
3189 r.in.domain_handle = handle;
3190 r.in.resume_handle = &resume_handle;
3191 r.in.acct_flags = 0;
3192 r.in.max_size = (uint32_t)-1;
3193 r.out.resume_handle = &resume_handle;
3195 for (i=0;i<ASYNC_COUNT;i++) {
3196 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3199 for (i=0;i<ASYNC_COUNT;i++) {
3200 status = dcerpc_ndr_request_recv(req[i]);
3201 if (!NT_STATUS_IS_OK(status)) {
3202 printf("EnumDomainUsers[%d] failed - %s\n",
3203 i, nt_errstr(status));
3208 printf("%d async requests OK\n", i);
3213 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3214 struct policy_handle *handle)
3217 struct samr_EnumDomainGroups r;
3218 uint32_t resume_handle=0;
3222 printf("Testing EnumDomainGroups\n");
3224 r.in.domain_handle = handle;
3225 r.in.resume_handle = &resume_handle;
3226 r.in.max_size = (uint32_t)-1;
3227 r.out.resume_handle = &resume_handle;
3229 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3230 if (!NT_STATUS_IS_OK(status)) {
3231 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3239 for (i=0;i<r.out.sam->count;i++) {
3240 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3248 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3249 struct policy_handle *handle)
3252 struct samr_EnumDomainAliases r;
3253 uint32_t resume_handle=0;
3257 printf("Testing EnumDomainAliases\n");
3259 r.in.domain_handle = handle;
3260 r.in.resume_handle = &resume_handle;
3261 r.in.acct_flags = (uint32_t)-1;
3262 r.out.resume_handle = &resume_handle;
3264 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3265 if (!NT_STATUS_IS_OK(status)) {
3266 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3274 for (i=0;i<r.out.sam->count;i++) {
3275 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3283 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3284 struct policy_handle *handle)
3287 struct samr_GetDisplayEnumerationIndex r;
3289 uint16_t levels[] = {1, 2, 3, 4, 5};
3290 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3293 for (i=0;i<ARRAY_SIZE(levels);i++) {
3294 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3296 r.in.domain_handle = handle;
3297 r.in.level = levels[i];
3298 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3300 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3303 !NT_STATUS_IS_OK(status) &&
3304 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3305 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3306 levels[i], nt_errstr(status));
3310 init_lsa_String(&r.in.name, "zzzzzzzz");
3312 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3314 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3315 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3316 levels[i], nt_errstr(status));
3324 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3325 struct policy_handle *handle)
3328 struct samr_GetDisplayEnumerationIndex2 r;
3330 uint16_t levels[] = {1, 2, 3, 4, 5};
3331 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3334 for (i=0;i<ARRAY_SIZE(levels);i++) {
3335 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3337 r.in.domain_handle = handle;
3338 r.in.level = levels[i];
3339 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3341 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3343 !NT_STATUS_IS_OK(status) &&
3344 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3345 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3346 levels[i], nt_errstr(status));
3350 init_lsa_String(&r.in.name, "zzzzzzzz");
3352 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3353 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3354 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3355 levels[i], nt_errstr(status));
3363 #define STRING_EQUAL_QUERY(s1, s2, user) \
3364 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3365 /* odd, but valid */ \
3366 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3367 printf("%s mismatch for %s: %s != %s (%s)\n", \
3368 #s1, user.string, s1.string, s2.string, __location__); \
3371 #define INT_EQUAL_QUERY(s1, s2, user) \
3373 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3374 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3378 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3379 struct samr_QueryDisplayInfo *querydisplayinfo,
3380 bool *seen_testuser)
3382 struct samr_OpenUser r;
3383 struct samr_QueryUserInfo q;
3384 struct policy_handle user_handle;
3387 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3388 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3389 for (i = 0; ; i++) {
3390 switch (querydisplayinfo->in.level) {
3392 if (i >= querydisplayinfo->out.info.info1.count) {
3395 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3398 if (i >= querydisplayinfo->out.info.info2.count) {
3401 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3407 /* Not interested in validating just the account name */
3411 r.out.user_handle = &user_handle;
3413 switch (querydisplayinfo->in.level) {
3416 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3417 if (!NT_STATUS_IS_OK(status)) {
3418 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3423 q.in.user_handle = &user_handle;
3425 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3426 if (!NT_STATUS_IS_OK(status)) {
3427 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3431 switch (querydisplayinfo->in.level) {
3433 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3434 *seen_testuser = true;
3436 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3437 q.out.info->info21.full_name, q.out.info->info21.account_name);
3438 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3439 q.out.info->info21.account_name, q.out.info->info21.account_name);
3440 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3441 q.out.info->info21.description, q.out.info->info21.account_name);
3442 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3443 q.out.info->info21.rid, q.out.info->info21.account_name);
3444 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3445 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3449 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3450 q.out.info->info21.account_name, q.out.info->info21.account_name);
3451 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3452 q.out.info->info21.description, q.out.info->info21.account_name);
3453 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3454 q.out.info->info21.rid, q.out.info->info21.account_name);
3455 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3456 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3458 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3459 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3460 q.out.info->info21.account_name.string);
3463 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3464 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3465 q.out.info->info21.account_name.string,
3466 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3467 q.out.info->info21.acct_flags);
3474 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3481 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3482 struct policy_handle *handle)
3485 struct samr_QueryDisplayInfo r;
3486 struct samr_QueryDomainInfo dom_info;
3488 uint16_t levels[] = {1, 2, 3, 4, 5};
3490 bool seen_testuser = false;
3492 for (i=0;i<ARRAY_SIZE(levels);i++) {
3493 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3496 status = STATUS_MORE_ENTRIES;
3497 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3498 r.in.domain_handle = handle;
3499 r.in.level = levels[i];
3500 r.in.max_entries = 2;
3501 r.in.buf_size = (uint32_t)-1;
3503 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3504 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3505 printf("QueryDisplayInfo level %u failed - %s\n",
3506 levels[i], nt_errstr(status));
3509 switch (r.in.level) {
3511 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3514 r.in.start_idx += r.out.info.info1.count;
3517 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3520 r.in.start_idx += r.out.info.info2.count;
3523 r.in.start_idx += r.out.info.info3.count;
3526 r.in.start_idx += r.out.info.info4.count;
3529 r.in.start_idx += r.out.info.info5.count;
3533 dom_info.in.domain_handle = handle;
3534 dom_info.in.level = 2;
3535 /* Check number of users returned is correct */
3536 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3537 if (!NT_STATUS_IS_OK(status)) {
3538 printf("QueryDomainInfo level %u failed - %s\n",
3539 r.in.level, nt_errstr(status));
3543 switch (r.in.level) {
3546 if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3547 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3548 r.in.start_idx, dom_info.out.info->info2.num_groups,
3549 dom_info.out.info->info2.domain_name.string);
3552 if (!seen_testuser) {
3553 struct policy_handle user_handle;
3554 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3555 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3556 dom_info.out.info->info2.domain_name.string);
3558 test_samr_handle_Close(p, mem_ctx, &user_handle);
3564 if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3565 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3566 r.in.start_idx, dom_info.out.info->info2.num_groups,
3567 dom_info.out.info->info2.domain_name.string);
3579 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3580 struct policy_handle *handle)
3583 struct samr_QueryDisplayInfo2 r;
3585 uint16_t levels[] = {1, 2, 3, 4, 5};
3588 for (i=0;i<ARRAY_SIZE(levels);i++) {
3589 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3591 r.in.domain_handle = handle;
3592 r.in.level = levels[i];
3594 r.in.max_entries = 1000;
3595 r.in.buf_size = (uint32_t)-1;
3597 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3598 if (!NT_STATUS_IS_OK(status)) {
3599 printf("QueryDisplayInfo2 level %u failed - %s\n",
3600 levels[i], nt_errstr(status));
3608 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3609 struct policy_handle *handle)
3612 struct samr_QueryDisplayInfo3 r;
3614 uint16_t levels[] = {1, 2, 3, 4, 5};
3617 for (i=0;i<ARRAY_SIZE(levels);i++) {
3618 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3620 r.in.domain_handle = handle;
3621 r.in.level = levels[i];
3623 r.in.max_entries = 1000;
3624 r.in.buf_size = (uint32_t)-1;
3626 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3627 if (!NT_STATUS_IS_OK(status)) {
3628 printf("QueryDisplayInfo3 level %u failed - %s\n",
3629 levels[i], nt_errstr(status));
3638 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3639 struct policy_handle *handle)
3642 struct samr_QueryDisplayInfo r;
3645 printf("Testing QueryDisplayInfo continuation\n");
3647 r.in.domain_handle = handle;
3650 r.in.max_entries = 1;
3651 r.in.buf_size = (uint32_t)-1;
3654 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3655 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3656 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3657 printf("expected idx %d but got %d\n",
3659 r.out.info.info1.entries[0].idx);
3663 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3664 !NT_STATUS_IS_OK(status)) {
3665 printf("QueryDisplayInfo level %u failed - %s\n",
3666 r.in.level, nt_errstr(status));
3671 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3672 NT_STATUS_IS_OK(status)) &&
3673 r.out.returned_size != 0);
3678 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3679 struct policy_handle *handle)
3682 struct samr_QueryDomainInfo r;
3683 struct samr_SetDomainInfo s;
3684 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3685 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3688 const char *domain_comment = talloc_asprintf(mem_ctx,
3689 "Tortured by Samba4 RPC-SAMR: %s",
3690 timestring(mem_ctx, time(NULL)));
3692 s.in.domain_handle = handle;
3694 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3696 s.in.info->info4.comment.string = domain_comment;
3697 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3698 if (!NT_STATUS_IS_OK(status)) {
3699 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3700 r.in.level, nt_errstr(status));
3704 for (i=0;i<ARRAY_SIZE(levels);i++) {
3705 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3707 r.in.domain_handle = handle;
3708 r.in.level = levels[i];
3710 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3711 if (!NT_STATUS_IS_OK(status)) {
3712 printf("QueryDomainInfo level %u failed - %s\n",
3713 r.in.level, nt_errstr(status));
3718 switch (levels[i]) {
3720 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3721 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3722 levels[i], r.out.info->info2.comment.string, domain_comment);
3725 if (!r.out.info->info2.primary.string) {
3726 printf("QueryDomainInfo level %u returned no PDC name\n",
3729 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3730 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3731 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3732 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3737 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3738 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3739 levels[i], r.out.info->info4.comment.string, domain_comment);
3744 if (!r.out.info->info6.primary.string) {
3745 printf("QueryDomainInfo level %u returned no PDC name\n",
3751 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3752 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3753 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3759 printf("Testing SetDomainInfo level %u\n", levels[i]);
3761 s.in.domain_handle = handle;
3762 s.in.level = levels[i];
3763 s.in.info = r.out.info;
3765 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3767 if (!NT_STATUS_IS_OK(status)) {
3768 printf("SetDomainInfo level %u failed - %s\n",
3769 r.in.level, nt_errstr(status));
3774 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3775 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3776 r.in.level, nt_errstr(status));
3782 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3783 if (!NT_STATUS_IS_OK(status)) {
3784 printf("QueryDomainInfo level %u failed - %s\n",
3785 r.in.level, nt_errstr(status));
3795 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3796 struct policy_handle *handle)
3799 struct samr_QueryDomainInfo2 r;
3800 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3804 for (i=0;i<ARRAY_SIZE(levels);i++) {
3805 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3807 r.in.domain_handle = handle;
3808 r.in.level = levels[i];
3810 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3811 if (!NT_STATUS_IS_OK(status)) {
3812 printf("QueryDomainInfo2 level %u failed - %s\n",
3813 r.in.level, nt_errstr(status));
3822 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3823 set of group names. */
3824 static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3825 struct policy_handle *handle)
3827 struct samr_EnumDomainGroups q1;
3828 struct samr_QueryDisplayInfo q2;
3830 uint32_t resume_handle=0;
3835 const char **names = NULL;
3837 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3839 q1.in.domain_handle = handle;
3840 q1.in.resume_handle = &resume_handle;
3842 q1.out.resume_handle = &resume_handle;
3844 status = STATUS_MORE_ENTRIES;
3845 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3846 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3848 if (!NT_STATUS_IS_OK(status) &&
3849 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3852 for (i=0; i<q1.out.num_entries; i++) {
3853 add_string_to_array(mem_ctx,
3854 q1.out.sam->entries[i].name.string,
3855 &names, &num_names);
3859 if (!NT_STATUS_IS_OK(status)) {
3860 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3868 q2.in.domain_handle = handle;
3870 q2.in.start_idx = 0;
3871 q2.in.max_entries = 5;
3872 q2.in.buf_size = (uint32_t)-1;
3874 status = STATUS_MORE_ENTRIES;
3875 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3876 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3878 if (!NT_STATUS_IS_OK(status) &&
3879 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3882 for (i=0; i<q2.out.info.info5.count; i++) {
3884 const char *name = q2.out.info.info5.entries[i].account_name.string;
3886 for (j=0; j<num_names; j++) {
3887 if (names[j] == NULL)
3889 /* Hmm. No strequal in samba4 */
3890 if (strequal(names[j], name)) {
3898 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3903 q2.in.start_idx += q2.out.info.info5.count;
3906 if (!NT_STATUS_IS_OK(status)) {
3907 printf("QueryDisplayInfo level 5 failed - %s\n",
3912 for (i=0; i<num_names; i++) {
3913 if (names[i] != NULL) {
3914 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3923 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3924 struct policy_handle *group_handle)
3926 struct samr_DeleteDomainGroup d;
3930 printf("Testing DeleteDomainGroup\n");
3932 d.in.group_handle = group_handle;
3933 d.out.group_handle = group_handle;
3935 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3944 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3945 struct policy_handle *domain_handle)
3947 struct samr_TestPrivateFunctionsDomain r;
3951 printf("Testing TestPrivateFunctionsDomain\n");
3953 r.in.domain_handle = domain_handle;
3955 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3956 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3957 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3964 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3965 struct dom_sid *domain_sid,
3966 struct policy_handle *domain_handle)
3968 struct samr_RidToSid r;
3971 struct dom_sid *calc_sid;
3972 int rids[] = { 0, 42, 512, 10200 };
3975 for (i=0;i<ARRAY_SIZE(rids);i++) {
3977 printf("Testing RidToSid\n");
3979 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3980 r.in.domain_handle = domain_handle;
3983 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3984 if (!NT_STATUS_IS_OK(status)) {
3985 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3988 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3990 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3991 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3992 dom_sid_string(mem_ctx, r.out.sid),
3993 dom_sid_string(mem_ctx, calc_sid));
4002 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4003 struct policy_handle *domain_handle)
4005 struct samr_GetBootKeyInformation r;
4009 printf("Testing GetBootKeyInformation\n");
4011 r.in.domain_handle = domain_handle;
4013 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4014 if (!NT_STATUS_IS_OK(status)) {
4015 /* w2k3 seems to fail this sometimes and pass it sometimes */
4016 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4022 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4023 struct policy_handle *domain_handle,
4024 struct policy_handle *group_handle)
4027 struct samr_AddGroupMember r;
4028 struct samr_DeleteGroupMember d;
4029 struct samr_QueryGroupMember q;
4030 struct samr_SetMemberAttributesOfGroup s;
4034 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4035 if (!NT_STATUS_IS_OK(status)) {
4036 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4040 r.in.group_handle = group_handle;
4042 r.in.flags = 0; /* ??? */
4044 printf("Testing AddGroupMember and DeleteGroupMember\n");
4046 d.in.group_handle = group_handle;
4049 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4050 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4051 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4056 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4062 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4063 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4064 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4069 if (torture_setting_bool(tctx, "samba4", false)) {
4070 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4072 /* this one is quite strange. I am using random inputs in the
4073 hope of triggering an error that might give us a clue */
4075 s.in.group_handle = group_handle;
4076 s.in.unknown1 = random();
4077 s.in.unknown2 = random();
4079 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4086 q.in.group_handle = group_handle;
4088 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4089 if (!NT_STATUS_IS_OK(status)) {
4090 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4094 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4095 if (!NT_STATUS_IS_OK(status)) {
4096 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4100 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4101 if (!NT_STATUS_IS_OK(status)) {
4102 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4110 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4111 struct policy_handle *domain_handle, struct policy_handle *group_handle)
4114 struct samr_CreateDomainGroup r;
4116 struct lsa_String name;
4119 init_lsa_String(&name, TEST_GROUPNAME);
4121 r.in.domain_handle = domain_handle;
4123 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4124 r.out.group_handle = group_handle;
4127 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4129 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4131 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4132 printf("Server refused create of '%s'\n", r.in.name->string);
4133 ZERO_STRUCTP(group_handle);
4137 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4138 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4140 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4144 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4146 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4147 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4149 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4153 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4155 if (!NT_STATUS_IS_OK(status)) {
4156 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4160 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4161 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4165 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4174 its not totally clear what this does. It seems to accept any sid you like.
4176 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4177 TALLOC_CTX *mem_ctx,
4178 struct policy_handle *domain_handle)
4181 struct samr_RemoveMemberFromForeignDomain r;
4183 r.in.domain_handle = domain_handle;
4184 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4186 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4187 if (!NT_STATUS_IS_OK(status)) {
4188 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4197 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4198 struct policy_handle *handle);
4200 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4201 struct policy_handle *handle, struct dom_sid *sid,
4202 enum torture_samr_choice which_ops)
4205 struct samr_OpenDomain r;
4206 struct policy_handle domain_handle;
4207 struct policy_handle alias_handle;
4208 struct policy_handle user_handle;
4209 struct policy_handle group_handle;
4212 ZERO_STRUCT(alias_handle);
4213 ZERO_STRUCT(user_handle);
4214 ZERO_STRUCT(group_handle);
4215 ZERO_STRUCT(domain_handle);
4217 printf("Testing OpenDomain\n");
4219 r.in.connect_handle = handle;
4220 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4222 r.out.domain_handle = &domain_handle;
4224 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4225 if (!NT_STATUS_IS_OK(status)) {
4226 printf("OpenDomain failed - %s\n", nt_errstr(status));
4230 /* run the domain tests with the main handle closed - this tests
4231 the servers reference counting */
4232 ret &= test_samr_handle_Close(p, tctx, handle);
4234 switch (which_ops) {
4235 case TORTURE_SAMR_USER_ATTRIBUTES:
4236 case TORTURE_SAMR_PASSWORDS:
4237 ret &= test_CreateUser2(p, tctx, &domain_handle, which_ops);
4238 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
4239 /* This test needs 'complex' users to validate */
4240 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4242 case TORTURE_SAMR_OTHER:
4243 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
4244 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4245 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4246 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4247 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle);
4248 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4249 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4250 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4251 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4252 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4253 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4254 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4255 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4256 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4258 if (torture_setting_bool(tctx, "samba4", false)) {
4259 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4261 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4262 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4264 ret &= test_GroupList(p, tctx, &domain_handle);
4265 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4266 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4267 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4271 if (!policy_handle_empty(&user_handle) &&
4272 !test_DeleteUser(p, tctx, &user_handle)) {
4276 if (!policy_handle_empty(&alias_handle) &&
4277 !test_DeleteAlias(p, tctx, &alias_handle)) {
4281 if (!policy_handle_empty(&group_handle) &&
4282 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4286 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4288 /* reconnect the main handle */
4289 ret &= test_Connect(p, tctx, handle);
4292 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4298 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4299 struct policy_handle *handle, const char *domain,
4300 enum torture_samr_choice which_ops)
4303 struct samr_LookupDomain r;
4304 struct lsa_String n1;
4305 struct lsa_String n2;
4308 printf("Testing LookupDomain(%s)\n", domain);
4310 /* check for correct error codes */
4311 r.in.connect_handle = handle;
4312 r.in.domain_name = &n2;
4315 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4316 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4317 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4321 init_lsa_String(&n2, "xxNODOMAINxx");
4323 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4324 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4325 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4329 r.in.connect_handle = handle;
4331 init_lsa_String(&n1, domain);
4332 r.in.domain_name = &n1;
4334 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4335 if (!NT_STATUS_IS_OK(status)) {
4336 printf("LookupDomain failed - %s\n", nt_errstr(status));
4340 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4344 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4352 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4353 struct policy_handle *handle, enum torture_samr_choice which_ops)
4356 struct samr_EnumDomains r;
4357 uint32_t resume_handle = 0;
4361 r.in.connect_handle = handle;
4362 r.in.resume_handle = &resume_handle;
4363 r.in.buf_size = (uint32_t)-1;
4364 r.out.resume_handle = &resume_handle;
4366 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4367 if (!NT_STATUS_IS_OK(status)) {
4368 printf("EnumDomains failed - %s\n", nt_errstr(status));
4376 for (i=0;i<r.out.sam->count;i++) {
4377 if (!test_LookupDomain(p, tctx, handle,
4378 r.out.sam->entries[i].name.string, which_ops)) {
4383 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4384 if (!NT_STATUS_IS_OK(status)) {
4385 printf("EnumDomains failed - %s\n", nt_errstr(status));
4393 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4394 struct policy_handle *handle)
4397 struct samr_Connect r;
4398 struct samr_Connect2 r2;
4399 struct samr_Connect3 r3;
4400 struct samr_Connect4 r4;
4401 struct samr_Connect5 r5;
4402 union samr_ConnectInfo info;
4403 struct policy_handle h;
4404 bool ret = true, got_handle = false;
4406 printf("testing samr_Connect\n");
4408 r.in.system_name = 0;
4409 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4410 r.out.connect_handle = &h;
4412 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4413 if (!NT_STATUS_IS_OK(status)) {
4414 printf("Connect failed - %s\n", nt_errstr(status));
4421 printf("testing samr_Connect2\n");
4423 r2.in.system_name = NULL;
4424 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4425 r2.out.connect_handle = &h;
4427 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4428 if (!NT_STATUS_IS_OK(status)) {
4429 printf("Connect2 failed - %s\n", nt_errstr(status));
4433 test_samr_handle_Close(p, mem_ctx, handle);
4439 printf("testing samr_Connect3\n");
4441 r3.in.system_name = NULL;
4443 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4444 r3.out.connect_handle = &h;
4446 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4447 if (!NT_STATUS_IS_OK(status)) {
4448 printf("Connect3 failed - %s\n", nt_errstr(status));
4452 test_samr_handle_Close(p, mem_ctx, handle);
4458 printf("testing samr_Connect4\n");
4460 r4.in.system_name = "";
4462 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4463 r4.out.connect_handle = &h;
4465 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4466 if (!NT_STATUS_IS_OK(status)) {
4467 printf("Connect4 failed - %s\n", nt_errstr(status));
4471 test_samr_handle_Close(p, mem_ctx, handle);
4477 printf("testing samr_Connect5\n");
4479 info.info1.unknown1 = 0;
4480 info.info1.unknown2 = 0;
4482 r5.in.system_name = "";
4483 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4486 r5.out.info = &info;
4487 r5.out.connect_handle = &h;
4489 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4490 if (!NT_STATUS_IS_OK(status)) {
4491 printf("Connect5 failed - %s\n", nt_errstr(status));
4495 test_samr_handle_Close(p, mem_ctx, handle);
4505 bool torture_rpc_samr(struct torture_context *torture)
4508 struct dcerpc_pipe *p;
4510 struct policy_handle handle;
4512 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4513 if (!NT_STATUS_IS_OK(status)) {
4517 ret &= test_Connect(p, torture, &handle);
4519 ret &= test_QuerySecurity(p, torture, &handle);
4521 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4523 ret &= test_SetDsrmPassword(p, torture, &handle);
4525 ret &= test_Shutdown(p, torture, &handle);
4527 ret &= test_samr_handle_Close(p, torture, &handle);
4533 bool torture_rpc_samr_users(struct torture_context *torture)
4536 struct dcerpc_pipe *p;
4538 struct policy_handle handle;
4540 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4541 if (!NT_STATUS_IS_OK(status)) {
4545 ret &= test_Connect(p, torture, &handle);
4547 ret &= test_QuerySecurity(p, torture, &handle);
4549 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4551 ret &= test_SetDsrmPassword(p, torture, &handle);
4553 ret &= test_Shutdown(p, torture, &handle);
4555 ret &= test_samr_handle_Close(p, torture, &handle);
4561 bool torture_rpc_samr_passwords(struct torture_context *torture)
4564 struct dcerpc_pipe *p;
4566 struct policy_handle handle;
4568 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4569 if (!NT_STATUS_IS_OK(status)) {
4573 ret &= test_Connect(p, torture, &handle);
4575 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4577 ret &= test_samr_handle_Close(p, torture, &handle);