2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
63 struct policy_handle *handle)
69 r.out.handle = handle;
71 status = dcerpc_samr_Close(p, mem_ctx, &r);
72 if (!NT_STATUS_IS_OK(status)) {
73 printf("Close handle failed - %s\n", nt_errstr(status));
80 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
81 struct policy_handle *handle)
84 struct samr_Shutdown r;
86 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
87 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
91 r.in.connect_handle = handle;
93 printf("testing samr_Shutdown\n");
95 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
96 if (!NT_STATUS_IS_OK(status)) {
97 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
104 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
105 struct policy_handle *handle)
108 struct samr_SetDsrmPassword r;
109 struct lsa_String string;
110 struct samr_Password hash;
112 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
113 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 printf("testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
128 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
129 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
137 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
138 struct policy_handle *handle)
141 struct samr_QuerySecurity r;
142 struct samr_SetSecurity s;
144 r.in.handle = handle;
147 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
148 if (!NT_STATUS_IS_OK(status)) {
149 printf("QuerySecurity failed - %s\n", nt_errstr(status));
153 if (r.out.sdbuf == NULL) {
157 s.in.handle = handle;
159 s.in.sdbuf = r.out.sdbuf;
161 if (lp_parm_bool(-1, "torture", "samba4", False)) {
162 printf("skipping SetSecurity test against Samba4\n");
166 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
167 if (!NT_STATUS_IS_OK(status)) {
168 printf("SetSecurity failed - %s\n", nt_errstr(status));
172 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
173 if (!NT_STATUS_IS_OK(status)) {
174 printf("QuerySecurity failed - %s\n", nt_errstr(status));
182 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
183 struct policy_handle *handle, uint32_t base_acct_flags,
184 const char *base_account_name)
187 struct samr_SetUserInfo s;
188 struct samr_SetUserInfo2 s2;
189 struct samr_QueryUserInfo q;
190 struct samr_QueryUserInfo q0;
191 union samr_UserInfo u;
193 const char *test_account_name;
195 uint32_t user_extra_flags = 0;
196 if (base_acct_flags == ACB_NORMAL) {
197 /* When created, accounts are expired by default */
198 user_extra_flags = ACB_PW_EXPIRED;
201 s.in.user_handle = handle;
204 s2.in.user_handle = handle;
207 q.in.user_handle = handle;
211 #define TESTCALL(call, r) \
212 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
213 if (!NT_STATUS_IS_OK(status)) { \
214 printf(#call " level %u failed - %s (%s)\n", \
215 r.in.level, nt_errstr(status), __location__); \
220 #define STRING_EQUAL(s1, s2, field) \
221 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
222 printf("Failed to set %s to '%s' (%s)\n", \
223 #field, s2, __location__); \
228 #define INT_EQUAL(i1, i2, field) \
230 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
231 #field, i2, i1, __location__); \
236 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
237 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
239 TESTCALL(QueryUserInfo, q) \
241 s2.in.level = lvl1; \
244 ZERO_STRUCT(u.info21); \
245 u.info21.fields_present = fpval; \
247 init_lsa_String(&u.info ## lvl1.field1, value); \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 init_lsa_String(&u.info ## lvl1.field1, ""); \
251 TESTCALL(QueryUserInfo, q); \
253 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
255 TESTCALL(QueryUserInfo, q) \
257 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
261 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
263 TESTCALL(QueryUserInfo, q) \
265 s2.in.level = lvl1; \
268 uint8_t *bits = u.info21.logon_hours.bits; \
269 ZERO_STRUCT(u.info21); \
270 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
271 u.info21.logon_hours.units_per_week = 168; \
272 u.info21.logon_hours.bits = bits; \
274 u.info21.fields_present = fpval; \
276 u.info ## lvl1.field1 = value; \
277 TESTCALL(SetUserInfo, s) \
278 TESTCALL(SetUserInfo2, s2) \
279 u.info ## lvl1.field1 = 0; \
280 TESTCALL(QueryUserInfo, q); \
282 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
284 TESTCALL(QueryUserInfo, q) \
286 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
289 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
290 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
294 do { TESTCALL(QueryUserInfo, q0) } while (0);
296 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
297 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
298 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
301 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
302 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
303 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
304 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
305 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
306 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
307 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
308 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
309 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
310 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
311 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
312 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
313 test_account_name = base_account_name;
314 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
315 SAMR_FIELD_ACCOUNT_NAME);
317 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
318 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
319 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
323 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
324 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
325 SAMR_FIELD_FULL_NAME);
327 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
328 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
329 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
333 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
334 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
335 SAMR_FIELD_FULL_NAME);
337 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
338 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
339 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
340 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
341 SAMR_FIELD_LOGON_SCRIPT);
343 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
344 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
345 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
346 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
347 SAMR_FIELD_PROFILE_PATH);
349 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
350 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
351 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
352 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
353 SAMR_FIELD_HOME_DIRECTORY);
354 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
355 SAMR_FIELD_HOME_DIRECTORY);
357 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
358 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
359 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
360 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
361 SAMR_FIELD_HOME_DRIVE);
362 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
363 SAMR_FIELD_HOME_DRIVE);
365 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
366 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
367 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
368 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
369 SAMR_FIELD_DESCRIPTION);
371 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
372 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
373 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
374 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
375 SAMR_FIELD_WORKSTATIONS);
377 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
378 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
379 SAMR_FIELD_PARAMETERS);
381 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
382 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
383 SAMR_FIELD_COUNTRY_CODE);
385 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
386 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
387 SAMR_FIELD_CODE_PAGE);
389 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
390 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
391 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
392 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
393 SAMR_FIELD_LOGON_HOURS);
395 if (lp_parm_bool(-1, "torture", "samba4", False)) {
396 printf("skipping Set Account Flag tests against Samba4\n");
400 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
401 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
402 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
404 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
405 (base_acct_flags | ACB_DISABLED),
406 (base_acct_flags | ACB_DISABLED | user_extra_flags),
409 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
410 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
411 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
412 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
414 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
415 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
416 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
420 /* The 'autolock' flag doesn't stick - check this */
421 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
422 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
423 (base_acct_flags | ACB_DISABLED | user_extra_flags),
426 /* Removing the 'disabled' flag doesn't stick - check this */
427 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
429 (base_acct_flags | ACB_DISABLED | user_extra_flags),
432 /* The 'store plaintext' flag does stick */
433 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
434 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
435 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
437 /* The 'use DES' flag does stick */
438 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
440 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
442 /* The 'don't require kerberos pre-authentication flag does stick */
443 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
444 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
445 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
447 /* The 'no kerberos PAC required' flag sticks */
448 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
449 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
450 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
453 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
454 (base_acct_flags | ACB_DISABLED),
455 (base_acct_flags | ACB_DISABLED | user_extra_flags),
456 SAMR_FIELD_ACCT_FLAGS);
459 /* these fail with win2003 - it appears you can't set the primary gid?
460 the set succeeds, but the gid isn't changed. Very weird! */
461 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
462 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
463 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
464 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
471 generate a random password for password change tests
473 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
475 size_t len = MAX(8, min_len) + (random() % 6);
476 char *s = generate_random_str(mem_ctx, len);
477 printf("Generated password '%s'\n", s);
482 generate a random password for password change tests (fixed length)
484 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
486 char *s = generate_random_str(mem_ctx, len);
487 printf("Generated password '%s'\n", s);
491 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
492 struct policy_handle *handle, char **password)
495 struct samr_SetUserInfo s;
496 union samr_UserInfo u;
498 DATA_BLOB session_key;
500 struct samr_GetUserPwInfo pwp;
501 int policy_min_pw_len = 0;
502 pwp.in.user_handle = handle;
504 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
505 if (NT_STATUS_IS_OK(status)) {
506 policy_min_pw_len = pwp.out.info.min_password_length;
508 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
510 s.in.user_handle = handle;
514 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
515 /* w2k3 ignores this length */
516 u.info24.pw_len = strlen_m(newpass) * 2;
518 status = dcerpc_fetch_session_key(p, &session_key);
519 if (!NT_STATUS_IS_OK(status)) {
520 printf("SetUserInfo level %u - no session key - %s\n",
521 s.in.level, nt_errstr(status));
525 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
527 printf("Testing SetUserInfo level 24 (set password)\n");
529 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
530 if (!NT_STATUS_IS_OK(status)) {
531 printf("SetUserInfo level %u failed - %s\n",
532 s.in.level, nt_errstr(status));
542 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
543 struct policy_handle *handle, uint32_t fields_present,
547 struct samr_SetUserInfo s;
548 union samr_UserInfo u;
550 DATA_BLOB session_key;
552 struct samr_GetUserPwInfo pwp;
553 int policy_min_pw_len = 0;
554 pwp.in.user_handle = handle;
556 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
557 if (NT_STATUS_IS_OK(status)) {
558 policy_min_pw_len = pwp.out.info.min_password_length;
560 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
562 s.in.user_handle = handle;
568 u.info23.info.fields_present = fields_present;
570 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
572 status = dcerpc_fetch_session_key(p, &session_key);
573 if (!NT_STATUS_IS_OK(status)) {
574 printf("SetUserInfo level %u - no session key - %s\n",
575 s.in.level, nt_errstr(status));
579 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
581 printf("Testing SetUserInfo level 23 (set password)\n");
583 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
584 if (!NT_STATUS_IS_OK(status)) {
585 printf("SetUserInfo level %u failed - %s\n",
586 s.in.level, nt_errstr(status));
592 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
594 status = dcerpc_fetch_session_key(p, &session_key);
595 if (!NT_STATUS_IS_OK(status)) {
596 printf("SetUserInfo level %u - no session key - %s\n",
597 s.in.level, nt_errstr(status));
601 /* This should break the key nicely */
602 session_key.length--;
603 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
605 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
607 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
608 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
609 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
610 s.in.level, nt_errstr(status));
618 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
619 struct policy_handle *handle, bool makeshort,
623 struct samr_SetUserInfo s;
624 union samr_UserInfo u;
626 DATA_BLOB session_key;
627 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
628 uint8_t confounder[16];
630 struct MD5Context ctx;
631 struct samr_GetUserPwInfo pwp;
632 int policy_min_pw_len = 0;
633 pwp.in.user_handle = handle;
635 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
636 if (NT_STATUS_IS_OK(status)) {
637 policy_min_pw_len = pwp.out.info.min_password_length;
639 if (makeshort && policy_min_pw_len) {
640 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
642 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
645 s.in.user_handle = handle;
649 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
650 u.info26.pw_len = strlen(newpass);
652 status = dcerpc_fetch_session_key(p, &session_key);
653 if (!NT_STATUS_IS_OK(status)) {
654 printf("SetUserInfo level %u - no session key - %s\n",
655 s.in.level, nt_errstr(status));
659 generate_random_buffer((uint8_t *)confounder, 16);
662 MD5Update(&ctx, confounder, 16);
663 MD5Update(&ctx, session_key.data, session_key.length);
664 MD5Final(confounded_session_key.data, &ctx);
666 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
667 memcpy(&u.info26.password.data[516], confounder, 16);
669 printf("Testing SetUserInfo level 26 (set password ex)\n");
671 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
672 if (!NT_STATUS_IS_OK(status)) {
673 printf("SetUserInfo level %u failed - %s\n",
674 s.in.level, nt_errstr(status));
680 /* This should break the key nicely */
681 confounded_session_key.data[0]++;
683 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
684 memcpy(&u.info26.password.data[516], confounder, 16);
686 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
688 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
689 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
690 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
691 s.in.level, nt_errstr(status));
700 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
701 struct policy_handle *handle, uint32_t fields_present,
705 struct samr_SetUserInfo s;
706 union samr_UserInfo u;
708 DATA_BLOB session_key;
709 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
710 struct MD5Context ctx;
711 uint8_t confounder[16];
713 struct samr_GetUserPwInfo pwp;
714 int policy_min_pw_len = 0;
715 pwp.in.user_handle = handle;
717 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
718 if (NT_STATUS_IS_OK(status)) {
719 policy_min_pw_len = pwp.out.info.min_password_length;
721 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
723 s.in.user_handle = handle;
729 u.info25.info.fields_present = fields_present;
731 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
733 status = dcerpc_fetch_session_key(p, &session_key);
734 if (!NT_STATUS_IS_OK(status)) {
735 printf("SetUserInfo level %u - no session key - %s\n",
736 s.in.level, nt_errstr(status));
740 generate_random_buffer((uint8_t *)confounder, 16);
743 MD5Update(&ctx, confounder, 16);
744 MD5Update(&ctx, session_key.data, session_key.length);
745 MD5Final(confounded_session_key.data, &ctx);
747 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
748 memcpy(&u.info25.password.data[516], confounder, 16);
750 printf("Testing SetUserInfo level 25 (set password ex)\n");
752 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
753 if (!NT_STATUS_IS_OK(status)) {
754 printf("SetUserInfo level %u failed - %s\n",
755 s.in.level, nt_errstr(status));
761 /* This should break the key nicely */
762 confounded_session_key.data[0]++;
764 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
765 memcpy(&u.info25.password.data[516], confounder, 16);
767 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
769 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
770 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
771 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
772 s.in.level, nt_errstr(status));
779 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
780 struct policy_handle *handle)
783 struct samr_SetAliasInfo r;
784 struct samr_QueryAliasInfo q;
785 uint16_t levels[] = {2, 3};
789 /* Ignoring switch level 1, as that includes the number of members for the alias
790 * and setting this to a wrong value might have negative consequences
793 for (i=0;i<ARRAY_SIZE(levels);i++) {
794 printf("Testing SetAliasInfo level %u\n", levels[i]);
796 r.in.alias_handle = handle;
797 r.in.level = levels[i];
798 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
799 switch (r.in.level) {
800 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
801 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
802 "Test Description, should test I18N as well"); break;
805 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
806 if (!NT_STATUS_IS_OK(status)) {
807 printf("SetAliasInfo level %u failed - %s\n",
808 levels[i], nt_errstr(status));
812 q.in.alias_handle = handle;
813 q.in.level = levels[i];
815 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("QueryAliasInfo level %u failed - %s\n",
818 levels[i], nt_errstr(status));
826 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
827 struct policy_handle *user_handle)
829 struct samr_GetGroupsForUser r;
833 printf("testing GetGroupsForUser\n");
835 r.in.user_handle = user_handle;
837 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
838 if (!NT_STATUS_IS_OK(status)) {
839 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
847 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
848 struct lsa_String *domain_name)
851 struct samr_GetDomPwInfo r;
854 r.in.domain_name = domain_name;
855 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
857 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
858 if (!NT_STATUS_IS_OK(status)) {
859 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
863 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
864 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
866 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
867 if (!NT_STATUS_IS_OK(status)) {
868 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
872 r.in.domain_name->string = "\\\\__NONAME__";
873 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
875 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
876 if (!NT_STATUS_IS_OK(status)) {
877 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
881 r.in.domain_name->string = "\\\\Builtin";
882 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
884 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
885 if (!NT_STATUS_IS_OK(status)) {
886 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
894 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
895 struct policy_handle *handle)
898 struct samr_GetUserPwInfo r;
901 printf("Testing GetUserPwInfo\n");
903 r.in.user_handle = handle;
905 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
906 if (!NT_STATUS_IS_OK(status)) {
907 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
914 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
915 struct policy_handle *domain_handle, const char *name,
919 struct samr_LookupNames n;
920 struct lsa_String sname[2];
922 init_lsa_String(&sname[0], name);
924 n.in.domain_handle = domain_handle;
927 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
928 if (NT_STATUS_IS_OK(status)) {
929 *rid = n.out.rids.ids[0];
934 init_lsa_String(&sname[1], "xxNONAMExx");
936 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
937 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
938 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
939 if (NT_STATUS_IS_OK(status)) {
940 return NT_STATUS_UNSUCCESSFUL;
946 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
947 if (!NT_STATUS_IS_OK(status)) {
948 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
952 init_lsa_String(&sname[0], "xxNONAMExx");
954 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
955 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
956 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
957 if (NT_STATUS_IS_OK(status)) {
958 return NT_STATUS_UNSUCCESSFUL;
963 init_lsa_String(&sname[0], "xxNONAMExx");
964 init_lsa_String(&sname[1], "xxNONAME2xx");
966 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
967 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
968 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
969 if (NT_STATUS_IS_OK(status)) {
970 return NT_STATUS_UNSUCCESSFUL;
978 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
979 struct policy_handle *domain_handle,
980 const char *name, struct policy_handle *user_handle)
983 struct samr_OpenUser r;
986 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
987 if (!NT_STATUS_IS_OK(status)) {
991 r.in.domain_handle = domain_handle;
992 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
994 r.out.user_handle = user_handle;
995 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
996 if (!NT_STATUS_IS_OK(status)) {
997 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1004 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1005 struct policy_handle *handle)
1008 struct samr_ChangePasswordUser r;
1010 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1011 struct policy_handle user_handle;
1012 char *oldpass = "test";
1013 char *newpass = "test2";
1014 uint8_t old_nt_hash[16], new_nt_hash[16];
1015 uint8_t old_lm_hash[16], new_lm_hash[16];
1017 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1018 if (!NT_STATUS_IS_OK(status)) {
1022 printf("Testing ChangePasswordUser for user 'testuser'\n");
1024 printf("old password: %s\n", oldpass);
1025 printf("new password: %s\n", newpass);
1027 E_md4hash(oldpass, old_nt_hash);
1028 E_md4hash(newpass, new_nt_hash);
1029 E_deshash(oldpass, old_lm_hash);
1030 E_deshash(newpass, new_lm_hash);
1032 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1033 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1034 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1035 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1036 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1037 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1039 r.in.handle = &user_handle;
1040 r.in.lm_present = 1;
1041 r.in.old_lm_crypted = &hash1;
1042 r.in.new_lm_crypted = &hash2;
1043 r.in.nt_present = 1;
1044 r.in.old_nt_crypted = &hash3;
1045 r.in.new_nt_crypted = &hash4;
1046 r.in.cross1_present = 1;
1047 r.in.nt_cross = &hash5;
1048 r.in.cross2_present = 1;
1049 r.in.lm_cross = &hash6;
1051 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1052 if (!NT_STATUS_IS_OK(status)) {
1053 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1057 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1065 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1066 const char *acct_name,
1067 struct policy_handle *handle, char **password)
1070 struct samr_ChangePasswordUser r;
1072 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1073 struct policy_handle user_handle;
1075 uint8_t old_nt_hash[16], new_nt_hash[16];
1076 uint8_t old_lm_hash[16], new_lm_hash[16];
1077 BOOL changed = True;
1080 struct samr_GetUserPwInfo pwp;
1081 int policy_min_pw_len = 0;
1083 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1084 if (!NT_STATUS_IS_OK(status)) {
1087 pwp.in.user_handle = &user_handle;
1089 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1090 if (NT_STATUS_IS_OK(status)) {
1091 policy_min_pw_len = pwp.out.info.min_password_length;
1093 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1095 printf("Testing ChangePasswordUser\n");
1098 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1102 oldpass = *password;
1104 E_md4hash(oldpass, old_nt_hash);
1105 E_md4hash(newpass, new_nt_hash);
1106 E_deshash(oldpass, old_lm_hash);
1107 E_deshash(newpass, new_lm_hash);
1109 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1110 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1111 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1112 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1113 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1114 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1116 r.in.user_handle = &user_handle;
1117 r.in.lm_present = 1;
1118 /* Break the LM hash */
1120 r.in.old_lm_crypted = &hash1;
1121 r.in.new_lm_crypted = &hash2;
1122 r.in.nt_present = 1;
1123 r.in.old_nt_crypted = &hash3;
1124 r.in.new_nt_crypted = &hash4;
1125 r.in.cross1_present = 1;
1126 r.in.nt_cross = &hash5;
1127 r.in.cross2_present = 1;
1128 r.in.lm_cross = &hash6;
1130 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1131 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1132 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1136 /* Unbreak the LM hash */
1139 r.in.user_handle = &user_handle;
1140 r.in.lm_present = 1;
1141 r.in.old_lm_crypted = &hash1;
1142 r.in.new_lm_crypted = &hash2;
1143 /* Break the NT hash */
1145 r.in.nt_present = 1;
1146 r.in.old_nt_crypted = &hash3;
1147 r.in.new_nt_crypted = &hash4;
1148 r.in.cross1_present = 1;
1149 r.in.nt_cross = &hash5;
1150 r.in.cross2_present = 1;
1151 r.in.lm_cross = &hash6;
1153 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1154 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1155 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1159 /* Unbreak the NT hash */
1162 r.in.user_handle = &user_handle;
1163 r.in.lm_present = 1;
1164 r.in.old_lm_crypted = &hash1;
1165 r.in.new_lm_crypted = &hash2;
1166 r.in.nt_present = 1;
1167 r.in.old_nt_crypted = &hash3;
1168 r.in.new_nt_crypted = &hash4;
1169 r.in.cross1_present = 1;
1170 r.in.nt_cross = &hash5;
1171 r.in.cross2_present = 1;
1172 /* Break the LM cross */
1174 r.in.lm_cross = &hash6;
1176 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1177 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1178 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1182 /* Unbreak the LM cross */
1185 r.in.user_handle = &user_handle;
1186 r.in.lm_present = 1;
1187 r.in.old_lm_crypted = &hash1;
1188 r.in.new_lm_crypted = &hash2;
1189 r.in.nt_present = 1;
1190 r.in.old_nt_crypted = &hash3;
1191 r.in.new_nt_crypted = &hash4;
1192 r.in.cross1_present = 1;
1193 /* Break the NT cross */
1195 r.in.nt_cross = &hash5;
1196 r.in.cross2_present = 1;
1197 r.in.lm_cross = &hash6;
1199 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1200 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1201 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1205 /* Unbreak the NT cross */
1209 /* Reset the hashes to not broken values */
1210 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1211 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1212 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1213 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1214 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1215 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1217 r.in.user_handle = &user_handle;
1218 r.in.lm_present = 1;
1219 r.in.old_lm_crypted = &hash1;
1220 r.in.new_lm_crypted = &hash2;
1221 r.in.nt_present = 1;
1222 r.in.old_nt_crypted = &hash3;
1223 r.in.new_nt_crypted = &hash4;
1224 r.in.cross1_present = 1;
1225 r.in.nt_cross = &hash5;
1226 r.in.cross2_present = 0;
1227 r.in.lm_cross = NULL;
1229 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1230 if (NT_STATUS_IS_OK(status)) {
1232 *password = newpass;
1233 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1234 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1239 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1241 E_md4hash(oldpass, old_nt_hash);
1242 E_md4hash(newpass, new_nt_hash);
1243 E_deshash(oldpass, old_lm_hash);
1244 E_deshash(newpass, new_lm_hash);
1247 /* Reset the hashes to not broken values */
1248 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1249 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1250 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1251 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1252 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1253 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1255 r.in.user_handle = &user_handle;
1256 r.in.lm_present = 1;
1257 r.in.old_lm_crypted = &hash1;
1258 r.in.new_lm_crypted = &hash2;
1259 r.in.nt_present = 1;
1260 r.in.old_nt_crypted = &hash3;
1261 r.in.new_nt_crypted = &hash4;
1262 r.in.cross1_present = 0;
1263 r.in.nt_cross = NULL;
1264 r.in.cross2_present = 1;
1265 r.in.lm_cross = &hash6;
1267 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1268 if (NT_STATUS_IS_OK(status)) {
1270 *password = newpass;
1271 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1272 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1277 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1279 E_md4hash(oldpass, old_nt_hash);
1280 E_md4hash(newpass, new_nt_hash);
1281 E_deshash(oldpass, old_lm_hash);
1282 E_deshash(newpass, new_lm_hash);
1285 /* Reset the hashes to not broken values */
1286 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1287 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1288 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1289 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1290 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1291 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1293 r.in.user_handle = &user_handle;
1294 r.in.lm_present = 1;
1295 r.in.old_lm_crypted = &hash1;
1296 r.in.new_lm_crypted = &hash2;
1297 r.in.nt_present = 1;
1298 r.in.old_nt_crypted = &hash3;
1299 r.in.new_nt_crypted = &hash4;
1300 r.in.cross1_present = 1;
1301 r.in.nt_cross = &hash5;
1302 r.in.cross2_present = 1;
1303 r.in.lm_cross = &hash6;
1305 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1306 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1307 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1308 } else if (!NT_STATUS_IS_OK(status)) {
1309 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1313 *password = newpass;
1316 r.in.user_handle = &user_handle;
1317 r.in.lm_present = 1;
1318 r.in.old_lm_crypted = &hash1;
1319 r.in.new_lm_crypted = &hash2;
1320 r.in.nt_present = 1;
1321 r.in.old_nt_crypted = &hash3;
1322 r.in.new_nt_crypted = &hash4;
1323 r.in.cross1_present = 1;
1324 r.in.nt_cross = &hash5;
1325 r.in.cross2_present = 1;
1326 r.in.lm_cross = &hash6;
1329 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1330 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1331 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1332 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1333 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1339 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1347 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1348 const char *acct_name,
1349 struct policy_handle *handle, char **password)
1352 struct samr_OemChangePasswordUser2 r;
1354 struct samr_Password lm_verifier;
1355 struct samr_CryptPassword lm_pass;
1356 struct lsa_AsciiString server, account, account_bad;
1359 uint8_t old_lm_hash[16], new_lm_hash[16];
1361 struct samr_GetDomPwInfo dom_pw_info;
1362 int policy_min_pw_len = 0;
1364 struct lsa_String domain_name;
1366 domain_name.string = "";
1367 dom_pw_info.in.domain_name = &domain_name;
1369 printf("Testing OemChangePasswordUser2\n");
1372 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1376 oldpass = *password;
1378 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1379 if (NT_STATUS_IS_OK(status)) {
1380 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1383 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1385 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1386 account.string = acct_name;
1388 E_deshash(oldpass, old_lm_hash);
1389 E_deshash(newpass, new_lm_hash);
1391 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1392 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1393 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1395 r.in.server = &server;
1396 r.in.account = &account;
1397 r.in.password = &lm_pass;
1398 r.in.hash = &lm_verifier;
1400 /* Break the verification */
1401 lm_verifier.hash[0]++;
1403 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1405 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1406 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1407 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1412 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1413 /* Break the old password */
1415 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1416 /* unbreak it for the next operation */
1418 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1420 r.in.server = &server;
1421 r.in.account = &account;
1422 r.in.password = &lm_pass;
1423 r.in.hash = &lm_verifier;
1425 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1427 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1428 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1429 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1434 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1435 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1437 r.in.server = &server;
1438 r.in.account = &account;
1439 r.in.password = &lm_pass;
1442 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1444 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1445 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1446 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1451 /* This shouldn't be a valid name */
1452 account_bad.string = TEST_ACCOUNT_NAME "XX";
1453 r.in.account = &account_bad;
1455 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1457 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1458 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1463 /* This shouldn't be a valid name */
1464 account_bad.string = TEST_ACCOUNT_NAME "XX";
1465 r.in.account = &account_bad;
1466 r.in.password = &lm_pass;
1467 r.in.hash = &lm_verifier;
1469 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1471 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1472 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1477 /* This shouldn't be a valid name */
1478 account_bad.string = TEST_ACCOUNT_NAME "XX";
1479 r.in.account = &account_bad;
1480 r.in.password = NULL;
1481 r.in.hash = &lm_verifier;
1483 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1485 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1486 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1491 E_deshash(oldpass, old_lm_hash);
1492 E_deshash(newpass, new_lm_hash);
1494 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1495 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1496 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1498 r.in.server = &server;
1499 r.in.account = &account;
1500 r.in.password = &lm_pass;
1501 r.in.hash = &lm_verifier;
1503 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1504 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1505 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1506 } else if (!NT_STATUS_IS_OK(status)) {
1507 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1510 *password = newpass;
1517 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1518 const char *acct_name,
1520 char *newpass, bool allow_password_restriction)
1523 struct samr_ChangePasswordUser2 r;
1525 struct lsa_String server, account;
1526 struct samr_CryptPassword nt_pass, lm_pass;
1527 struct samr_Password nt_verifier, lm_verifier;
1529 uint8_t old_nt_hash[16], new_nt_hash[16];
1530 uint8_t old_lm_hash[16], new_lm_hash[16];
1532 struct samr_GetDomPwInfo dom_pw_info;
1534 struct lsa_String domain_name;
1536 domain_name.string = "";
1537 dom_pw_info.in.domain_name = &domain_name;
1539 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1542 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1545 oldpass = *password;
1548 int policy_min_pw_len = 0;
1549 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1550 if (NT_STATUS_IS_OK(status)) {
1551 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1554 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1557 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1558 init_lsa_String(&account, acct_name);
1560 E_md4hash(oldpass, old_nt_hash);
1561 E_md4hash(newpass, new_nt_hash);
1563 E_deshash(oldpass, old_lm_hash);
1564 E_deshash(newpass, new_lm_hash);
1566 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1567 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1568 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1570 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1571 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1572 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1574 r.in.server = &server;
1575 r.in.account = &account;
1576 r.in.nt_password = &nt_pass;
1577 r.in.nt_verifier = &nt_verifier;
1579 r.in.lm_password = &lm_pass;
1580 r.in.lm_verifier = &lm_verifier;
1582 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1583 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1584 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1585 } else if (!NT_STATUS_IS_OK(status)) {
1586 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1589 *password = newpass;
1596 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1597 const char *account_string,
1598 int policy_min_pw_len,
1600 const char *newpass,
1601 NTTIME last_password_change,
1602 BOOL handle_reject_reason)
1605 struct samr_ChangePasswordUser3 r;
1607 struct lsa_String server, account, account_bad;
1608 struct samr_CryptPassword nt_pass, lm_pass;
1609 struct samr_Password nt_verifier, lm_verifier;
1611 uint8_t old_nt_hash[16], new_nt_hash[16];
1612 uint8_t old_lm_hash[16], new_lm_hash[16];
1615 printf("Testing ChangePasswordUser3\n");
1617 if (newpass == NULL) {
1619 if (policy_min_pw_len == 0) {
1620 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1622 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1624 } while (check_password_quality(newpass) == False);
1626 printf("Using password '%s'\n", newpass);
1630 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1634 oldpass = *password;
1635 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1636 init_lsa_String(&account, account_string);
1638 E_md4hash(oldpass, old_nt_hash);
1639 E_md4hash(newpass, new_nt_hash);
1641 E_deshash(oldpass, old_lm_hash);
1642 E_deshash(newpass, new_lm_hash);
1644 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1645 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1646 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1648 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1649 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1650 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1652 /* Break the verification */
1653 nt_verifier.hash[0]++;
1655 r.in.server = &server;
1656 r.in.account = &account;
1657 r.in.nt_password = &nt_pass;
1658 r.in.nt_verifier = &nt_verifier;
1660 r.in.lm_password = &lm_pass;
1661 r.in.lm_verifier = &lm_verifier;
1662 r.in.password3 = NULL;
1664 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1665 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1666 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1667 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1672 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1673 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1674 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1676 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1677 /* Break the NT hash */
1679 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1680 /* Unbreak it again */
1682 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1684 r.in.server = &server;
1685 r.in.account = &account;
1686 r.in.nt_password = &nt_pass;
1687 r.in.nt_verifier = &nt_verifier;
1689 r.in.lm_password = &lm_pass;
1690 r.in.lm_verifier = &lm_verifier;
1691 r.in.password3 = NULL;
1693 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1694 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1695 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1696 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1701 /* This shouldn't be a valid name */
1702 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1704 r.in.account = &account_bad;
1705 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1706 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1707 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1712 E_md4hash(oldpass, old_nt_hash);
1713 E_md4hash(newpass, new_nt_hash);
1715 E_deshash(oldpass, old_lm_hash);
1716 E_deshash(newpass, new_lm_hash);
1718 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1719 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1720 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1722 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1723 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1724 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1726 r.in.server = &server;
1727 r.in.account = &account;
1728 r.in.nt_password = &nt_pass;
1729 r.in.nt_verifier = &nt_verifier;
1731 r.in.lm_password = &lm_pass;
1732 r.in.lm_verifier = &lm_verifier;
1733 r.in.password3 = NULL;
1735 unix_to_nt_time(&t, time(NULL));
1737 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1739 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1742 && handle_reject_reason
1743 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1744 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1746 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1747 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1748 SAMR_REJECT_OTHER, r.out.reject->reason);
1753 /* We tested the order of precendence which is as follows:
1762 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1763 (last_password_change + r.out.dominfo->min_password_age > t)) {
1765 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1766 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1767 SAMR_REJECT_OTHER, r.out.reject->reason);
1771 } else if ((r.out.dominfo->min_password_length > 0) &&
1772 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1774 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1775 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1776 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1780 } else if ((r.out.dominfo->password_history_length > 0) &&
1781 strequal(oldpass, newpass)) {
1783 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1784 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1785 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1788 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1790 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1791 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1792 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1798 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1799 /* retry with adjusted size */
1800 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1801 r.out.dominfo->min_password_length,
1802 password, NULL, 0, False);
1806 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1807 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1808 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1809 SAMR_REJECT_OTHER, r.out.reject->reason);
1812 /* Perhaps the server has a 'min password age' set? */
1814 } else if (!NT_STATUS_IS_OK(status)) {
1815 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1818 *password = talloc_strdup(mem_ctx, newpass);
1825 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1826 struct policy_handle *alias_handle)
1828 struct samr_GetMembersInAlias r;
1829 struct lsa_SidArray sids;
1833 printf("Testing GetMembersInAlias\n");
1835 r.in.alias_handle = alias_handle;
1838 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1839 if (!NT_STATUS_IS_OK(status)) {
1840 printf("GetMembersInAlias failed - %s\n",
1848 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1849 struct policy_handle *alias_handle,
1850 const struct dom_sid *domain_sid)
1852 struct samr_AddAliasMember r;
1853 struct samr_DeleteAliasMember d;
1856 struct dom_sid *sid;
1858 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1860 printf("testing AddAliasMember\n");
1861 r.in.alias_handle = alias_handle;
1864 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1865 if (!NT_STATUS_IS_OK(status)) {
1866 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1870 d.in.alias_handle = alias_handle;
1873 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1874 if (!NT_STATUS_IS_OK(status)) {
1875 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1882 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1883 struct policy_handle *alias_handle)
1885 struct samr_AddMultipleMembersToAlias a;
1886 struct samr_RemoveMultipleMembersFromAlias r;
1889 struct lsa_SidArray sids;
1891 printf("testing AddMultipleMembersToAlias\n");
1892 a.in.alias_handle = alias_handle;
1896 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1898 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1899 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1900 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1902 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1903 if (!NT_STATUS_IS_OK(status)) {
1904 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1909 printf("testing RemoveMultipleMembersFromAlias\n");
1910 r.in.alias_handle = alias_handle;
1913 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1914 if (!NT_STATUS_IS_OK(status)) {
1915 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1919 /* strange! removing twice doesn't give any error */
1920 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1921 if (!NT_STATUS_IS_OK(status)) {
1922 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1926 /* but removing an alias that isn't there does */
1927 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1929 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1930 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1931 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1938 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1939 struct policy_handle *user_handle)
1941 struct samr_TestPrivateFunctionsUser r;
1945 printf("Testing TestPrivateFunctionsUser\n");
1947 r.in.user_handle = user_handle;
1949 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1950 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1951 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1959 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1960 struct policy_handle *user_handle,
1961 struct policy_handle *domain_handle,
1962 uint32_t base_acct_flags,
1963 const char *base_acct_name, enum torture_samr_choice which_ops)
1965 TALLOC_CTX *user_ctx;
1966 char *password = NULL;
1970 const uint32_t password_fields[] = {
1971 SAMR_FIELD_PASSWORD,
1972 SAMR_FIELD_PASSWORD2,
1973 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1977 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1978 switch (which_ops) {
1979 case TORTURE_SAMR_USER_ATTRIBUTES:
1980 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1984 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1988 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1992 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
1997 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
2001 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
2005 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
2009 case TORTURE_SAMR_PASSWORDS:
2010 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2011 char simple_pass[9];
2012 char *v = generate_random_str(mem_ctx, 1);
2014 ZERO_STRUCT(simple_pass);
2015 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2017 printf("Testing machine account password policy rules\n");
2019 /* Workstation trust accounts don't seem to need to honour password quality policy */
2020 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2024 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, simple_pass, False)) {
2028 /* reset again, to allow another 'user' password change */
2029 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2033 /* Try a 'short' password */
2034 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, samr_rand_pass(mem_ctx, 4), False)) {
2040 for (i = 0; password_fields[i]; i++) {
2041 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
2045 /* check it was set right */
2046 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2051 for (i = 0; password_fields[i]; i++) {
2052 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
2056 /* check it was set right */
2057 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2062 if (!test_SetUserPassEx(p, user_ctx, user_handle, false, &password)) {
2066 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
2071 case TORTURE_SAMR_OTHER:
2072 /* We just need the account to exist */
2075 talloc_free(user_ctx);
2079 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2080 struct policy_handle *alias_handle,
2081 const struct dom_sid *domain_sid)
2085 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
2089 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
2093 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
2097 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
2101 if (lp_parm_bool(-1, "torture", "samba4", False)) {
2102 printf("skipping MultipleMembers Alias tests against Samba4\n");
2106 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
2114 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2115 struct policy_handle *user_handle)
2117 struct samr_DeleteUser d;
2120 printf("Testing DeleteUser\n");
2122 d.in.user_handle = user_handle;
2123 d.out.user_handle = user_handle;
2125 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2126 if (!NT_STATUS_IS_OK(status)) {
2127 printf("DeleteUser failed - %s\n", nt_errstr(status));
2134 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2135 struct policy_handle *handle, const char *name)
2138 struct samr_DeleteUser d;
2139 struct policy_handle user_handle;
2142 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2143 if (!NT_STATUS_IS_OK(status)) {
2147 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2148 if (!NT_STATUS_IS_OK(status)) {
2152 d.in.user_handle = &user_handle;
2153 d.out.user_handle = &user_handle;
2154 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2155 if (!NT_STATUS_IS_OK(status)) {
2162 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2167 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2168 struct policy_handle *handle, const char *name)
2171 struct samr_OpenGroup r;
2172 struct samr_DeleteDomainGroup d;
2173 struct policy_handle group_handle;
2176 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2177 if (!NT_STATUS_IS_OK(status)) {
2181 r.in.domain_handle = handle;
2182 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2184 r.out.group_handle = &group_handle;
2185 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2186 if (!NT_STATUS_IS_OK(status)) {
2190 d.in.group_handle = &group_handle;
2191 d.out.group_handle = &group_handle;
2192 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2193 if (!NT_STATUS_IS_OK(status)) {
2200 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2205 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2206 struct policy_handle *domain_handle, const char *name)
2209 struct samr_OpenAlias r;
2210 struct samr_DeleteDomAlias d;
2211 struct policy_handle alias_handle;
2214 printf("testing DeleteAlias_byname\n");
2216 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2217 if (!NT_STATUS_IS_OK(status)) {
2221 r.in.domain_handle = domain_handle;
2222 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2224 r.out.alias_handle = &alias_handle;
2225 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2226 if (!NT_STATUS_IS_OK(status)) {
2230 d.in.alias_handle = &alias_handle;
2231 d.out.alias_handle = &alias_handle;
2232 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2233 if (!NT_STATUS_IS_OK(status)) {
2240 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2244 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2245 struct policy_handle *alias_handle)
2247 struct samr_DeleteDomAlias d;
2250 printf("Testing DeleteAlias\n");
2252 d.in.alias_handle = alias_handle;
2253 d.out.alias_handle = alias_handle;
2255 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2256 if (!NT_STATUS_IS_OK(status)) {
2257 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2264 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2265 struct policy_handle *domain_handle,
2266 struct policy_handle *alias_handle,
2267 const struct dom_sid *domain_sid)
2270 struct samr_CreateDomAlias r;
2271 struct lsa_String name;
2275 init_lsa_String(&name, TEST_ALIASNAME);
2276 r.in.domain_handle = domain_handle;
2277 r.in.alias_name = &name;
2278 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2279 r.out.alias_handle = alias_handle;
2282 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2284 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2286 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2287 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2291 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2292 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2295 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2298 if (!NT_STATUS_IS_OK(status)) {
2299 printf("CreateAlias failed - %s\n", nt_errstr(status));
2303 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2310 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2311 const char *acct_name,
2312 struct policy_handle *domain_handle, char **password)
2320 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2324 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, True)) {
2328 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2332 /* test what happens when setting the old password again */
2333 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2338 char simple_pass[9];
2339 char *v = generate_random_str(mem_ctx, 1);
2341 ZERO_STRUCT(simple_pass);
2342 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2344 /* test what happens when picking a simple password */
2345 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2350 /* set samr_SetDomainInfo level 1 with min_length 5 */
2352 struct samr_QueryDomainInfo r;
2353 struct samr_SetDomainInfo s;
2354 uint16_t len_old, len;
2355 uint32_t pwd_prop_old;
2356 int64_t min_pwd_age_old;
2361 r.in.domain_handle = domain_handle;
2364 printf("testing samr_QueryDomainInfo level 1\n");
2365 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2366 if (!NT_STATUS_IS_OK(status)) {
2370 s.in.domain_handle = domain_handle;
2372 s.in.info = r.out.info;
2374 /* remember the old min length, so we can reset it */
2375 len_old = s.in.info->info1.min_password_length;
2376 s.in.info->info1.min_password_length = len;
2377 pwd_prop_old = s.in.info->info1.password_properties;
2378 /* turn off password complexity checks for this test */
2379 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2381 min_pwd_age_old = s.in.info->info1.min_password_age;
2382 s.in.info->info1.min_password_age = 0;
2384 printf("testing samr_SetDomainInfo level 1\n");
2385 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2386 if (!NT_STATUS_IS_OK(status)) {
2390 printf("calling test_ChangePasswordUser3 with too short password\n");
2392 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2396 s.in.info->info1.min_password_length = len_old;
2397 s.in.info->info1.password_properties = pwd_prop_old;
2398 s.in.info->info1.min_password_age = min_pwd_age_old;
2400 printf("testing samr_SetDomainInfo level 1\n");
2401 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2402 if (!NT_STATUS_IS_OK(status)) {
2410 struct samr_OpenUser r;
2411 struct samr_QueryUserInfo q;
2412 struct samr_LookupNames n;
2413 struct policy_handle user_handle;
2415 n.in.domain_handle = domain_handle;
2417 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2418 n.in.names[0].string = acct_name;
2420 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2421 if (!NT_STATUS_IS_OK(status)) {
2422 printf("LookupNames failed - %s\n", nt_errstr(status));
2426 r.in.domain_handle = domain_handle;
2427 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2428 r.in.rid = n.out.rids.ids[0];
2429 r.out.user_handle = &user_handle;
2431 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2432 if (!NT_STATUS_IS_OK(status)) {
2433 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2437 q.in.user_handle = &user_handle;
2440 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2441 if (!NT_STATUS_IS_OK(status)) {
2442 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2446 printf("calling test_ChangePasswordUser3 with too early password change\n");
2448 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2449 q.out.info->info5.last_password_change, True)) {
2454 /* we change passwords twice - this has the effect of verifying
2455 they were changed correctly for the final call */
2456 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2460 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2467 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2468 struct policy_handle *domain_handle,
2469 struct policy_handle *user_handle_out,
2470 enum torture_samr_choice which_ops)
2473 TALLOC_CTX *user_ctx;
2476 struct samr_CreateUser r;
2477 struct samr_QueryUserInfo q;
2478 struct samr_DeleteUser d;
2481 /* This call creates a 'normal' account - check that it really does */
2482 const uint32_t acct_flags = ACB_NORMAL;
2483 struct lsa_String name;
2486 struct policy_handle user_handle;
2487 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2488 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2490 r.in.domain_handle = domain_handle;
2491 r.in.account_name = &name;
2492 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2493 r.out.user_handle = &user_handle;
2496 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2498 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2500 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2501 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2502 talloc_free(user_ctx);
2506 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2507 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2508 talloc_free(user_ctx);
2511 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 talloc_free(user_ctx);
2515 printf("CreateUser failed - %s\n", nt_errstr(status));
2518 q.in.user_handle = &user_handle;
2521 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2522 if (!NT_STATUS_IS_OK(status)) {
2523 printf("QueryUserInfo level %u failed - %s\n",
2524 q.in.level, nt_errstr(status));
2527 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2528 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2529 q.out.info->info16.acct_flags,
2535 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2536 acct_flags, name.string, which_ops)) {
2540 if (user_handle_out) {
2541 *user_handle_out = user_handle;
2543 printf("Testing DeleteUser (createuser test)\n");
2545 d.in.user_handle = &user_handle;
2546 d.out.user_handle = &user_handle;
2548 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2549 if (!NT_STATUS_IS_OK(status)) {
2550 printf("DeleteUser failed - %s\n", nt_errstr(status));
2557 talloc_free(user_ctx);
2563 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2564 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2567 struct samr_CreateUser2 r;
2568 struct samr_QueryUserInfo q;
2569 struct samr_DeleteUser d;
2570 struct policy_handle user_handle;
2572 struct lsa_String name;
2577 uint32_t acct_flags;
2578 const char *account_name;
2580 } account_types[] = {
2581 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2582 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2583 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2584 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2585 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2586 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2587 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2588 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2589 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2590 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2591 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2592 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2593 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2594 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2595 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2598 for (i = 0; account_types[i].account_name; i++) {
2599 TALLOC_CTX *user_ctx;
2600 uint32_t acct_flags = account_types[i].acct_flags;
2601 uint32_t access_granted;
2602 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2603 init_lsa_String(&name, account_types[i].account_name);
2605 r.in.domain_handle = domain_handle;
2606 r.in.account_name = &name;
2607 r.in.acct_flags = acct_flags;
2608 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2609 r.out.user_handle = &user_handle;
2610 r.out.access_granted = &access_granted;
2613 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2615 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2617 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2618 talloc_free(user_ctx);
2619 printf("Server refused create of '%s'\n", r.in.account_name->string);
2622 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2623 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2624 talloc_free(user_ctx);
2628 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2631 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2632 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2633 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2637 if (NT_STATUS_IS_OK(status)) {
2638 q.in.user_handle = &user_handle;
2641 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2642 if (!NT_STATUS_IS_OK(status)) {
2643 printf("QueryUserInfo level %u failed - %s\n",
2644 q.in.level, nt_errstr(status));
2647 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2648 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2649 q.out.info->info5.acct_flags,
2653 switch (acct_flags) {
2655 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2656 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2657 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2662 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2663 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2664 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2669 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2670 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2671 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2678 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2679 acct_flags, name.string, which_ops)) {
2683 printf("Testing DeleteUser (createuser2 test)\n");
2685 d.in.user_handle = &user_handle;
2686 d.out.user_handle = &user_handle;
2688 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2689 if (!NT_STATUS_IS_OK(status)) {
2690 printf("DeleteUser failed - %s\n", nt_errstr(status));
2694 talloc_free(user_ctx);
2700 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2701 struct policy_handle *handle)
2704 struct samr_QueryAliasInfo r;
2705 uint16_t levels[] = {1, 2, 3};
2709 for (i=0;i<ARRAY_SIZE(levels);i++) {
2710 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2712 r.in.alias_handle = handle;
2713 r.in.level = levels[i];
2715 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2716 if (!NT_STATUS_IS_OK(status)) {
2717 printf("QueryAliasInfo level %u failed - %s\n",
2718 levels[i], nt_errstr(status));
2726 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2727 struct policy_handle *handle)
2730 struct samr_QueryGroupInfo r;
2731 uint16_t levels[] = {1, 2, 3, 4, 5};
2735 for (i=0;i<ARRAY_SIZE(levels);i++) {
2736 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2738 r.in.group_handle = handle;
2739 r.in.level = levels[i];
2741 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2742 if (!NT_STATUS_IS_OK(status)) {
2743 printf("QueryGroupInfo level %u failed - %s\n",
2744 levels[i], nt_errstr(status));
2752 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2753 struct policy_handle *handle)
2756 struct samr_QueryGroupMember r;
2759 printf("Testing QueryGroupMember\n");
2761 r.in.group_handle = handle;
2763 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2764 if (!NT_STATUS_IS_OK(status)) {
2765 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2773 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2774 struct policy_handle *handle)
2777 struct samr_QueryGroupInfo r;
2778 struct samr_SetGroupInfo s;
2779 uint16_t levels[] = {1, 2, 3, 4};
2780 uint16_t set_ok[] = {0, 1, 1, 1};
2784 for (i=0;i<ARRAY_SIZE(levels);i++) {
2785 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2787 r.in.group_handle = handle;
2788 r.in.level = levels[i];
2790 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2791 if (!NT_STATUS_IS_OK(status)) {
2792 printf("QueryGroupInfo level %u failed - %s\n",
2793 levels[i], nt_errstr(status));
2797 printf("Testing SetGroupInfo level %u\n", levels[i]);
2799 s.in.group_handle = handle;
2800 s.in.level = levels[i];
2801 s.in.info = r.out.info;
2804 /* disabled this, as it changes the name only from the point of view of samr,
2805 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2806 the name is still reserved, so creating the old name fails, but deleting by the old name
2808 if (s.in.level == 2) {
2809 init_lsa_String(&s.in.info->string, "NewName");
2813 if (s.in.level == 4) {
2814 init_lsa_String(&s.in.info->description, "test description");
2817 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2819 if (!NT_STATUS_IS_OK(status)) {
2820 printf("SetGroupInfo level %u failed - %s\n",
2821 r.in.level, nt_errstr(status));
2826 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2827 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2828 r.in.level, nt_errstr(status));
2838 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2839 struct policy_handle *handle)
2842 struct samr_QueryUserInfo r;
2843 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2844 11, 12, 13, 14, 16, 17, 20, 21};
2848 for (i=0;i<ARRAY_SIZE(levels);i++) {
2849 printf("Testing QueryUserInfo level %u\n", levels[i]);
2851 r.in.user_handle = handle;
2852 r.in.level = levels[i];
2854 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2855 if (!NT_STATUS_IS_OK(status)) {
2856 printf("QueryUserInfo level %u failed - %s\n",
2857 levels[i], nt_errstr(status));
2865 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2866 struct policy_handle *handle)
2869 struct samr_QueryUserInfo2 r;
2870 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2871 11, 12, 13, 14, 16, 17, 20, 21};
2875 for (i=0;i<ARRAY_SIZE(levels);i++) {
2876 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2878 r.in.user_handle = handle;
2879 r.in.level = levels[i];
2881 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2882 if (!NT_STATUS_IS_OK(status)) {
2883 printf("QueryUserInfo2 level %u failed - %s\n",
2884 levels[i], nt_errstr(status));
2892 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2893 struct policy_handle *handle, uint32_t rid)
2896 struct samr_OpenUser r;
2897 struct policy_handle user_handle;
2900 printf("Testing OpenUser(%u)\n", rid);
2902 r.in.domain_handle = handle;
2903 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2905 r.out.user_handle = &user_handle;
2907 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2908 if (!NT_STATUS_IS_OK(status)) {
2909 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2913 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2917 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2921 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2925 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2929 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2933 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2940 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2941 struct policy_handle *handle, uint32_t rid)
2944 struct samr_OpenGroup r;
2945 struct policy_handle group_handle;
2948 printf("Testing OpenGroup(%u)\n", rid);
2950 r.in.domain_handle = handle;
2951 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2953 r.out.group_handle = &group_handle;
2955 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2956 if (!NT_STATUS_IS_OK(status)) {
2957 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2961 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2965 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2969 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2973 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2980 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2981 struct policy_handle *handle, uint32_t rid)
2984 struct samr_OpenAlias r;
2985 struct policy_handle alias_handle;
2988 printf("Testing OpenAlias(%u)\n", rid);
2990 r.in.domain_handle = handle;
2991 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2993 r.out.alias_handle = &alias_handle;
2995 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2996 if (!NT_STATUS_IS_OK(status)) {
2997 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3001 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3005 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3009 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3013 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3020 static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3021 struct policy_handle *handle, uint32_t rid,
3022 uint32_t acct_flag_mask)
3025 struct samr_OpenUser r;
3026 struct samr_QueryUserInfo q;
3027 struct policy_handle user_handle;
3030 printf("Testing OpenUser(%u)\n", rid);
3032 r.in.domain_handle = handle;
3033 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3035 r.out.user_handle = &user_handle;
3037 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3038 if (!NT_STATUS_IS_OK(status)) {
3039 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3043 q.in.user_handle = &user_handle;
3046 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3047 if (!NT_STATUS_IS_OK(status)) {
3048 printf("QueryUserInfo level 16 failed - %s\n",
3052 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3053 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3054 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3059 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3066 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3067 struct policy_handle *handle)
3069 NTSTATUS status = STATUS_MORE_ENTRIES;
3070 struct samr_EnumDomainUsers r;
3071 uint32_t mask, resume_handle=0;
3074 struct samr_LookupNames n;
3075 struct samr_LookupRids lr ;
3076 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3077 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3078 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3081 printf("Testing EnumDomainUsers\n");
3083 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3084 r.in.domain_handle = handle;
3085 r.in.resume_handle = &resume_handle;
3086 r.in.acct_flags = mask = masks[mask_idx];
3087 r.in.max_size = (uint32_t)-1;
3088 r.out.resume_handle = &resume_handle;
3090 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3091 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3092 !NT_STATUS_IS_OK(status)) {
3093 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3098 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3102 if (r.out.sam->count == 0) {
3106 for (i=0;i<r.out.sam->count;i++) {
3108 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3111 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3117 printf("Testing LookupNames\n");
3118 n.in.domain_handle = handle;
3119 n.in.num_names = r.out.sam->count;
3120 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3121 for (i=0;i<r.out.sam->count;i++) {
3122 n.in.names[i].string = r.out.sam->entries[i].name.string;
3124 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3125 if (!NT_STATUS_IS_OK(status)) {
3126 printf("LookupNames failed - %s\n", nt_errstr(status));
3131 printf("Testing LookupRids\n");
3132 lr.in.domain_handle = handle;
3133 lr.in.num_rids = r.out.sam->count;
3134 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3135 for (i=0;i<r.out.sam->count;i++) {
3136 lr.in.rids[i] = r.out.sam->entries[i].idx;
3138 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3139 if (!NT_STATUS_IS_OK(status)) {
3140 printf("LookupRids failed - %s\n", nt_errstr(status));
3148 try blasting the server with a bunch of sync requests
3150 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3151 struct policy_handle *handle)
3154 struct samr_EnumDomainUsers r;
3155 uint32_t resume_handle=0;
3157 #define ASYNC_COUNT 100
3158 struct rpc_request *req[ASYNC_COUNT];
3160 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
3161 printf("samr async test disabled - enable dangerous tests to use\n");
3165 printf("Testing EnumDomainUsers_async\n");
3167 r.in.domain_handle = handle;
3168 r.in.resume_handle = &resume_handle;
3169 r.in.acct_flags = 0;
3170 r.in.max_size = (uint32_t)-1;
3171 r.out.resume_handle = &resume_handle;
3173 for (i=0;i<ASYNC_COUNT;i++) {
3174 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
3177 for (i=0;i<ASYNC_COUNT;i++) {
3178 status = dcerpc_ndr_request_recv(req[i]);
3179 if (!NT_STATUS_IS_OK(status)) {
3180 printf("EnumDomainUsers[%d] failed - %s\n",
3181 i, nt_errstr(status));
3186 printf("%d async requests OK\n", i);
3191 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3192 struct policy_handle *handle)
3195 struct samr_EnumDomainGroups r;
3196 uint32_t resume_handle=0;
3200 printf("Testing EnumDomainGroups\n");
3202 r.in.domain_handle = handle;
3203 r.in.resume_handle = &resume_handle;
3204 r.in.max_size = (uint32_t)-1;
3205 r.out.resume_handle = &resume_handle;
3207 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3208 if (!NT_STATUS_IS_OK(status)) {
3209 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3217 for (i=0;i<r.out.sam->count;i++) {
3218 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3226 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3227 struct policy_handle *handle)
3230 struct samr_EnumDomainAliases r;