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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_samr_c.h"
28 #include "lib/crypto/crypto.h"
29 #include "libcli/auth/libcli_auth.h"
30 #include "libcli/security/security.h"
31 #include "torture/rpc/rpc.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, TALLOC_CTX *mem_ctx,
82 struct policy_handle *handle)
85 struct samr_Shutdown r;
87 if (!lp_parm_bool(-1, "torture", "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, mem_ctx, &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, TALLOC_CTX *mem_ctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!lp_parm_bool(-1, "torture", "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, mem_ctx, &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, TALLOC_CTX *mem_ctx,
139 struct policy_handle *handle)
142 struct samr_QuerySecurity r;
143 struct samr_SetSecurity s;
145 r.in.handle = handle;
148 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
149 if (!NT_STATUS_IS_OK(status)) {
150 printf("QuerySecurity failed - %s\n", nt_errstr(status));
154 if (r.out.sdbuf == NULL) {
158 s.in.handle = handle;
160 s.in.sdbuf = r.out.sdbuf;
162 if (lp_parm_bool(-1, "torture", "samba4", False)) {
163 printf("skipping SetSecurity test against Samba4\n");
167 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
168 if (!NT_STATUS_IS_OK(status)) {
169 printf("SetSecurity failed - %s\n", nt_errstr(status));
173 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
174 if (!NT_STATUS_IS_OK(status)) {
175 printf("QuerySecurity failed - %s\n", nt_errstr(status));
183 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
184 struct policy_handle *handle, uint32_t base_acct_flags,
185 const char *base_account_name)
188 struct samr_SetUserInfo s;
189 struct samr_SetUserInfo2 s2;
190 struct samr_QueryUserInfo q;
191 struct samr_QueryUserInfo q0;
192 union samr_UserInfo u;
194 const char *test_account_name;
196 uint32_t user_extra_flags = 0;
197 if (base_acct_flags == ACB_NORMAL) {
198 /* When created, accounts are expired by default */
199 user_extra_flags = ACB_PW_EXPIRED;
202 s.in.user_handle = handle;
205 s2.in.user_handle = handle;
208 q.in.user_handle = handle;
212 #define TESTCALL(call, r) \
213 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
214 if (!NT_STATUS_IS_OK(status)) { \
215 printf(#call " level %u failed - %s (%s)\n", \
216 r.in.level, nt_errstr(status), __location__); \
221 #define STRING_EQUAL(s1, s2, field) \
222 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
223 printf("Failed to set %s to '%s' (%s)\n", \
224 #field, s2, __location__); \
229 #define INT_EQUAL(i1, i2, field) \
231 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
232 #field, i2, i1, __location__); \
237 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
238 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
240 TESTCALL(QueryUserInfo, q) \
242 s2.in.level = lvl1; \
245 ZERO_STRUCT(u.info21); \
246 u.info21.fields_present = fpval; \
248 init_lsa_String(&u.info ## lvl1.field1, value); \
249 TESTCALL(SetUserInfo, s) \
250 TESTCALL(SetUserInfo2, s2) \
251 init_lsa_String(&u.info ## lvl1.field1, ""); \
252 TESTCALL(QueryUserInfo, q); \
254 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
256 TESTCALL(QueryUserInfo, q) \
258 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
261 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
262 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
264 TESTCALL(QueryUserInfo, q) \
266 s2.in.level = lvl1; \
269 uint8_t *bits = u.info21.logon_hours.bits; \
270 ZERO_STRUCT(u.info21); \
271 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
272 u.info21.logon_hours.units_per_week = 168; \
273 u.info21.logon_hours.bits = bits; \
275 u.info21.fields_present = fpval; \
277 u.info ## lvl1.field1 = value; \
278 TESTCALL(SetUserInfo, s) \
279 TESTCALL(SetUserInfo2, s2) \
280 u.info ## lvl1.field1 = 0; \
281 TESTCALL(QueryUserInfo, q); \
283 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
285 TESTCALL(QueryUserInfo, q) \
287 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
290 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
291 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
295 do { TESTCALL(QueryUserInfo, q0) } while (0);
297 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
298 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
299 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
302 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
303 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
304 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
305 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
306 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
307 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
308 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
309 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
310 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
311 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
312 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
313 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
314 test_account_name = base_account_name;
315 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
316 SAMR_FIELD_ACCOUNT_NAME);
318 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
319 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
323 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
324 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
325 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
326 SAMR_FIELD_FULL_NAME);
328 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
329 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
330 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
331 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
332 SAMR_FIELD_LOGON_SCRIPT);
334 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
335 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
336 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
337 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
338 SAMR_FIELD_PROFILE_PATH);
340 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
341 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
342 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
343 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
344 SAMR_FIELD_HOME_DIRECTORY);
345 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
346 SAMR_FIELD_HOME_DIRECTORY);
348 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
349 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
350 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
351 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
352 SAMR_FIELD_HOME_DRIVE);
353 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
354 SAMR_FIELD_HOME_DRIVE);
356 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
357 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
358 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
359 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
360 SAMR_FIELD_DESCRIPTION);
362 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
363 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
364 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
365 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
366 SAMR_FIELD_WORKSTATIONS);
368 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
369 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
370 SAMR_FIELD_PARAMETERS);
372 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
373 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
374 SAMR_FIELD_COUNTRY_CODE);
376 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
377 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
378 SAMR_FIELD_CODE_PAGE);
380 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
381 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
382 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
383 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
384 SAMR_FIELD_LOGON_HOURS);
386 if (lp_parm_bool(-1, "torture", "samba4", False)) {
387 printf("skipping Set Account Flag tests against Samba4\n");
391 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
392 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
393 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
395 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
396 (base_acct_flags | ACB_DISABLED),
397 (base_acct_flags | ACB_DISABLED | user_extra_flags),
400 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
401 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
402 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
403 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
405 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
406 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
407 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
411 /* The 'autolock' flag doesn't stick - check this */
412 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
413 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
414 (base_acct_flags | ACB_DISABLED | user_extra_flags),
417 /* Removing the 'disabled' flag doesn't stick - check this */
418 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
420 (base_acct_flags | ACB_DISABLED | user_extra_flags),
423 /* The 'store plaintext' flag does stick */
424 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
425 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
426 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
428 /* The 'use DES' flag does stick */
429 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
430 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
431 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
433 /* The 'don't require kerberos pre-authentication flag does stick */
434 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
435 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
436 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
438 /* The 'no kerberos PAC required' flag sticks */
439 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
440 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
441 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
444 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
445 (base_acct_flags | ACB_DISABLED),
446 (base_acct_flags | ACB_DISABLED | user_extra_flags),
447 SAMR_FIELD_ACCT_FLAGS);
450 /* these fail with win2003 - it appears you can't set the primary gid?
451 the set succeeds, but the gid isn't changed. Very weird! */
452 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
453 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
454 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
455 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
462 generate a random password for password change tests
464 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
466 size_t len = MAX(8, min_len) + (random() % 6);
467 char *s = generate_random_str(mem_ctx, len);
468 printf("Generated password '%s'\n", s);
473 generate a random password for password change tests (fixed length)
475 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
477 char *s = generate_random_str(mem_ctx, len);
478 printf("Generated password '%s'\n", s);
482 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
483 struct policy_handle *handle, char **password)
486 struct samr_SetUserInfo s;
487 union samr_UserInfo u;
489 DATA_BLOB session_key;
491 struct samr_GetUserPwInfo pwp;
492 int policy_min_pw_len = 0;
493 pwp.in.user_handle = handle;
495 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
496 if (NT_STATUS_IS_OK(status)) {
497 policy_min_pw_len = pwp.out.info.min_password_length;
499 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
501 s.in.user_handle = handle;
505 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
506 /* w2k3 ignores this length */
507 u.info24.pw_len = strlen_m(newpass) * 2;
509 status = dcerpc_fetch_session_key(p, &session_key);
510 if (!NT_STATUS_IS_OK(status)) {
511 printf("SetUserInfo level %u - no session key - %s\n",
512 s.in.level, nt_errstr(status));
516 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
518 printf("Testing SetUserInfo level 24 (set password)\n");
520 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
521 if (!NT_STATUS_IS_OK(status)) {
522 printf("SetUserInfo level %u failed - %s\n",
523 s.in.level, nt_errstr(status));
533 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
534 struct policy_handle *handle, uint32_t fields_present,
538 struct samr_SetUserInfo s;
539 union samr_UserInfo u;
541 DATA_BLOB session_key;
543 struct samr_GetUserPwInfo pwp;
544 int policy_min_pw_len = 0;
545 pwp.in.user_handle = handle;
547 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
548 if (NT_STATUS_IS_OK(status)) {
549 policy_min_pw_len = pwp.out.info.min_password_length;
551 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
553 s.in.user_handle = handle;
559 u.info23.info.fields_present = fields_present;
561 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
563 status = dcerpc_fetch_session_key(p, &session_key);
564 if (!NT_STATUS_IS_OK(status)) {
565 printf("SetUserInfo level %u - no session key - %s\n",
566 s.in.level, nt_errstr(status));
570 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
572 printf("Testing SetUserInfo level 23 (set password)\n");
574 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
575 if (!NT_STATUS_IS_OK(status)) {
576 printf("SetUserInfo level %u failed - %s\n",
577 s.in.level, nt_errstr(status));
583 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
585 status = dcerpc_fetch_session_key(p, &session_key);
586 if (!NT_STATUS_IS_OK(status)) {
587 printf("SetUserInfo level %u - no session key - %s\n",
588 s.in.level, nt_errstr(status));
592 /* This should break the key nicely */
593 session_key.length--;
594 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
596 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
598 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
599 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
600 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
601 s.in.level, nt_errstr(status));
609 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
610 struct policy_handle *handle, char **password)
613 struct samr_SetUserInfo s;
614 union samr_UserInfo u;
616 DATA_BLOB session_key;
617 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
618 uint8_t confounder[16];
620 struct MD5Context ctx;
621 struct samr_GetUserPwInfo pwp;
622 int policy_min_pw_len = 0;
623 pwp.in.user_handle = handle;
625 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
626 if (NT_STATUS_IS_OK(status)) {
627 policy_min_pw_len = pwp.out.info.min_password_length;
629 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
631 s.in.user_handle = handle;
635 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
636 u.info26.pw_len = strlen(newpass);
638 status = dcerpc_fetch_session_key(p, &session_key);
639 if (!NT_STATUS_IS_OK(status)) {
640 printf("SetUserInfo level %u - no session key - %s\n",
641 s.in.level, nt_errstr(status));
645 generate_random_buffer((uint8_t *)confounder, 16);
648 MD5Update(&ctx, confounder, 16);
649 MD5Update(&ctx, session_key.data, session_key.length);
650 MD5Final(confounded_session_key.data, &ctx);
652 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
653 memcpy(&u.info26.password.data[516], confounder, 16);
655 printf("Testing SetUserInfo level 26 (set password ex)\n");
657 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
658 if (!NT_STATUS_IS_OK(status)) {
659 printf("SetUserInfo level %u failed - %s\n",
660 s.in.level, nt_errstr(status));
666 /* This should break the key nicely */
667 confounded_session_key.data[0]++;
669 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
670 memcpy(&u.info26.password.data[516], confounder, 16);
672 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
674 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
675 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
676 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
677 s.in.level, nt_errstr(status));
686 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
687 struct policy_handle *handle, uint32_t fields_present,
691 struct samr_SetUserInfo s;
692 union samr_UserInfo u;
694 DATA_BLOB session_key;
695 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
696 struct MD5Context ctx;
697 uint8_t confounder[16];
699 struct samr_GetUserPwInfo pwp;
700 int policy_min_pw_len = 0;
701 pwp.in.user_handle = handle;
703 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
704 if (NT_STATUS_IS_OK(status)) {
705 policy_min_pw_len = pwp.out.info.min_password_length;
707 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
709 s.in.user_handle = handle;
715 u.info25.info.fields_present = fields_present;
717 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
719 status = dcerpc_fetch_session_key(p, &session_key);
720 if (!NT_STATUS_IS_OK(status)) {
721 printf("SetUserInfo level %u - no session key - %s\n",
722 s.in.level, nt_errstr(status));
726 generate_random_buffer((uint8_t *)confounder, 16);
729 MD5Update(&ctx, confounder, 16);
730 MD5Update(&ctx, session_key.data, session_key.length);
731 MD5Final(confounded_session_key.data, &ctx);
733 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
734 memcpy(&u.info25.password.data[516], confounder, 16);
736 printf("Testing SetUserInfo level 25 (set password ex)\n");
738 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
739 if (!NT_STATUS_IS_OK(status)) {
740 printf("SetUserInfo level %u failed - %s\n",
741 s.in.level, nt_errstr(status));
747 /* This should break the key nicely */
748 confounded_session_key.data[0]++;
750 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
751 memcpy(&u.info25.password.data[516], confounder, 16);
753 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
755 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
756 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
757 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
758 s.in.level, nt_errstr(status));
765 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
766 struct policy_handle *handle)
769 struct samr_SetAliasInfo r;
770 struct samr_QueryAliasInfo q;
771 uint16_t levels[] = {2, 3};
775 /* Ignoring switch level 1, as that includes the number of members for the alias
776 * and setting this to a wrong value might have negative consequences
779 for (i=0;i<ARRAY_SIZE(levels);i++) {
780 printf("Testing SetAliasInfo level %u\n", levels[i]);
782 r.in.alias_handle = handle;
783 r.in.level = levels[i];
784 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
785 switch (r.in.level) {
786 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
787 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
788 "Test Description, should test I18N as well"); break;
791 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
792 if (!NT_STATUS_IS_OK(status)) {
793 printf("SetAliasInfo level %u failed - %s\n",
794 levels[i], nt_errstr(status));
798 q.in.alias_handle = handle;
799 q.in.level = levels[i];
801 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
802 if (!NT_STATUS_IS_OK(status)) {
803 printf("QueryAliasInfo level %u failed - %s\n",
804 levels[i], nt_errstr(status));
812 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
813 struct policy_handle *user_handle)
815 struct samr_GetGroupsForUser r;
819 printf("testing GetGroupsForUser\n");
821 r.in.user_handle = user_handle;
823 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
824 if (!NT_STATUS_IS_OK(status)) {
825 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
833 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
834 struct lsa_String *domain_name)
837 struct samr_GetDomPwInfo r;
840 r.in.domain_name = domain_name;
841 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
843 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
844 if (!NT_STATUS_IS_OK(status)) {
845 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
849 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
850 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
852 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
853 if (!NT_STATUS_IS_OK(status)) {
854 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
858 r.in.domain_name->string = "\\\\__NONAME__";
859 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
861 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
862 if (!NT_STATUS_IS_OK(status)) {
863 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
867 r.in.domain_name->string = "\\\\Builtin";
868 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
870 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
871 if (!NT_STATUS_IS_OK(status)) {
872 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
880 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
881 struct policy_handle *handle)
884 struct samr_GetUserPwInfo r;
887 printf("Testing GetUserPwInfo\n");
889 r.in.user_handle = handle;
891 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
892 if (!NT_STATUS_IS_OK(status)) {
893 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
900 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
901 struct policy_handle *domain_handle, const char *name,
905 struct samr_LookupNames n;
906 struct lsa_String sname[2];
908 init_lsa_String(&sname[0], name);
910 n.in.domain_handle = domain_handle;
913 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
914 if (NT_STATUS_IS_OK(status)) {
915 *rid = n.out.rids.ids[0];
920 init_lsa_String(&sname[1], "xxNONAMExx");
922 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
923 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
924 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
928 init_lsa_String(&sname[1], "xxNONAMExx");
930 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
931 if (!NT_STATUS_IS_OK(status)) {
932 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
938 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
939 struct policy_handle *domain_handle,
940 const char *name, struct policy_handle *user_handle)
943 struct samr_OpenUser r;
946 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
947 if (!NT_STATUS_IS_OK(status)) {
951 r.in.domain_handle = domain_handle;
952 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
954 r.out.user_handle = user_handle;
955 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
956 if (!NT_STATUS_IS_OK(status)) {
957 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
964 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
965 struct policy_handle *handle)
968 struct samr_ChangePasswordUser r;
970 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
971 struct policy_handle user_handle;
972 char *oldpass = "test";
973 char *newpass = "test2";
974 uint8_t old_nt_hash[16], new_nt_hash[16];
975 uint8_t old_lm_hash[16], new_lm_hash[16];
977 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
978 if (!NT_STATUS_IS_OK(status)) {
982 printf("Testing ChangePasswordUser for user 'testuser'\n");
984 printf("old password: %s\n", oldpass);
985 printf("new password: %s\n", newpass);
987 E_md4hash(oldpass, old_nt_hash);
988 E_md4hash(newpass, new_nt_hash);
989 E_deshash(oldpass, old_lm_hash);
990 E_deshash(newpass, new_lm_hash);
992 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
993 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
994 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
995 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
996 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
997 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
999 r.in.handle = &user_handle;
1000 r.in.lm_present = 1;
1001 r.in.old_lm_crypted = &hash1;
1002 r.in.new_lm_crypted = &hash2;
1003 r.in.nt_present = 1;
1004 r.in.old_nt_crypted = &hash3;
1005 r.in.new_nt_crypted = &hash4;
1006 r.in.cross1_present = 1;
1007 r.in.nt_cross = &hash5;
1008 r.in.cross2_present = 1;
1009 r.in.lm_cross = &hash6;
1011 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1012 if (!NT_STATUS_IS_OK(status)) {
1013 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1017 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1025 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1026 const char *acct_name,
1027 struct policy_handle *handle, char **password)
1030 struct samr_ChangePasswordUser r;
1032 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1033 struct policy_handle user_handle;
1035 uint8_t old_nt_hash[16], new_nt_hash[16];
1036 uint8_t old_lm_hash[16], new_lm_hash[16];
1039 struct samr_GetUserPwInfo pwp;
1040 int policy_min_pw_len = 0;
1042 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1043 if (!NT_STATUS_IS_OK(status)) {
1046 pwp.in.user_handle = &user_handle;
1048 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1049 if (NT_STATUS_IS_OK(status)) {
1050 policy_min_pw_len = pwp.out.info.min_password_length;
1052 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1054 printf("Testing ChangePasswordUser\n");
1057 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1061 oldpass = *password;
1063 E_md4hash(oldpass, old_nt_hash);
1064 E_md4hash(newpass, new_nt_hash);
1065 E_deshash(oldpass, old_lm_hash);
1066 E_deshash(newpass, new_lm_hash);
1068 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1069 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1070 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1071 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1072 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1073 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1075 r.in.user_handle = &user_handle;
1076 r.in.lm_present = 1;
1077 r.in.old_lm_crypted = &hash1;
1078 r.in.new_lm_crypted = &hash2;
1079 r.in.nt_present = 1;
1080 r.in.old_nt_crypted = &hash3;
1081 r.in.new_nt_crypted = &hash4;
1082 r.in.cross1_present = 1;
1083 r.in.nt_cross = &hash5;
1084 r.in.cross2_present = 1;
1085 r.in.lm_cross = &hash6;
1087 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1088 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1089 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1090 } else if (!NT_STATUS_IS_OK(status)) {
1091 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1094 *password = newpass;
1097 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1105 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1106 const char *acct_name,
1107 struct policy_handle *handle, char **password)
1110 struct samr_OemChangePasswordUser2 r;
1112 struct samr_Password lm_verifier;
1113 struct samr_CryptPassword lm_pass;
1114 struct lsa_AsciiString server, account, account_bad;
1117 uint8_t old_lm_hash[16], new_lm_hash[16];
1119 struct samr_GetDomPwInfo dom_pw_info;
1120 int policy_min_pw_len = 0;
1122 struct lsa_String domain_name;
1124 domain_name.string = "";
1125 dom_pw_info.in.domain_name = &domain_name;
1127 printf("Testing OemChangePasswordUser2\n");
1130 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1134 oldpass = *password;
1136 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1137 if (NT_STATUS_IS_OK(status)) {
1138 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1141 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1143 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1144 account.string = acct_name;
1146 E_deshash(oldpass, old_lm_hash);
1147 E_deshash(newpass, new_lm_hash);
1149 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1150 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1151 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1153 r.in.server = &server;
1154 r.in.account = &account;
1155 r.in.password = &lm_pass;
1156 r.in.hash = &lm_verifier;
1158 /* Break the verification */
1159 lm_verifier.hash[0]++;
1161 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1163 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1164 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1165 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1170 /* This shouldn't be a valid name */
1171 account_bad.string = TEST_ACCOUNT_NAME "XX";
1172 r.in.account = &account_bad;
1174 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1176 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1177 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1182 E_deshash(oldpass, old_lm_hash);
1183 E_deshash(newpass, new_lm_hash);
1185 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1186 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1187 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1189 r.in.server = &server;
1190 r.in.account = &account;
1191 r.in.password = &lm_pass;
1192 r.in.hash = &lm_verifier;
1194 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1195 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1196 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1197 } else if (!NT_STATUS_IS_OK(status)) {
1198 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1201 *password = newpass;
1208 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1209 const char *acct_name,
1210 struct policy_handle *handle, char **password)
1213 struct samr_ChangePasswordUser2 r;
1215 struct lsa_String server, account;
1216 struct samr_CryptPassword nt_pass, lm_pass;
1217 struct samr_Password nt_verifier, lm_verifier;
1220 uint8_t old_nt_hash[16], new_nt_hash[16];
1221 uint8_t old_lm_hash[16], new_lm_hash[16];
1223 struct samr_GetDomPwInfo dom_pw_info;
1224 int policy_min_pw_len = 0;
1226 struct lsa_String domain_name;
1229 domain_name.string = "";
1230 dom_pw_info.in.domain_name = &domain_name;
1232 printf("Testing ChangePasswordUser2\n");
1235 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1238 oldpass = *password;
1240 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1241 if (NT_STATUS_IS_OK(status)) {
1242 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1245 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1247 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1248 init_lsa_String(&account, acct_name);
1250 E_md4hash(oldpass, old_nt_hash);
1251 E_md4hash(newpass, new_nt_hash);
1253 E_deshash(oldpass, old_lm_hash);
1254 E_deshash(newpass, new_lm_hash);
1256 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1257 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1258 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1260 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1261 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1262 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1264 r.in.server = &server;
1265 r.in.account = &account;
1266 r.in.nt_password = &nt_pass;
1267 r.in.nt_verifier = &nt_verifier;
1269 r.in.lm_password = &lm_pass;
1270 r.in.lm_verifier = &lm_verifier;
1272 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1273 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1274 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1275 } else if (!NT_STATUS_IS_OK(status)) {
1276 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1279 *password = newpass;
1286 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1287 const char *account_string,
1288 int policy_min_pw_len,
1290 const char *newpass,
1291 NTTIME last_password_change,
1292 BOOL handle_reject_reason)
1295 struct samr_ChangePasswordUser3 r;
1297 struct lsa_String server, account, account_bad;
1298 struct samr_CryptPassword nt_pass, lm_pass;
1299 struct samr_Password nt_verifier, lm_verifier;
1301 uint8_t old_nt_hash[16], new_nt_hash[16];
1302 uint8_t old_lm_hash[16], new_lm_hash[16];
1305 printf("Testing ChangePasswordUser3\n");
1307 if (newpass == NULL) {
1308 if (policy_min_pw_len == 0) {
1309 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1311 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1314 printf("Using password '%s'\n", newpass);
1318 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1322 oldpass = *password;
1323 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1324 init_lsa_String(&account, account_string);
1326 E_md4hash(oldpass, old_nt_hash);
1327 E_md4hash(newpass, new_nt_hash);
1329 E_deshash(oldpass, old_lm_hash);
1330 E_deshash(newpass, new_lm_hash);
1332 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1333 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1334 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1336 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1337 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1338 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1340 /* Break the verification */
1341 nt_verifier.hash[0]++;
1343 r.in.server = &server;
1344 r.in.account = &account;
1345 r.in.nt_password = &nt_pass;
1346 r.in.nt_verifier = &nt_verifier;
1348 r.in.lm_password = &lm_pass;
1349 r.in.lm_verifier = &lm_verifier;
1350 r.in.password3 = NULL;
1352 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1353 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1354 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1355 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1360 /* This shouldn't be a valid name */
1361 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1363 r.in.account = &account_bad;
1364 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1365 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1366 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1371 E_md4hash(oldpass, old_nt_hash);
1372 E_md4hash(newpass, new_nt_hash);
1374 E_deshash(oldpass, old_lm_hash);
1375 E_deshash(newpass, new_lm_hash);
1377 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1378 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1379 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1381 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1382 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1383 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1385 r.in.server = &server;
1386 r.in.account = &account;
1387 r.in.nt_password = &nt_pass;
1388 r.in.nt_verifier = &nt_verifier;
1390 r.in.lm_password = &lm_pass;
1391 r.in.lm_verifier = &lm_verifier;
1392 r.in.password3 = NULL;
1394 unix_to_nt_time(&t, time(NULL));
1396 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1398 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1399 r.out.dominfo && r.out.reject && handle_reject_reason) {
1401 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1403 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1404 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1405 SAMR_REJECT_OTHER, r.out.reject->reason);
1410 /* We tested the order of precendence which is as follows:
1419 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1420 (last_password_change + r.out.dominfo->min_password_age > t)) {
1422 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1423 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1424 SAMR_REJECT_OTHER, r.out.reject->reason);
1428 } else if ((r.out.dominfo->min_password_length > 0) &&
1429 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1431 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1432 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1433 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1437 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1439 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1440 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1441 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1445 } else if ((r.out.dominfo->password_history_length > 0) &&
1446 strequal(oldpass, newpass)) {
1448 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1449 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1450 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1455 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1456 /* retry with adjusted size */
1457 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1458 r.out.dominfo->min_password_length,
1459 password, NULL, 0, False);
1463 } else if (!NT_STATUS_IS_OK(status)) {
1464 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1467 *password = talloc_strdup(mem_ctx, newpass);
1474 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1475 struct policy_handle *alias_handle)
1477 struct samr_GetMembersInAlias r;
1478 struct lsa_SidArray sids;
1482 printf("Testing GetMembersInAlias\n");
1484 r.in.alias_handle = alias_handle;
1487 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1488 if (!NT_STATUS_IS_OK(status)) {
1489 printf("GetMembersInAlias failed - %s\n",
1497 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1498 struct policy_handle *alias_handle,
1499 const struct dom_sid *domain_sid)
1501 struct samr_AddAliasMember r;
1502 struct samr_DeleteAliasMember d;
1505 struct dom_sid *sid;
1507 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1509 printf("testing AddAliasMember\n");
1510 r.in.alias_handle = alias_handle;
1513 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1514 if (!NT_STATUS_IS_OK(status)) {
1515 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1519 d.in.alias_handle = alias_handle;
1522 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1523 if (!NT_STATUS_IS_OK(status)) {
1524 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1531 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1532 struct policy_handle *alias_handle)
1534 struct samr_AddMultipleMembersToAlias a;
1535 struct samr_RemoveMultipleMembersFromAlias r;
1538 struct lsa_SidArray sids;
1540 printf("testing AddMultipleMembersToAlias\n");
1541 a.in.alias_handle = alias_handle;
1545 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1547 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1548 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1549 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1551 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1552 if (!NT_STATUS_IS_OK(status)) {
1553 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1558 printf("testing RemoveMultipleMembersFromAlias\n");
1559 r.in.alias_handle = alias_handle;
1562 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1563 if (!NT_STATUS_IS_OK(status)) {
1564 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1568 /* strange! removing twice doesn't give any error */
1569 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1570 if (!NT_STATUS_IS_OK(status)) {
1571 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1575 /* but removing an alias that isn't there does */
1576 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1578 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1579 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1580 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1587 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1588 struct policy_handle *user_handle)
1590 struct samr_TestPrivateFunctionsUser r;
1594 printf("Testing TestPrivateFunctionsUser\n");
1596 r.in.user_handle = user_handle;
1598 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1599 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1600 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1608 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1609 struct policy_handle *user_handle,
1610 struct policy_handle *domain_handle,
1611 uint32_t base_acct_flags,
1612 const char *base_acct_name, enum torture_samr_choice which_ops)
1614 TALLOC_CTX *user_ctx;
1615 char *password = NULL;
1619 const uint32_t password_fields[] = {
1620 SAMR_FIELD_PASSWORD,
1621 SAMR_FIELD_PASSWORD2,
1622 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1626 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1627 switch (which_ops) {
1628 case TORTURE_SAMR_USER_ATTRIBUTES:
1629 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1633 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1637 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1641 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
1646 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
1650 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
1654 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1658 case TORTURE_SAMR_PASSWORDS:
1659 for (i = 0; password_fields[i]; i++) {
1660 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1664 /* check it was set right */
1665 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
1670 for (i = 0; password_fields[i]; i++) {
1671 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1675 /* check it was set right */
1676 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
1681 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1685 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
1689 case TORTURE_SAMR_OTHER:
1690 /* We just need the account to exist */
1693 talloc_free(user_ctx);
1697 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1698 struct policy_handle *alias_handle,
1699 const struct dom_sid *domain_sid)
1703 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1707 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1711 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1715 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1719 if (lp_parm_bool(-1, "torture", "samba4", False)) {
1720 printf("skipping MultipleMembers Alias tests against Samba4\n");
1724 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1732 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1733 struct policy_handle *user_handle)
1735 struct samr_DeleteUser d;
1738 printf("Testing DeleteUser\n");
1740 d.in.user_handle = user_handle;
1741 d.out.user_handle = user_handle;
1743 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1744 if (!NT_STATUS_IS_OK(status)) {
1745 printf("DeleteUser failed - %s\n", nt_errstr(status));
1752 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1753 struct policy_handle *handle, const char *name)
1756 struct samr_DeleteUser d;
1757 struct policy_handle user_handle;
1760 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1761 if (!NT_STATUS_IS_OK(status)) {
1765 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1766 if (!NT_STATUS_IS_OK(status)) {
1770 d.in.user_handle = &user_handle;
1771 d.out.user_handle = &user_handle;
1772 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1773 if (!NT_STATUS_IS_OK(status)) {
1780 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1785 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1786 struct policy_handle *handle, const char *name)
1789 struct samr_OpenGroup r;
1790 struct samr_DeleteDomainGroup d;
1791 struct policy_handle group_handle;
1794 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1795 if (!NT_STATUS_IS_OK(status)) {
1799 r.in.domain_handle = handle;
1800 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1802 r.out.group_handle = &group_handle;
1803 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1804 if (!NT_STATUS_IS_OK(status)) {
1808 d.in.group_handle = &group_handle;
1809 d.out.group_handle = &group_handle;
1810 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1811 if (!NT_STATUS_IS_OK(status)) {
1818 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1823 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1824 struct policy_handle *domain_handle, const char *name)
1827 struct samr_OpenAlias r;
1828 struct samr_DeleteDomAlias d;
1829 struct policy_handle alias_handle;
1832 printf("testing DeleteAlias_byname\n");
1834 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1835 if (!NT_STATUS_IS_OK(status)) {
1839 r.in.domain_handle = domain_handle;
1840 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1842 r.out.alias_handle = &alias_handle;
1843 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1844 if (!NT_STATUS_IS_OK(status)) {
1848 d.in.alias_handle = &alias_handle;
1849 d.out.alias_handle = &alias_handle;
1850 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1851 if (!NT_STATUS_IS_OK(status)) {
1858 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
1862 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1863 struct policy_handle *alias_handle)
1865 struct samr_DeleteDomAlias d;
1868 printf("Testing DeleteAlias\n");
1870 d.in.alias_handle = alias_handle;
1871 d.out.alias_handle = alias_handle;
1873 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1874 if (!NT_STATUS_IS_OK(status)) {
1875 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1882 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1883 struct policy_handle *domain_handle,
1884 struct policy_handle *alias_handle,
1885 const struct dom_sid *domain_sid)
1888 struct samr_CreateDomAlias r;
1889 struct lsa_String name;
1893 init_lsa_String(&name, TEST_ALIASNAME);
1894 r.in.domain_handle = domain_handle;
1895 r.in.alias_name = &name;
1896 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1897 r.out.alias_handle = alias_handle;
1900 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1902 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1904 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1905 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1909 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1910 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1913 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1916 if (!NT_STATUS_IS_OK(status)) {
1917 printf("CreateAlias failed - %s\n", nt_errstr(status));
1921 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1928 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1929 const char *acct_name,
1930 struct policy_handle *domain_handle, char **password)
1938 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
1942 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
1946 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
1950 /* test what happens when setting the old password again */
1951 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
1956 char simple_pass[9];
1957 char *v = generate_random_str(mem_ctx, 1);
1959 ZERO_STRUCT(simple_pass);
1960 memset(simple_pass, *v, sizeof(simple_pass) - 1);
1962 /* test what happens when picking a simple password */
1963 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
1968 /* set samr_SetDomainInfo level 1 with min_length 5 */
1970 struct samr_QueryDomainInfo r;
1971 struct samr_SetDomainInfo s;
1972 uint16_t len_old, len;
1977 r.in.domain_handle = domain_handle;
1980 printf("testing samr_QueryDomainInfo level 1\n");
1981 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
1982 if (!NT_STATUS_IS_OK(status)) {
1986 s.in.domain_handle = domain_handle;
1988 s.in.info = r.out.info;
1990 len_old = s.in.info->info1.min_password_length;
1991 s.in.info->info1.min_password_length = len;
1993 printf("testing samr_SetDomainInfo level 1\n");
1994 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
1995 if (!NT_STATUS_IS_OK(status)) {
1999 printf("calling test_ChangePasswordUser3 with too short password\n");
2001 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2005 s.in.info->info1.min_password_length = len_old;
2007 printf("testing samr_SetDomainInfo level 1\n");
2008 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2009 if (!NT_STATUS_IS_OK(status)) {
2017 struct samr_OpenUser r;
2018 struct samr_QueryUserInfo q;
2019 struct samr_LookupNames n;
2020 struct policy_handle user_handle;
2022 n.in.domain_handle = domain_handle;
2024 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2025 n.in.names[0].string = acct_name;
2027 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2028 if (!NT_STATUS_IS_OK(status)) {
2029 printf("LookupNames failed - %s\n", nt_errstr(status));
2033 r.in.domain_handle = domain_handle;
2034 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2035 r.in.rid = n.out.rids.ids[0];
2036 r.out.user_handle = &user_handle;
2038 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2039 if (!NT_STATUS_IS_OK(status)) {
2040 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2044 q.in.user_handle = &user_handle;
2047 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2048 if (!NT_STATUS_IS_OK(status)) {
2049 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2053 printf("calling test_ChangePasswordUser3 with too early password change\n");
2055 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2056 q.out.info->info5.last_password_change, True)) {
2063 /* we change passwords twice - this has the effect of verifying
2064 they were changed correctly for the final call */
2065 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2069 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2076 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2077 struct policy_handle *domain_handle,
2078 struct policy_handle *user_handle_out,
2079 enum torture_samr_choice which_ops)
2082 TALLOC_CTX *user_ctx;
2085 struct samr_CreateUser r;
2086 struct samr_QueryUserInfo q;
2087 struct samr_DeleteUser d;
2090 /* This call creates a 'normal' account - check that it really does */
2091 const uint32_t acct_flags = ACB_NORMAL;
2092 struct lsa_String name;
2095 struct policy_handle user_handle;
2096 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2097 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2099 r.in.domain_handle = domain_handle;
2100 r.in.account_name = &name;
2101 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2102 r.out.user_handle = &user_handle;
2105 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2107 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2109 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2110 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2111 talloc_free(user_ctx);
2115 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2116 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2117 talloc_free(user_ctx);
2120 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2122 if (!NT_STATUS_IS_OK(status)) {
2123 talloc_free(user_ctx);
2124 printf("CreateUser failed - %s\n", nt_errstr(status));
2127 q.in.user_handle = &user_handle;
2130 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2131 if (!NT_STATUS_IS_OK(status)) {
2132 printf("QueryUserInfo level %u failed - %s\n",
2133 q.in.level, nt_errstr(status));
2136 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2137 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2138 q.out.info->info16.acct_flags,
2144 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2145 acct_flags, name.string, which_ops)) {
2149 if (user_handle_out) {
2150 *user_handle_out = user_handle;
2152 printf("Testing DeleteUser (createuser test)\n");
2154 d.in.user_handle = &user_handle;
2155 d.out.user_handle = &user_handle;
2157 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2158 if (!NT_STATUS_IS_OK(status)) {
2159 printf("DeleteUser failed - %s\n", nt_errstr(status));
2166 talloc_free(user_ctx);
2172 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2173 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2176 struct samr_CreateUser2 r;
2177 struct samr_QueryUserInfo q;
2178 struct samr_DeleteUser d;
2179 struct policy_handle user_handle;
2181 struct lsa_String name;
2186 uint32_t acct_flags;
2187 const char *account_name;
2189 } account_types[] = {
2190 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2191 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2192 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2193 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2194 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2195 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2196 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2197 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2198 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2199 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2200 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2201 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2202 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2203 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2204 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2207 for (i = 0; account_types[i].account_name; i++) {
2208 TALLOC_CTX *user_ctx;
2209 uint32_t acct_flags = account_types[i].acct_flags;
2210 uint32_t access_granted;
2211 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2212 init_lsa_String(&name, account_types[i].account_name);
2214 r.in.domain_handle = domain_handle;
2215 r.in.account_name = &name;
2216 r.in.acct_flags = acct_flags;
2217 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2218 r.out.user_handle = &user_handle;
2219 r.out.access_granted = &access_granted;
2222 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2224 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2226 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2227 talloc_free(user_ctx);
2228 printf("Server refused create of '%s'\n", r.in.account_name->string);
2231 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2232 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2233 talloc_free(user_ctx);
2237 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2240 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2241 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2242 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2246 if (NT_STATUS_IS_OK(status)) {
2247 q.in.user_handle = &user_handle;
2250 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2251 if (!NT_STATUS_IS_OK(status)) {
2252 printf("QueryUserInfo level %u failed - %s\n",
2253 q.in.level, nt_errstr(status));
2256 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2257 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2258 q.out.info->info16.acct_flags,
2264 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2265 acct_flags, name.string, which_ops)) {
2269 printf("Testing DeleteUser (createuser2 test)\n");
2271 d.in.user_handle = &user_handle;
2272 d.out.user_handle = &user_handle;
2274 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2275 if (!NT_STATUS_IS_OK(status)) {
2276 printf("DeleteUser failed - %s\n", nt_errstr(status));
2280 talloc_free(user_ctx);
2286 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2287 struct policy_handle *handle)
2290 struct samr_QueryAliasInfo r;
2291 uint16_t levels[] = {1, 2, 3};
2295 for (i=0;i<ARRAY_SIZE(levels);i++) {
2296 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2298 r.in.alias_handle = handle;
2299 r.in.level = levels[i];
2301 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2302 if (!NT_STATUS_IS_OK(status)) {
2303 printf("QueryAliasInfo level %u failed - %s\n",
2304 levels[i], nt_errstr(status));
2312 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2313 struct policy_handle *handle)
2316 struct samr_QueryGroupInfo r;
2317 uint16_t levels[] = {1, 2, 3, 4, 5};
2321 for (i=0;i<ARRAY_SIZE(levels);i++) {
2322 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2324 r.in.group_handle = handle;
2325 r.in.level = levels[i];
2327 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2328 if (!NT_STATUS_IS_OK(status)) {
2329 printf("QueryGroupInfo level %u failed - %s\n",
2330 levels[i], nt_errstr(status));
2338 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2339 struct policy_handle *handle)
2342 struct samr_QueryGroupMember r;
2345 printf("Testing QueryGroupMember\n");
2347 r.in.group_handle = handle;
2349 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2350 if (!NT_STATUS_IS_OK(status)) {
2351 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2359 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2360 struct policy_handle *handle)
2363 struct samr_QueryGroupInfo r;
2364 struct samr_SetGroupInfo s;
2365 uint16_t levels[] = {1, 2, 3, 4};
2366 uint16_t set_ok[] = {0, 1, 1, 1};
2370 for (i=0;i<ARRAY_SIZE(levels);i++) {
2371 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2373 r.in.group_handle = handle;
2374 r.in.level = levels[i];
2376 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 printf("QueryGroupInfo level %u failed - %s\n",
2379 levels[i], nt_errstr(status));
2383 printf("Testing SetGroupInfo level %u\n", levels[i]);
2385 s.in.group_handle = handle;
2386 s.in.level = levels[i];
2387 s.in.info = r.out.info;
2390 /* disabled this, as it changes the name only from the point of view of samr,
2391 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2392 the name is still reserved, so creating the old name fails, but deleting by the old name
2394 if (s.in.level == 2) {
2395 init_lsa_String(&s.in.info->string, "NewName");
2399 if (s.in.level == 4) {
2400 init_lsa_String(&s.in.info->description, "test description");
2403 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2405 if (!NT_STATUS_IS_OK(status)) {
2406 printf("SetGroupInfo level %u failed - %s\n",
2407 r.in.level, nt_errstr(status));
2412 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2413 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2414 r.in.level, nt_errstr(status));
2424 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2425 struct policy_handle *handle)
2428 struct samr_QueryUserInfo r;
2429 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2430 11, 12, 13, 14, 16, 17, 20, 21};
2434 for (i=0;i<ARRAY_SIZE(levels);i++) {
2435 printf("Testing QueryUserInfo level %u\n", levels[i]);
2437 r.in.user_handle = handle;
2438 r.in.level = levels[i];
2440 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2441 if (!NT_STATUS_IS_OK(status)) {
2442 printf("QueryUserInfo level %u failed - %s\n",
2443 levels[i], nt_errstr(status));
2451 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2452 struct policy_handle *handle)
2455 struct samr_QueryUserInfo2 r;
2456 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2457 11, 12, 13, 14, 16, 17, 20, 21};
2461 for (i=0;i<ARRAY_SIZE(levels);i++) {
2462 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2464 r.in.user_handle = handle;
2465 r.in.level = levels[i];
2467 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2468 if (!NT_STATUS_IS_OK(status)) {
2469 printf("QueryUserInfo2 level %u failed - %s\n",
2470 levels[i], nt_errstr(status));
2478 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2479 struct policy_handle *handle, uint32_t rid)
2482 struct samr_OpenUser r;
2483 struct policy_handle user_handle;
2486 printf("Testing OpenUser(%u)\n", rid);
2488 r.in.domain_handle = handle;
2489 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2491 r.out.user_handle = &user_handle;
2493 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2494 if (!NT_STATUS_IS_OK(status)) {
2495 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2499 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2503 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2507 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2511 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2515 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2519 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2526 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2527 struct policy_handle *handle, uint32_t rid)
2530 struct samr_OpenGroup r;
2531 struct policy_handle group_handle;
2534 printf("Testing OpenGroup(%u)\n", rid);
2536 r.in.domain_handle = handle;
2537 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2539 r.out.group_handle = &group_handle;
2541 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2542 if (!NT_STATUS_IS_OK(status)) {
2543 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2547 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2551 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2555 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2559 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2566 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2567 struct policy_handle *handle, uint32_t rid)
2570 struct samr_OpenAlias r;
2571 struct policy_handle alias_handle;
2574 printf("Testing OpenAlias(%u)\n", rid);
2576 r.in.domain_handle = handle;
2577 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2579 r.out.alias_handle = &alias_handle;
2581 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2582 if (!NT_STATUS_IS_OK(status)) {
2583 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2587 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2591 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2595 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2599 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2606 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2607 struct policy_handle *handle)
2610 struct samr_EnumDomainUsers r;
2611 uint32_t resume_handle=0;
2614 struct samr_LookupNames n;
2615 struct samr_LookupRids lr ;
2617 printf("Testing EnumDomainUsers\n");
2619 r.in.domain_handle = handle;
2620 r.in.resume_handle = &resume_handle;
2621 r.in.acct_flags = 0;
2622 r.in.max_size = (uint32_t)-1;
2623 r.out.resume_handle = &resume_handle;
2625 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2626 if (!NT_STATUS_IS_OK(status)) {
2627 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2635 if (r.out.sam->count == 0) {
2639 for (i=0;i<r.out.sam->count;i++) {
2640 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2645 printf("Testing LookupNames\n");
2646 n.in.domain_handle = handle;
2647 n.in.num_names = r.out.sam->count;
2648 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2649 for (i=0;i<r.out.sam->count;i++) {
2650 n.in.names[i].string = r.out.sam->entries[i].name.string;
2652 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2653 if (!NT_STATUS_IS_OK(status)) {
2654 printf("LookupNames failed - %s\n", nt_errstr(status));
2659 printf("Testing LookupRids\n");
2660 lr.in.domain_handle = handle;
2661 lr.in.num_rids = r.out.sam->count;
2662 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2663 for (i=0;i<r.out.sam->count;i++) {
2664 lr.in.rids[i] = r.out.sam->entries[i].idx;
2666 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2667 if (!NT_STATUS_IS_OK(status)) {
2668 printf("LookupRids failed - %s\n", nt_errstr(status));
2676 try blasting the server with a bunch of sync requests
2678 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2679 struct policy_handle *handle)
2682 struct samr_EnumDomainUsers r;
2683 uint32_t resume_handle=0;
2685 #define ASYNC_COUNT 100
2686 struct rpc_request *req[ASYNC_COUNT];
2688 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2689 printf("samr async test disabled - enable dangerous tests to use\n");
2693 printf("Testing EnumDomainUsers_async\n");
2695 r.in.domain_handle = handle;
2696 r.in.resume_handle = &resume_handle;
2697 r.in.acct_flags = 0;
2698 r.in.max_size = (uint32_t)-1;
2699 r.out.resume_handle = &resume_handle;
2701 for (i=0;i<ASYNC_COUNT;i++) {
2702 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2705 for (i=0;i<ASYNC_COUNT;i++) {
2706 status = dcerpc_ndr_request_recv(req[i]);
2707 if (!NT_STATUS_IS_OK(status)) {
2708 printf("EnumDomainUsers[%d] failed - %s\n",
2709 i, nt_errstr(status));
2714 printf("%d async requests OK\n", i);
2719 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2720 struct policy_handle *handle)
2723 struct samr_EnumDomainGroups r;
2724 uint32_t resume_handle=0;
2728 printf("Testing EnumDomainGroups\n");
2730 r.in.domain_handle = handle;
2731 r.in.resume_handle = &resume_handle;
2732 r.in.max_size = (uint32_t)-1;
2733 r.out.resume_handle = &resume_handle;
2735 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2736 if (!NT_STATUS_IS_OK(status)) {
2737 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2745 for (i=0;i<r.out.sam->count;i++) {
2746 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2754 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2755 struct policy_handle *handle)
2758 struct samr_EnumDomainAliases r;
2759 uint32_t resume_handle=0;
2763 printf("Testing EnumDomainAliases\n");
2765 r.in.domain_handle = handle;
2766 r.in.resume_handle = &resume_handle;
2767 r.in.acct_flags = (uint32_t)-1;
2768 r.out.resume_handle = &resume_handle;
2770 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2771 if (!NT_STATUS_IS_OK(status)) {
2772 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2780 for (i=0;i<r.out.sam->count;i++) {
2781 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2789 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2790 struct policy_handle *handle)
2793 struct samr_GetDisplayEnumerationIndex r;
2795 uint16_t levels[] = {1, 2, 3, 4, 5};
2796 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2799 for (i=0;i<ARRAY_SIZE(levels);i++) {
2800 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2802 r.in.domain_handle = handle;
2803 r.in.level = levels[i];
2804 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2806 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2809 !NT_STATUS_IS_OK(status) &&
2810 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2811 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2812 levels[i], nt_errstr(status));
2816 init_lsa_String(&r.in.name, "zzzzzzzz");
2818 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2820 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2821 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2822 levels[i], nt_errstr(status));
2830 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2831 struct policy_handle *handle)
2834 struct samr_GetDisplayEnumerationIndex2 r;
2836 uint16_t levels[] = {1, 2, 3, 4, 5};
2837 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2840 for (i=0;i<ARRAY_SIZE(levels);i++) {
2841 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2843 r.in.domain_handle = handle;
2844 r.in.level = levels[i];
2845 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2847 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2849 !NT_STATUS_IS_OK(status) &&
2850 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2851 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2852 levels[i], nt_errstr(status));
2856 init_lsa_String(&r.in.name, "zzzzzzzz");
2858 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2859 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2860 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2861 levels[i], nt_errstr(status));
2869 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2870 struct policy_handle *handle)
2873 struct samr_QueryDisplayInfo r;
2875 uint16_t levels[] = {1, 2, 3, 4, 5};
2878 for (i=0;i<ARRAY_SIZE(levels);i++) {
2879 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2881 r.in.domain_handle = handle;
2882 r.in.level = levels[i];
2884 r.in.max_entries = 1000;
2885 r.in.buf_size = (uint32_t)-1;
2887 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2888 if (!NT_STATUS_IS_OK(status)) {
2889 printf("QueryDisplayInfo level %u failed - %s\n",
2890 levels[i], nt_errstr(status));
2898 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2899 struct policy_handle *handle)
2902 struct samr_QueryDisplayInfo2 r;
2904 uint16_t levels[] = {1, 2, 3, 4, 5};
2907 for (i=0;i<ARRAY_SIZE(levels);i++) {
2908 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2910 r.in.domain_handle = handle;
2911 r.in.level = levels[i];
2913 r.in.max_entries = 1000;
2914 r.in.buf_size = (uint32_t)-1;
2916 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2917 if (!NT_STATUS_IS_OK(status)) {
2918 printf("QueryDisplayInfo2 level %u failed - %s\n",
2919 levels[i], nt_errstr(status));
2927 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2928 struct policy_handle *handle)
2931 struct samr_QueryDisplayInfo3 r;
2933 uint16_t levels[] = {1, 2, 3, 4, 5};
2936 for (i=0;i<ARRAY_SIZE(levels);i++) {
2937 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2939 r.in.domain_handle = handle;
2940 r.in.level = levels[i];
2942 r.in.max_entries = 1000;
2943 r.in.buf_size = (uint32_t)-1;
2945 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2946 if (!NT_STATUS_IS_OK(status)) {
2947 printf("QueryDisplayInfo3 level %u failed - %s\n",
2948 levels[i], nt_errstr(status));
2957 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2958 struct policy_handle *handle)
2961 struct samr_QueryDisplayInfo r;
2964 printf("Testing QueryDisplayInfo continuation\n");
2966 r.in.domain_handle = handle;
2969 r.in.max_entries = 1;
2970 r.in.buf_size = (uint32_t)-1;
2973 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2974 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2975 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2976 printf("expected idx %d but got %d\n",
2978 r.out.info.info1.entries[0].idx);
2982 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2983 !NT_STATUS_IS_OK(status)) {
2984 printf("QueryDisplayInfo level %u failed - %s\n",
2985 r.in.level, nt_errstr(status));
2990 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2991 NT_STATUS_IS_OK(status)) &&
2992 r.out.returned_size != 0);
2997 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2998 struct policy_handle *handle)
3001 struct samr_QueryDomainInfo r;
3002 struct samr_SetDomainInfo s;
3003 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3004 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3007 const char *domain_comment = talloc_asprintf(mem_ctx,
3008 "Tortured by Samba4 RPC-SAMR: %s",
3009 timestring(mem_ctx, time(NULL)));
3011 s.in.domain_handle = handle;
3013 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3015 s.in.info->info4.comment.string = domain_comment;
3016 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3017 if (!NT_STATUS_IS_OK(status)) {
3018 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3019 r.in.level, nt_errstr(status));
3023 for (i=0;i<ARRAY_SIZE(levels);i++) {
3024 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3026 r.in.domain_handle = handle;
3027 r.in.level = levels[i];
3029 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3030 if (!NT_STATUS_IS_OK(status)) {
3031 printf("QueryDomainInfo level %u failed - %s\n",
3032 r.in.level, nt_errstr(status));
3037 switch (levels[i]) {
3039 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3040 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3041 levels[i], r.out.info->info2.comment.string, domain_comment);
3044 if (!r.out.info->info2.primary.string) {
3045 printf("QueryDomainInfo level %u returned no PDC name\n",
3048 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3049 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3050 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3051 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3056 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3057 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3058 levels[i], r.out.info->info4.comment.string, domain_comment);
3063 if (!r.out.info->info6.primary.string) {
3064 printf("QueryDomainInfo level %u returned no PDC name\n",
3070 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3071 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3072 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3078 printf("Testing SetDomainInfo level %u\n", levels[i]);
3080 s.in.domain_handle = handle;
3081 s.in.level = levels[i];
3082 s.in.info = r.out.info;
3084 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3086 if (!NT_STATUS_IS_OK(status)) {
3087 printf("SetDomainInfo level %u failed - %s\n",
3088 r.in.level, nt_errstr(status));
3093 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3094 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3095 r.in.level, nt_errstr(status));
3101 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3102 if (!NT_STATUS_IS_OK(status)) {
3103 printf("QueryDomainInfo level %u failed - %s\n",
3104 r.in.level, nt_errstr(status));
3114 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3115 struct policy_handle *handle)
3118 struct samr_QueryDomainInfo2 r;
3119 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3123 for (i=0;i<ARRAY_SIZE(levels);i++) {
3124 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3126 r.in.domain_handle = handle;
3127 r.in.level = levels[i];
3129 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3130 if (!NT_STATUS_IS_OK(status)) {
3131 printf("QueryDomainInfo2 level %u failed - %s\n",
3132 r.in.level, nt_errstr(status));
3141 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3142 set of group names. */
3143 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3144 struct policy_handle *handle)
3146 struct samr_EnumDomainGroups q1;
3147 struct samr_QueryDisplayInfo q2;
3149 uint32_t resume_handle=0;
3154 const char **names = NULL;
3156 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3158 q1.in.domain_handle = handle;
3159 q1.in.resume_handle = &resume_handle;
3161 q1.out.resume_handle = &resume_handle;
3163 status = STATUS_MORE_ENTRIES;
3164 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3165 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3167 if (!NT_STATUS_IS_OK(status) &&
3168 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3171 for (i=0; i<q1.out.num_entries; i++) {
3172 add_string_to_array(mem_ctx,
3173 q1.out.sam->entries[i].name.string,
3174 &names, &num_names);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3187 q2.in.domain_handle = handle;
3189 q2.in.start_idx = 0;
3190 q2.in.max_entries = 5;
3191 q2.in.buf_size = (uint32_t)-1;
3193 status = STATUS_MORE_ENTRIES;
3194 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3195 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3197 if (!NT_STATUS_IS_OK(status) &&
3198 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3201 for (i=0; i<q2.out.info.info5.count; i++) {
3203 const char *name = q2.out.info.info5.entries[i].account_name.string;
3205 for (j=0; j<num_names; j++) {
3206 if (names[j] == NULL)
3208 /* Hmm. No strequal in samba4 */
3209 if (strequal(names[j], name)) {
3217 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3222 q2.in.start_idx += q2.out.info.info5.count;
3225 if (!NT_STATUS_IS_OK(status)) {
3226 printf("QueryDisplayInfo level 5 failed - %s\n",
3231 for (i=0; i<num_names; i++) {
3232 if (names[i] != NULL) {
3233 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3242 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3243 struct policy_handle *group_handle)
3245 struct samr_DeleteDomainGroup d;
3249 printf("Testing DeleteDomainGroup\n");
3251 d.in.group_handle = group_handle;
3252 d.out.group_handle = group_handle;
3254 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3255 if (!NT_STATUS_IS_OK(status)) {
3256 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3263 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3264 struct policy_handle *domain_handle)
3266 struct samr_TestPrivateFunctionsDomain r;
3270 printf("Testing TestPrivateFunctionsDomain\n");
3272 r.in.domain_handle = domain_handle;
3274 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3275 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3276 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3283 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3284 struct dom_sid *domain_sid,
3285 struct policy_handle *domain_handle)
3287 struct samr_RidToSid r;
3290 struct dom_sid *calc_sid;
3291 int rids[] = { 0, 42, 512, 10200 };
3294 for (i=0;i<ARRAY_SIZE(rids);i++) {
3296 printf("Testing RidToSid\n");
3298 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3299 r.in.domain_handle = domain_handle;
3302 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3303 if (!NT_STATUS_IS_OK(status)) {
3304 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3307 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3309 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3310 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3311 dom_sid_string(mem_ctx, r.out.sid),
3312 dom_sid_string(mem_ctx, calc_sid));
3321 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3322 struct policy_handle *domain_handle)
3324 struct samr_GetBootKeyInformation r;
3328 printf("Testing GetBootKeyInformation\n");
3330 r.in.domain_handle = domain_handle;
3332 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
3333 if (!NT_STATUS_IS_OK(status)) {
3334 /* w2k3 seems to fail this sometimes and pass it sometimes */
3335 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
3341 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3342 struct policy_handle *domain_handle,
3343 struct policy_handle *group_handle)
3346 struct samr_AddGroupMember r;
3347 struct samr_DeleteGroupMember d;
3348 struct samr_QueryGroupMember q;
3349 struct samr_SetMemberAttributesOfGroup s;
3353 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
3354 if (!NT_STATUS_IS_OK(status)) {
3355 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
3359 r.in.group_handle = group_handle;
3361 r.in.flags = 0; /* ??? */
3363 printf("Testing AddGroupMember and DeleteGroupMember\n");
3365 d.in.group_handle = group_handle;
3368 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3369 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
3370 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
3375 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3376 if (!NT_STATUS_IS_OK(status)) {
3377 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3381 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3382 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
3383 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
3388 if (lp_parm_bool(-1, "torture", "samba4", False)) {
3389 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
3391 /* this one is quite strange. I am using random inputs in the
3392 hope of triggering an error that might give us a clue */
3394 s.in.group_handle = group_handle;
3395 s.in.unknown1 = random();
3396 s.in.unknown2 = random();
3398 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
3399 if (!NT_STATUS_IS_OK(status)) {
3400 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
3405 q.in.group_handle = group_handle;
3407 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
3408 if (!NT_STATUS_IS_OK(status)) {
3409 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
3413 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3414 if (!NT_STATUS_IS_OK(status)) {
3415 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
3419 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3420 if (!NT_STATUS_IS_OK(status)) {
3421 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3429 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3430 struct policy_handle *domain_handle, struct policy_handle *group_handle)
3433 struct samr_CreateDomainGroup r;
3435 struct lsa_String name;
3438 init_lsa_String(&name, TEST_GROUPNAME);
3440 r.in.domain_handle = domain_handle;
3442 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3443 r.out.group_handle = group_handle;
3446 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3448 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3450 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3451 printf("Server refused create of '%s'\n", r.in.name->string);
3452 ZERO_STRUCTP(group_handle);
3456 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
3457 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3459 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
3463 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3465 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3466 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3468 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
3472 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3474 if (!NT_STATUS_IS_OK(status)) {
3475 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3479 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3480 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3484 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3493 its not totally clear what this does. It seems to accept any sid you like.
3495 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3496 TALLOC_CTX *mem_ctx,
3497 struct policy_handle *domain_handle)
3500 struct samr_RemoveMemberFromForeignDomain r;
3502 r.in.domain_handle = domain_handle;
3503 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3505 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3506 if (!NT_STATUS_IS_OK(status)) {
3507 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3516 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3517 struct policy_handle *handle);
3519 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3520 struct policy_handle *handle, struct dom_sid *sid,
3521 enum torture_samr_choice which_ops)
3524 struct samr_OpenDomain r;
3525 struct policy_handle domain_handle;
3526 struct policy_handle alias_handle;
3527 struct policy_handle user_handle;
3528 struct policy_handle group_handle;
3531 ZERO_STRUCT(alias_handle);
3532 ZERO_STRUCT(user_handle);
3533 ZERO_STRUCT(group_handle);
3534 ZERO_STRUCT(domain_handle);
3536 printf("Testing OpenDomain\n");
3538 r.in.connect_handle = handle;
3539 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3541 r.out.domain_handle = &domain_handle;
3543 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3544 if (!NT_STATUS_IS_OK(status)) {
3545 printf("OpenDomain failed - %s\n", nt_errstr(status));
3549 /* run the domain tests with the main handle closed - this tests
3550 the servers reference counting */
3551 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3553 switch (which_ops) {
3554 case TORTURE_SAMR_USER_ATTRIBUTES:
3555 case TORTURE_SAMR_PASSWORDS:
3556 ret &= test_CreateUser(p, mem_ctx, &domain_handle, NULL, which_ops);
3557 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
3559 case TORTURE_SAMR_OTHER:
3560 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
3561 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3562 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3563 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3564 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3565 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3566 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3567 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3568 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3569 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3570 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3571 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3572 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3573 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3574 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3576 if (lp_parm_bool(-1, "torture", "samba4", False)) {
3577 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
3579 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3580 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3582 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3583 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3584 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3585 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3589 if (!policy_handle_empty(&user_handle) &&
3590 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3594 if (!policy_handle_empty(&alias_handle) &&
3595 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3599 if (!policy_handle_empty(&group_handle) &&
3600 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3604 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3606 /* reconnect the main handle */
3607 ret &= test_Connect(p, mem_ctx, handle);
3610 printf("Testing domain %s failed!\n", dom_sid_string(mem_ctx, sid));
3616 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3617 struct policy_handle *handle, const char *domain,
3618 enum torture_samr_choice which_ops)
3621 struct samr_LookupDomain r;
3622 struct lsa_String n1;
3623 struct lsa_String n2;
3626 printf("Testing LookupDomain(%s)\n", domain);
3628 /* check for correct error codes */
3629 r.in.connect_handle = handle;
3630 r.in.domain_name = &n2;
3633 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3634 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3635 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3639 init_lsa_String(&n2, "xxNODOMAINxx");
3641 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3642 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3643 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3647 r.in.connect_handle = handle;
3649 init_lsa_String(&n1, domain);
3650 r.in.domain_name = &n1;
3652 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3653 if (!NT_STATUS_IS_OK(status)) {
3654 printf("LookupDomain failed - %s\n", nt_errstr(status));
3658 if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
3662 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
3670 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3671 struct policy_handle *handle, enum torture_samr_choice which_ops)
3674 struct samr_EnumDomains r;
3675 uint32_t resume_handle = 0;
3679 r.in.connect_handle = handle;
3680 r.in.resume_handle = &resume_handle;
3681 r.in.buf_size = (uint32_t)-1;
3682 r.out.resume_handle = &resume_handle;
3684 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3685 if (!NT_STATUS_IS_OK(status)) {
3686 printf("EnumDomains failed - %s\n", nt_errstr(status));
3694 for (i=0;i<r.out.sam->count;i++) {
3695 if (!test_LookupDomain(p, mem_ctx, handle,
3696 r.out.sam->entries[i].name.string, which_ops)) {
3701 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3702 if (!NT_STATUS_IS_OK(status)) {
3703 printf("EnumDomains failed - %s\n", nt_errstr(status));
3711 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3712 struct policy_handle *handle)
3715 struct samr_Connect r;
3716 struct samr_Connect2 r2;
3717 struct samr_Connect3 r3;
3718 struct samr_Connect4 r4;
3719 struct samr_Connect5 r5;
3720 union samr_ConnectInfo info;
3721 struct policy_handle h;
3722 BOOL ret = True, got_handle = False;
3724 printf("testing samr_Connect\n");
3726 r.in.system_name = 0;
3727 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3728 r.out.connect_handle = &h;
3730 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3731 if (!NT_STATUS_IS_OK(status)) {
3732 printf("Connect failed - %s\n", nt_errstr(status));
3739 printf("testing samr_Connect2\n");
3741 r2.in.system_name = NULL;
3742 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3743 r2.out.connect_handle = &h;
3745 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3746 if (!NT_STATUS_IS_OK(status)) {
3747 printf("Connect2 failed - %s\n", nt_errstr(status));
3751 test_samr_handle_Close(p, mem_ctx, handle);
3757 printf("testing samr_Connect3\n");
3759 r3.in.system_name = NULL;
3761 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3762 r3.out.connect_handle = &h;
3764 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3765 if (!NT_STATUS_IS_OK(status)) {
3766 printf("Connect3 failed - %s\n", nt_errstr(status));
3770 test_samr_handle_Close(p, mem_ctx, handle);
3776 printf("testing samr_Connect4\n");
3778 r4.in.system_name = "";
3780 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3781 r4.out.connect_handle = &h;
3783 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3784 if (!NT_STATUS_IS_OK(status)) {
3785 printf("Connect4 failed - %s\n", nt_errstr(status));
3789 test_samr_handle_Close(p, mem_ctx, handle);
3795 printf("testing samr_Connect5\n");
3797 info.info1.unknown1 = 0;
3798 info.info1.unknown2 = 0;
3800 r5.in.system_name = "";
3801 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3804 r5.out.info = &info;
3805 r5.out.connect_handle = &h;
3807 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3808 if (!NT_STATUS_IS_OK(status)) {
3809 printf("Connect5 failed - %s\n", nt_errstr(status));
3813 test_samr_handle_Close(p, mem_ctx, handle);
3823 BOOL torture_rpc_samr(struct torture_context *torture)
3826 struct dcerpc_pipe *p;
3828 struct policy_handle handle;
3830 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3831 if (!NT_STATUS_IS_OK(status)) {
3835 ret &= test_Connect(p, torture, &handle);
3837 ret &= test_QuerySecurity(p, torture, &handle);
3839 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
3841 ret &= test_SetDsrmPassword(p, torture, &handle);
3843 ret &= test_Shutdown(p, torture, &handle);
3845 ret &= test_samr_handle_Close(p, torture, &handle);
3851 BOOL torture_rpc_samr_users(struct torture_context *torture)
3854 struct dcerpc_pipe *p;
3856 struct policy_handle handle;
3858 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3859 if (!NT_STATUS_IS_OK(status)) {
3863 ret &= test_Connect(p, torture, &handle);
3865 ret &= test_QuerySecurity(p, torture, &handle);
3867 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
3869 ret &= test_SetDsrmPassword(p, torture, &handle);
3871 ret &= test_Shutdown(p, torture, &handle);
3873 ret &= test_samr_handle_Close(p, torture, &handle);
3879 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
3882 struct dcerpc_pipe *p;
3884 struct policy_handle handle;
3886 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3887 if (!NT_STATUS_IS_OK(status)) {
3891 ret &= test_Connect(p, torture, &handle);
3893 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
3895 ret &= test_samr_handle_Close(p, torture, &handle);