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(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
390 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
391 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
392 SAMR_FIELD_ACCT_EXPIRY);
394 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
395 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
396 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
397 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
398 SAMR_FIELD_LOGON_HOURS);
400 if (lp_parm_bool(-1, "torture", "samba4", False)) {
401 printf("skipping Set Account Flag tests against Samba4\n");
405 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
406 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
407 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
409 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
410 (base_acct_flags | ACB_DISABLED),
411 (base_acct_flags | ACB_DISABLED | user_extra_flags),
414 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
415 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
416 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
417 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
419 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
420 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
421 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
425 /* The 'autolock' flag doesn't stick - check this */
426 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
427 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
428 (base_acct_flags | ACB_DISABLED | user_extra_flags),
431 /* Removing the 'disabled' flag doesn't stick - check this */
432 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
434 (base_acct_flags | ACB_DISABLED | user_extra_flags),
437 /* The 'store plaintext' flag does stick */
438 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
440 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
442 /* The 'use DES' flag does stick */
443 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
444 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
445 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
447 /* The 'don't require kerberos pre-authentication flag does stick */
448 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
449 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
450 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
452 /* The 'no kerberos PAC required' flag sticks */
453 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
454 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
455 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
458 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
459 (base_acct_flags | ACB_DISABLED),
460 (base_acct_flags | ACB_DISABLED | user_extra_flags),
461 SAMR_FIELD_ACCT_FLAGS);
464 /* these fail with win2003 - it appears you can't set the primary gid?
465 the set succeeds, but the gid isn't changed. Very weird! */
466 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
467 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
468 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
469 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
476 generate a random password for password change tests
478 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
480 size_t len = MAX(8, min_len) + (random() % 6);
481 char *s = generate_random_str(mem_ctx, len);
482 printf("Generated password '%s'\n", s);
487 generate a random password for password change tests (fixed length)
489 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
491 char *s = generate_random_str(mem_ctx, len);
492 printf("Generated password '%s'\n", s);
496 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
497 struct policy_handle *handle, char **password)
500 struct samr_SetUserInfo s;
501 union samr_UserInfo u;
503 DATA_BLOB session_key;
505 struct samr_GetUserPwInfo pwp;
506 int policy_min_pw_len = 0;
507 pwp.in.user_handle = handle;
509 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
510 if (NT_STATUS_IS_OK(status)) {
511 policy_min_pw_len = pwp.out.info.min_password_length;
513 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
515 s.in.user_handle = handle;
519 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
520 /* w2k3 ignores this length */
521 u.info24.pw_len = strlen_m(newpass) * 2;
523 status = dcerpc_fetch_session_key(p, &session_key);
524 if (!NT_STATUS_IS_OK(status)) {
525 printf("SetUserInfo level %u - no session key - %s\n",
526 s.in.level, nt_errstr(status));
530 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
532 printf("Testing SetUserInfo level 24 (set password)\n");
534 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
535 if (!NT_STATUS_IS_OK(status)) {
536 printf("SetUserInfo level %u failed - %s\n",
537 s.in.level, nt_errstr(status));
547 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
548 struct policy_handle *handle, uint32_t fields_present,
552 struct samr_SetUserInfo s;
553 union samr_UserInfo u;
555 DATA_BLOB session_key;
557 struct samr_GetUserPwInfo pwp;
558 int policy_min_pw_len = 0;
559 pwp.in.user_handle = handle;
561 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
562 if (NT_STATUS_IS_OK(status)) {
563 policy_min_pw_len = pwp.out.info.min_password_length;
565 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
567 s.in.user_handle = handle;
573 u.info23.info.fields_present = fields_present;
575 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
577 status = dcerpc_fetch_session_key(p, &session_key);
578 if (!NT_STATUS_IS_OK(status)) {
579 printf("SetUserInfo level %u - no session key - %s\n",
580 s.in.level, nt_errstr(status));
584 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
586 printf("Testing SetUserInfo level 23 (set password)\n");
588 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
589 if (!NT_STATUS_IS_OK(status)) {
590 printf("SetUserInfo level %u failed - %s\n",
591 s.in.level, nt_errstr(status));
597 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
599 status = dcerpc_fetch_session_key(p, &session_key);
600 if (!NT_STATUS_IS_OK(status)) {
601 printf("SetUserInfo level %u - no session key - %s\n",
602 s.in.level, nt_errstr(status));
606 /* This should break the key nicely */
607 session_key.length--;
608 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
610 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
612 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
613 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
614 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
615 s.in.level, nt_errstr(status));
623 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
624 struct policy_handle *handle, bool makeshort,
628 struct samr_SetUserInfo s;
629 union samr_UserInfo u;
631 DATA_BLOB session_key;
632 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
633 uint8_t confounder[16];
635 struct MD5Context ctx;
636 struct samr_GetUserPwInfo pwp;
637 int policy_min_pw_len = 0;
638 pwp.in.user_handle = handle;
640 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
641 if (NT_STATUS_IS_OK(status)) {
642 policy_min_pw_len = pwp.out.info.min_password_length;
644 if (makeshort && policy_min_pw_len) {
645 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
647 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
650 s.in.user_handle = handle;
654 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
655 u.info26.pw_len = strlen(newpass);
657 status = dcerpc_fetch_session_key(p, &session_key);
658 if (!NT_STATUS_IS_OK(status)) {
659 printf("SetUserInfo level %u - no session key - %s\n",
660 s.in.level, nt_errstr(status));
664 generate_random_buffer((uint8_t *)confounder, 16);
667 MD5Update(&ctx, confounder, 16);
668 MD5Update(&ctx, session_key.data, session_key.length);
669 MD5Final(confounded_session_key.data, &ctx);
671 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
672 memcpy(&u.info26.password.data[516], confounder, 16);
674 printf("Testing SetUserInfo level 26 (set password ex)\n");
676 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
677 if (!NT_STATUS_IS_OK(status)) {
678 printf("SetUserInfo level %u failed - %s\n",
679 s.in.level, nt_errstr(status));
685 /* This should break the key nicely */
686 confounded_session_key.data[0]++;
688 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
689 memcpy(&u.info26.password.data[516], confounder, 16);
691 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
693 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
694 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
695 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
696 s.in.level, nt_errstr(status));
705 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
706 struct policy_handle *handle, uint32_t fields_present,
710 struct samr_SetUserInfo s;
711 union samr_UserInfo u;
713 DATA_BLOB session_key;
714 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
715 struct MD5Context ctx;
716 uint8_t confounder[16];
718 struct samr_GetUserPwInfo pwp;
719 int policy_min_pw_len = 0;
720 pwp.in.user_handle = handle;
722 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
723 if (NT_STATUS_IS_OK(status)) {
724 policy_min_pw_len = pwp.out.info.min_password_length;
726 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
728 s.in.user_handle = handle;
734 u.info25.info.fields_present = fields_present;
736 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
738 status = dcerpc_fetch_session_key(p, &session_key);
739 if (!NT_STATUS_IS_OK(status)) {
740 printf("SetUserInfo level %u - no session key - %s\n",
741 s.in.level, nt_errstr(status));
745 generate_random_buffer((uint8_t *)confounder, 16);
748 MD5Update(&ctx, confounder, 16);
749 MD5Update(&ctx, session_key.data, session_key.length);
750 MD5Final(confounded_session_key.data, &ctx);
752 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
753 memcpy(&u.info25.password.data[516], confounder, 16);
755 printf("Testing SetUserInfo level 25 (set password ex)\n");
757 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
758 if (!NT_STATUS_IS_OK(status)) {
759 printf("SetUserInfo level %u failed - %s\n",
760 s.in.level, nt_errstr(status));
766 /* This should break the key nicely */
767 confounded_session_key.data[0]++;
769 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
770 memcpy(&u.info25.password.data[516], confounder, 16);
772 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
774 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
775 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
776 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
777 s.in.level, nt_errstr(status));
784 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
785 struct policy_handle *handle)
788 struct samr_SetAliasInfo r;
789 struct samr_QueryAliasInfo q;
790 uint16_t levels[] = {2, 3};
794 /* Ignoring switch level 1, as that includes the number of members for the alias
795 * and setting this to a wrong value might have negative consequences
798 for (i=0;i<ARRAY_SIZE(levels);i++) {
799 printf("Testing SetAliasInfo level %u\n", levels[i]);
801 r.in.alias_handle = handle;
802 r.in.level = levels[i];
803 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
804 switch (r.in.level) {
805 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
806 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
807 "Test Description, should test I18N as well"); break;
810 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
811 if (!NT_STATUS_IS_OK(status)) {
812 printf("SetAliasInfo level %u failed - %s\n",
813 levels[i], nt_errstr(status));
817 q.in.alias_handle = handle;
818 q.in.level = levels[i];
820 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
821 if (!NT_STATUS_IS_OK(status)) {
822 printf("QueryAliasInfo level %u failed - %s\n",
823 levels[i], nt_errstr(status));
831 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
832 struct policy_handle *user_handle)
834 struct samr_GetGroupsForUser r;
838 printf("testing GetGroupsForUser\n");
840 r.in.user_handle = user_handle;
842 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
843 if (!NT_STATUS_IS_OK(status)) {
844 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
852 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
853 struct lsa_String *domain_name)
856 struct samr_GetDomPwInfo r;
859 r.in.domain_name = domain_name;
860 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
862 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
863 if (!NT_STATUS_IS_OK(status)) {
864 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
868 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
869 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
871 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
872 if (!NT_STATUS_IS_OK(status)) {
873 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
877 r.in.domain_name->string = "\\\\__NONAME__";
878 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
880 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
881 if (!NT_STATUS_IS_OK(status)) {
882 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
886 r.in.domain_name->string = "\\\\Builtin";
887 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
889 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
890 if (!NT_STATUS_IS_OK(status)) {
891 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
899 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
900 struct policy_handle *handle)
903 struct samr_GetUserPwInfo r;
906 printf("Testing GetUserPwInfo\n");
908 r.in.user_handle = handle;
910 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
911 if (!NT_STATUS_IS_OK(status)) {
912 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
919 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
920 struct policy_handle *domain_handle, const char *name,
924 struct samr_LookupNames n;
925 struct lsa_String sname[2];
927 init_lsa_String(&sname[0], name);
929 n.in.domain_handle = domain_handle;
932 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
933 if (NT_STATUS_IS_OK(status)) {
934 *rid = n.out.rids.ids[0];
939 init_lsa_String(&sname[1], "xxNONAMExx");
941 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
942 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
943 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
944 if (NT_STATUS_IS_OK(status)) {
945 return NT_STATUS_UNSUCCESSFUL;
951 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
952 if (!NT_STATUS_IS_OK(status)) {
953 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
957 init_lsa_String(&sname[0], "xxNONAMExx");
959 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
960 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
961 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
962 if (NT_STATUS_IS_OK(status)) {
963 return NT_STATUS_UNSUCCESSFUL;
968 init_lsa_String(&sname[0], "xxNONAMExx");
969 init_lsa_String(&sname[1], "xxNONAME2xx");
971 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
972 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
973 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
974 if (NT_STATUS_IS_OK(status)) {
975 return NT_STATUS_UNSUCCESSFUL;
983 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
984 struct policy_handle *domain_handle,
985 const char *name, struct policy_handle *user_handle)
988 struct samr_OpenUser r;
991 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
992 if (!NT_STATUS_IS_OK(status)) {
996 r.in.domain_handle = domain_handle;
997 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
999 r.out.user_handle = user_handle;
1000 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1001 if (!NT_STATUS_IS_OK(status)) {
1002 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1009 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1010 struct policy_handle *handle)
1013 struct samr_ChangePasswordUser r;
1015 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1016 struct policy_handle user_handle;
1017 char *oldpass = "test";
1018 char *newpass = "test2";
1019 uint8_t old_nt_hash[16], new_nt_hash[16];
1020 uint8_t old_lm_hash[16], new_lm_hash[16];
1022 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1023 if (!NT_STATUS_IS_OK(status)) {
1027 printf("Testing ChangePasswordUser for user 'testuser'\n");
1029 printf("old password: %s\n", oldpass);
1030 printf("new password: %s\n", newpass);
1032 E_md4hash(oldpass, old_nt_hash);
1033 E_md4hash(newpass, new_nt_hash);
1034 E_deshash(oldpass, old_lm_hash);
1035 E_deshash(newpass, new_lm_hash);
1037 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1038 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1039 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1040 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1041 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1042 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1044 r.in.handle = &user_handle;
1045 r.in.lm_present = 1;
1046 r.in.old_lm_crypted = &hash1;
1047 r.in.new_lm_crypted = &hash2;
1048 r.in.nt_present = 1;
1049 r.in.old_nt_crypted = &hash3;
1050 r.in.new_nt_crypted = &hash4;
1051 r.in.cross1_present = 1;
1052 r.in.nt_cross = &hash5;
1053 r.in.cross2_present = 1;
1054 r.in.lm_cross = &hash6;
1056 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1062 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1070 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1071 const char *acct_name,
1072 struct policy_handle *handle, char **password)
1075 struct samr_ChangePasswordUser r;
1077 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1078 struct policy_handle user_handle;
1080 uint8_t old_nt_hash[16], new_nt_hash[16];
1081 uint8_t old_lm_hash[16], new_lm_hash[16];
1082 BOOL changed = True;
1085 struct samr_GetUserPwInfo pwp;
1086 int policy_min_pw_len = 0;
1088 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1089 if (!NT_STATUS_IS_OK(status)) {
1092 pwp.in.user_handle = &user_handle;
1094 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1095 if (NT_STATUS_IS_OK(status)) {
1096 policy_min_pw_len = pwp.out.info.min_password_length;
1098 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1100 printf("Testing ChangePasswordUser\n");
1103 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1107 oldpass = *password;
1109 E_md4hash(oldpass, old_nt_hash);
1110 E_md4hash(newpass, new_nt_hash);
1111 E_deshash(oldpass, old_lm_hash);
1112 E_deshash(newpass, new_lm_hash);
1114 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1115 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1116 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1117 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1118 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1119 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1121 r.in.user_handle = &user_handle;
1122 r.in.lm_present = 1;
1123 /* Break the LM hash */
1125 r.in.old_lm_crypted = &hash1;
1126 r.in.new_lm_crypted = &hash2;
1127 r.in.nt_present = 1;
1128 r.in.old_nt_crypted = &hash3;
1129 r.in.new_nt_crypted = &hash4;
1130 r.in.cross1_present = 1;
1131 r.in.nt_cross = &hash5;
1132 r.in.cross2_present = 1;
1133 r.in.lm_cross = &hash6;
1135 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1136 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1137 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1141 /* Unbreak the LM hash */
1144 r.in.user_handle = &user_handle;
1145 r.in.lm_present = 1;
1146 r.in.old_lm_crypted = &hash1;
1147 r.in.new_lm_crypted = &hash2;
1148 /* Break the NT hash */
1150 r.in.nt_present = 1;
1151 r.in.old_nt_crypted = &hash3;
1152 r.in.new_nt_crypted = &hash4;
1153 r.in.cross1_present = 1;
1154 r.in.nt_cross = &hash5;
1155 r.in.cross2_present = 1;
1156 r.in.lm_cross = &hash6;
1158 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1159 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1160 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1164 /* Unbreak the NT hash */
1167 r.in.user_handle = &user_handle;
1168 r.in.lm_present = 1;
1169 r.in.old_lm_crypted = &hash1;
1170 r.in.new_lm_crypted = &hash2;
1171 r.in.nt_present = 1;
1172 r.in.old_nt_crypted = &hash3;
1173 r.in.new_nt_crypted = &hash4;
1174 r.in.cross1_present = 1;
1175 r.in.nt_cross = &hash5;
1176 r.in.cross2_present = 1;
1177 /* Break the LM cross */
1179 r.in.lm_cross = &hash6;
1181 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1182 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1183 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1187 /* Unbreak the LM cross */
1190 r.in.user_handle = &user_handle;
1191 r.in.lm_present = 1;
1192 r.in.old_lm_crypted = &hash1;
1193 r.in.new_lm_crypted = &hash2;
1194 r.in.nt_present = 1;
1195 r.in.old_nt_crypted = &hash3;
1196 r.in.new_nt_crypted = &hash4;
1197 r.in.cross1_present = 1;
1198 /* Break the NT cross */
1200 r.in.nt_cross = &hash5;
1201 r.in.cross2_present = 1;
1202 r.in.lm_cross = &hash6;
1204 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1205 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1206 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1210 /* Unbreak the NT cross */
1214 /* Reset the hashes to not broken values */
1215 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1216 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1217 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1218 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1219 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1220 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1222 r.in.user_handle = &user_handle;
1223 r.in.lm_present = 1;
1224 r.in.old_lm_crypted = &hash1;
1225 r.in.new_lm_crypted = &hash2;
1226 r.in.nt_present = 1;
1227 r.in.old_nt_crypted = &hash3;
1228 r.in.new_nt_crypted = &hash4;
1229 r.in.cross1_present = 1;
1230 r.in.nt_cross = &hash5;
1231 r.in.cross2_present = 0;
1232 r.in.lm_cross = NULL;
1234 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1235 if (NT_STATUS_IS_OK(status)) {
1237 *password = newpass;
1238 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1239 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1244 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1246 E_md4hash(oldpass, old_nt_hash);
1247 E_md4hash(newpass, new_nt_hash);
1248 E_deshash(oldpass, old_lm_hash);
1249 E_deshash(newpass, new_lm_hash);
1252 /* Reset the hashes to not broken values */
1253 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1254 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1255 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1256 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1257 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1258 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1260 r.in.user_handle = &user_handle;
1261 r.in.lm_present = 1;
1262 r.in.old_lm_crypted = &hash1;
1263 r.in.new_lm_crypted = &hash2;
1264 r.in.nt_present = 1;
1265 r.in.old_nt_crypted = &hash3;
1266 r.in.new_nt_crypted = &hash4;
1267 r.in.cross1_present = 0;
1268 r.in.nt_cross = NULL;
1269 r.in.cross2_present = 1;
1270 r.in.lm_cross = &hash6;
1272 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1273 if (NT_STATUS_IS_OK(status)) {
1275 *password = newpass;
1276 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1277 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1282 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1284 E_md4hash(oldpass, old_nt_hash);
1285 E_md4hash(newpass, new_nt_hash);
1286 E_deshash(oldpass, old_lm_hash);
1287 E_deshash(newpass, new_lm_hash);
1290 /* Reset the hashes to not broken values */
1291 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1292 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1293 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1294 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1295 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1296 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1298 r.in.user_handle = &user_handle;
1299 r.in.lm_present = 1;
1300 r.in.old_lm_crypted = &hash1;
1301 r.in.new_lm_crypted = &hash2;
1302 r.in.nt_present = 1;
1303 r.in.old_nt_crypted = &hash3;
1304 r.in.new_nt_crypted = &hash4;
1305 r.in.cross1_present = 1;
1306 r.in.nt_cross = &hash5;
1307 r.in.cross2_present = 1;
1308 r.in.lm_cross = &hash6;
1310 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1311 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1312 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1313 } else if (!NT_STATUS_IS_OK(status)) {
1314 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1318 *password = newpass;
1321 r.in.user_handle = &user_handle;
1322 r.in.lm_present = 1;
1323 r.in.old_lm_crypted = &hash1;
1324 r.in.new_lm_crypted = &hash2;
1325 r.in.nt_present = 1;
1326 r.in.old_nt_crypted = &hash3;
1327 r.in.new_nt_crypted = &hash4;
1328 r.in.cross1_present = 1;
1329 r.in.nt_cross = &hash5;
1330 r.in.cross2_present = 1;
1331 r.in.lm_cross = &hash6;
1334 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1335 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1336 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1337 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1338 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1344 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1352 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1353 const char *acct_name,
1354 struct policy_handle *handle, char **password)
1357 struct samr_OemChangePasswordUser2 r;
1359 struct samr_Password lm_verifier;
1360 struct samr_CryptPassword lm_pass;
1361 struct lsa_AsciiString server, account, account_bad;
1364 uint8_t old_lm_hash[16], new_lm_hash[16];
1366 struct samr_GetDomPwInfo dom_pw_info;
1367 int policy_min_pw_len = 0;
1369 struct lsa_String domain_name;
1371 domain_name.string = "";
1372 dom_pw_info.in.domain_name = &domain_name;
1374 printf("Testing OemChangePasswordUser2\n");
1377 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1381 oldpass = *password;
1383 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1384 if (NT_STATUS_IS_OK(status)) {
1385 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1388 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1390 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1391 account.string = acct_name;
1393 E_deshash(oldpass, old_lm_hash);
1394 E_deshash(newpass, new_lm_hash);
1396 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1397 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1398 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1400 r.in.server = &server;
1401 r.in.account = &account;
1402 r.in.password = &lm_pass;
1403 r.in.hash = &lm_verifier;
1405 /* Break the verification */
1406 lm_verifier.hash[0]++;
1408 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1410 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1411 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1412 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1417 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1418 /* Break the old password */
1420 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1421 /* unbreak it for the next operation */
1423 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1425 r.in.server = &server;
1426 r.in.account = &account;
1427 r.in.password = &lm_pass;
1428 r.in.hash = &lm_verifier;
1430 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1432 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1433 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1434 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1439 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1440 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1442 r.in.server = &server;
1443 r.in.account = &account;
1444 r.in.password = &lm_pass;
1447 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1449 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1450 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1451 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1456 /* This shouldn't be a valid name */
1457 account_bad.string = TEST_ACCOUNT_NAME "XX";
1458 r.in.account = &account_bad;
1460 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1462 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1463 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1468 /* This shouldn't be a valid name */
1469 account_bad.string = TEST_ACCOUNT_NAME "XX";
1470 r.in.account = &account_bad;
1471 r.in.password = &lm_pass;
1472 r.in.hash = &lm_verifier;
1474 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1476 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1477 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1482 /* This shouldn't be a valid name */
1483 account_bad.string = TEST_ACCOUNT_NAME "XX";
1484 r.in.account = &account_bad;
1485 r.in.password = NULL;
1486 r.in.hash = &lm_verifier;
1488 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1490 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1491 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1496 E_deshash(oldpass, old_lm_hash);
1497 E_deshash(newpass, new_lm_hash);
1499 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1500 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1501 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1503 r.in.server = &server;
1504 r.in.account = &account;
1505 r.in.password = &lm_pass;
1506 r.in.hash = &lm_verifier;
1508 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1509 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1510 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1511 } else if (!NT_STATUS_IS_OK(status)) {
1512 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1515 *password = newpass;
1522 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1523 const char *acct_name,
1525 char *newpass, bool allow_password_restriction)
1528 struct samr_ChangePasswordUser2 r;
1530 struct lsa_String server, account;
1531 struct samr_CryptPassword nt_pass, lm_pass;
1532 struct samr_Password nt_verifier, lm_verifier;
1534 uint8_t old_nt_hash[16], new_nt_hash[16];
1535 uint8_t old_lm_hash[16], new_lm_hash[16];
1537 struct samr_GetDomPwInfo dom_pw_info;
1539 struct lsa_String domain_name;
1541 domain_name.string = "";
1542 dom_pw_info.in.domain_name = &domain_name;
1544 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1547 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1550 oldpass = *password;
1553 int policy_min_pw_len = 0;
1554 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1555 if (NT_STATUS_IS_OK(status)) {
1556 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1559 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1562 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1563 init_lsa_String(&account, acct_name);
1565 E_md4hash(oldpass, old_nt_hash);
1566 E_md4hash(newpass, new_nt_hash);
1568 E_deshash(oldpass, old_lm_hash);
1569 E_deshash(newpass, new_lm_hash);
1571 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1572 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1573 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1575 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1576 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1577 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1579 r.in.server = &server;
1580 r.in.account = &account;
1581 r.in.nt_password = &nt_pass;
1582 r.in.nt_verifier = &nt_verifier;
1584 r.in.lm_password = &lm_pass;
1585 r.in.lm_verifier = &lm_verifier;
1587 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1588 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1589 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1590 } else if (!NT_STATUS_IS_OK(status)) {
1591 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1594 *password = newpass;
1601 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1602 const char *account_string,
1603 int policy_min_pw_len,
1605 const char *newpass,
1606 NTTIME last_password_change,
1607 BOOL handle_reject_reason)
1610 struct samr_ChangePasswordUser3 r;
1612 struct lsa_String server, account, account_bad;
1613 struct samr_CryptPassword nt_pass, lm_pass;
1614 struct samr_Password nt_verifier, lm_verifier;
1616 uint8_t old_nt_hash[16], new_nt_hash[16];
1617 uint8_t old_lm_hash[16], new_lm_hash[16];
1620 printf("Testing ChangePasswordUser3\n");
1622 if (newpass == NULL) {
1624 if (policy_min_pw_len == 0) {
1625 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1627 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1629 } while (check_password_quality(newpass) == False);
1631 printf("Using password '%s'\n", newpass);
1635 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1639 oldpass = *password;
1640 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1641 init_lsa_String(&account, account_string);
1643 E_md4hash(oldpass, old_nt_hash);
1644 E_md4hash(newpass, new_nt_hash);
1646 E_deshash(oldpass, old_lm_hash);
1647 E_deshash(newpass, new_lm_hash);
1649 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1650 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1651 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1653 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1654 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1655 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1657 /* Break the verification */
1658 nt_verifier.hash[0]++;
1660 r.in.server = &server;
1661 r.in.account = &account;
1662 r.in.nt_password = &nt_pass;
1663 r.in.nt_verifier = &nt_verifier;
1665 r.in.lm_password = &lm_pass;
1666 r.in.lm_verifier = &lm_verifier;
1667 r.in.password3 = NULL;
1669 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1670 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1671 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1672 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1677 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1678 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1679 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1681 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1682 /* Break the NT hash */
1684 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1685 /* Unbreak it again */
1687 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1689 r.in.server = &server;
1690 r.in.account = &account;
1691 r.in.nt_password = &nt_pass;
1692 r.in.nt_verifier = &nt_verifier;
1694 r.in.lm_password = &lm_pass;
1695 r.in.lm_verifier = &lm_verifier;
1696 r.in.password3 = NULL;
1698 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1699 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1700 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1701 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1706 /* This shouldn't be a valid name */
1707 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1709 r.in.account = &account_bad;
1710 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1711 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1712 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1717 E_md4hash(oldpass, old_nt_hash);
1718 E_md4hash(newpass, new_nt_hash);
1720 E_deshash(oldpass, old_lm_hash);
1721 E_deshash(newpass, new_lm_hash);
1723 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1724 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1725 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1727 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1728 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1729 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1731 r.in.server = &server;
1732 r.in.account = &account;
1733 r.in.nt_password = &nt_pass;
1734 r.in.nt_verifier = &nt_verifier;
1736 r.in.lm_password = &lm_pass;
1737 r.in.lm_verifier = &lm_verifier;
1738 r.in.password3 = NULL;
1740 unix_to_nt_time(&t, time(NULL));
1742 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1744 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1747 && handle_reject_reason
1748 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1749 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1751 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1752 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1753 SAMR_REJECT_OTHER, r.out.reject->reason);
1758 /* We tested the order of precendence which is as follows:
1767 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1768 (last_password_change + r.out.dominfo->min_password_age > t)) {
1770 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1771 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1772 SAMR_REJECT_OTHER, r.out.reject->reason);
1776 } else if ((r.out.dominfo->min_password_length > 0) &&
1777 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1779 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1780 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1781 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1785 } else if ((r.out.dominfo->password_history_length > 0) &&
1786 strequal(oldpass, newpass)) {
1788 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1789 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1790 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1793 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1795 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1796 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1797 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1803 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1804 /* retry with adjusted size */
1805 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1806 r.out.dominfo->min_password_length,
1807 password, NULL, 0, False);
1811 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1812 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1813 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1814 SAMR_REJECT_OTHER, r.out.reject->reason);
1817 /* Perhaps the server has a 'min password age' set? */
1819 } else if (!NT_STATUS_IS_OK(status)) {
1820 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1823 *password = talloc_strdup(mem_ctx, newpass);
1830 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1831 struct policy_handle *alias_handle)
1833 struct samr_GetMembersInAlias r;
1834 struct lsa_SidArray sids;
1838 printf("Testing GetMembersInAlias\n");
1840 r.in.alias_handle = alias_handle;
1843 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1844 if (!NT_STATUS_IS_OK(status)) {
1845 printf("GetMembersInAlias failed - %s\n",
1853 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1854 struct policy_handle *alias_handle,
1855 const struct dom_sid *domain_sid)
1857 struct samr_AddAliasMember r;
1858 struct samr_DeleteAliasMember d;
1861 struct dom_sid *sid;
1863 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1865 printf("testing AddAliasMember\n");
1866 r.in.alias_handle = alias_handle;
1869 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1870 if (!NT_STATUS_IS_OK(status)) {
1871 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1875 d.in.alias_handle = alias_handle;
1878 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1887 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1888 struct policy_handle *alias_handle)
1890 struct samr_AddMultipleMembersToAlias a;
1891 struct samr_RemoveMultipleMembersFromAlias r;
1894 struct lsa_SidArray sids;
1896 printf("testing AddMultipleMembersToAlias\n");
1897 a.in.alias_handle = alias_handle;
1901 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1903 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1904 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1905 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1907 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1908 if (!NT_STATUS_IS_OK(status)) {
1909 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1914 printf("testing RemoveMultipleMembersFromAlias\n");
1915 r.in.alias_handle = alias_handle;
1918 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1919 if (!NT_STATUS_IS_OK(status)) {
1920 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1924 /* strange! removing twice doesn't give any error */
1925 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1926 if (!NT_STATUS_IS_OK(status)) {
1927 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1931 /* but removing an alias that isn't there does */
1932 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1934 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1935 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1936 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1943 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1944 struct policy_handle *user_handle)
1946 struct samr_TestPrivateFunctionsUser r;
1950 printf("Testing TestPrivateFunctionsUser\n");
1952 r.in.user_handle = user_handle;
1954 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1955 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1956 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1964 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1965 struct policy_handle *user_handle,
1966 struct policy_handle *domain_handle,
1967 uint32_t base_acct_flags,
1968 const char *base_acct_name, enum torture_samr_choice which_ops)
1970 TALLOC_CTX *user_ctx;
1971 char *password = NULL;
1975 const uint32_t password_fields[] = {
1976 SAMR_FIELD_PASSWORD,
1977 SAMR_FIELD_PASSWORD2,
1978 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1982 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1983 switch (which_ops) {
1984 case TORTURE_SAMR_USER_ATTRIBUTES:
1985 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1989 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1993 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1997 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
2002 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
2006 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
2010 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
2014 case TORTURE_SAMR_PASSWORDS:
2015 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2016 char simple_pass[9];
2017 char *v = generate_random_str(mem_ctx, 1);
2019 ZERO_STRUCT(simple_pass);
2020 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2022 printf("Testing machine account password policy rules\n");
2024 /* Workstation trust accounts don't seem to need to honour password quality policy */
2025 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2029 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, simple_pass, False)) {
2033 /* reset again, to allow another 'user' password change */
2034 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2038 /* Try a 'short' password */
2039 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, samr_rand_pass(mem_ctx, 4), False)) {
2045 for (i = 0; password_fields[i]; i++) {
2046 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
2050 /* check it was set right */
2051 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2056 for (i = 0; password_fields[i]; i++) {
2057 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
2061 /* check it was set right */
2062 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2067 if (!test_SetUserPassEx(p, user_ctx, user_handle, false, &password)) {
2071 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
2076 case TORTURE_SAMR_OTHER:
2077 /* We just need the account to exist */
2080 talloc_free(user_ctx);
2084 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2085 struct policy_handle *alias_handle,
2086 const struct dom_sid *domain_sid)
2090 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
2094 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
2098 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
2102 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
2106 if (lp_parm_bool(-1, "torture", "samba4", False)) {
2107 printf("skipping MultipleMembers Alias tests against Samba4\n");
2111 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
2119 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2120 struct policy_handle *user_handle)
2122 struct samr_DeleteUser d;
2125 printf("Testing DeleteUser\n");
2127 d.in.user_handle = user_handle;
2128 d.out.user_handle = user_handle;
2130 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2131 if (!NT_STATUS_IS_OK(status)) {
2132 printf("DeleteUser failed - %s\n", nt_errstr(status));
2139 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2140 struct policy_handle *handle, const char *name)
2143 struct samr_DeleteUser d;
2144 struct policy_handle user_handle;
2147 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2148 if (!NT_STATUS_IS_OK(status)) {
2152 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2153 if (!NT_STATUS_IS_OK(status)) {
2157 d.in.user_handle = &user_handle;
2158 d.out.user_handle = &user_handle;
2159 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2160 if (!NT_STATUS_IS_OK(status)) {
2167 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2172 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2173 struct policy_handle *handle, const char *name)
2176 struct samr_OpenGroup r;
2177 struct samr_DeleteDomainGroup d;
2178 struct policy_handle group_handle;
2181 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2182 if (!NT_STATUS_IS_OK(status)) {
2186 r.in.domain_handle = handle;
2187 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2189 r.out.group_handle = &group_handle;
2190 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2191 if (!NT_STATUS_IS_OK(status)) {
2195 d.in.group_handle = &group_handle;
2196 d.out.group_handle = &group_handle;
2197 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2198 if (!NT_STATUS_IS_OK(status)) {
2205 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2210 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2211 struct policy_handle *domain_handle, const char *name)
2214 struct samr_OpenAlias r;
2215 struct samr_DeleteDomAlias d;
2216 struct policy_handle alias_handle;
2219 printf("testing DeleteAlias_byname\n");
2221 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2222 if (!NT_STATUS_IS_OK(status)) {
2226 r.in.domain_handle = domain_handle;
2227 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2229 r.out.alias_handle = &alias_handle;
2230 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2231 if (!NT_STATUS_IS_OK(status)) {
2235 d.in.alias_handle = &alias_handle;
2236 d.out.alias_handle = &alias_handle;
2237 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2238 if (!NT_STATUS_IS_OK(status)) {
2245 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2249 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2250 struct policy_handle *alias_handle)
2252 struct samr_DeleteDomAlias d;
2255 printf("Testing DeleteAlias\n");
2257 d.in.alias_handle = alias_handle;
2258 d.out.alias_handle = alias_handle;
2260 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2261 if (!NT_STATUS_IS_OK(status)) {
2262 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2269 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2270 struct policy_handle *domain_handle,
2271 struct policy_handle *alias_handle,
2272 const struct dom_sid *domain_sid)
2275 struct samr_CreateDomAlias r;
2276 struct lsa_String name;
2280 init_lsa_String(&name, TEST_ALIASNAME);
2281 r.in.domain_handle = domain_handle;
2282 r.in.alias_name = &name;
2283 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2284 r.out.alias_handle = alias_handle;
2287 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2289 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2291 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2292 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2296 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2297 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2300 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2303 if (!NT_STATUS_IS_OK(status)) {
2304 printf("CreateAlias failed - %s\n", nt_errstr(status));
2308 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2315 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2316 const char *acct_name,
2317 struct policy_handle *domain_handle, char **password)
2325 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2329 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, True)) {
2333 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2337 /* test what happens when setting the old password again */
2338 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2343 char simple_pass[9];
2344 char *v = generate_random_str(mem_ctx, 1);
2346 ZERO_STRUCT(simple_pass);
2347 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2349 /* test what happens when picking a simple password */
2350 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2355 /* set samr_SetDomainInfo level 1 with min_length 5 */
2357 struct samr_QueryDomainInfo r;
2358 struct samr_SetDomainInfo s;
2359 uint16_t len_old, len;
2360 uint32_t pwd_prop_old;
2361 int64_t min_pwd_age_old;
2366 r.in.domain_handle = domain_handle;
2369 printf("testing samr_QueryDomainInfo level 1\n");
2370 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2371 if (!NT_STATUS_IS_OK(status)) {
2375 s.in.domain_handle = domain_handle;
2377 s.in.info = r.out.info;
2379 /* remember the old min length, so we can reset it */
2380 len_old = s.in.info->info1.min_password_length;
2381 s.in.info->info1.min_password_length = len;
2382 pwd_prop_old = s.in.info->info1.password_properties;
2383 /* turn off password complexity checks for this test */
2384 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2386 min_pwd_age_old = s.in.info->info1.min_password_age;
2387 s.in.info->info1.min_password_age = 0;
2389 printf("testing samr_SetDomainInfo level 1\n");
2390 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2391 if (!NT_STATUS_IS_OK(status)) {
2395 printf("calling test_ChangePasswordUser3 with too short password\n");
2397 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2401 s.in.info->info1.min_password_length = len_old;
2402 s.in.info->info1.password_properties = pwd_prop_old;
2403 s.in.info->info1.min_password_age = min_pwd_age_old;
2405 printf("testing samr_SetDomainInfo level 1\n");
2406 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2407 if (!NT_STATUS_IS_OK(status)) {
2415 struct samr_OpenUser r;
2416 struct samr_QueryUserInfo q;
2417 struct samr_LookupNames n;
2418 struct policy_handle user_handle;
2420 n.in.domain_handle = domain_handle;
2422 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2423 n.in.names[0].string = acct_name;
2425 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2426 if (!NT_STATUS_IS_OK(status)) {
2427 printf("LookupNames failed - %s\n", nt_errstr(status));
2431 r.in.domain_handle = domain_handle;
2432 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2433 r.in.rid = n.out.rids.ids[0];
2434 r.out.user_handle = &user_handle;
2436 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2437 if (!NT_STATUS_IS_OK(status)) {
2438 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2442 q.in.user_handle = &user_handle;
2445 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2446 if (!NT_STATUS_IS_OK(status)) {
2447 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2451 printf("calling test_ChangePasswordUser3 with too early password change\n");
2453 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2454 q.out.info->info5.last_password_change, True)) {
2459 /* we change passwords twice - this has the effect of verifying
2460 they were changed correctly for the final call */
2461 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2465 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2472 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2473 struct policy_handle *domain_handle,
2474 struct policy_handle *user_handle_out,
2475 enum torture_samr_choice which_ops)
2478 TALLOC_CTX *user_ctx;
2481 struct samr_CreateUser r;
2482 struct samr_QueryUserInfo q;
2483 struct samr_DeleteUser d;
2486 /* This call creates a 'normal' account - check that it really does */
2487 const uint32_t acct_flags = ACB_NORMAL;
2488 struct lsa_String name;
2491 struct policy_handle user_handle;
2492 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2493 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2495 r.in.domain_handle = domain_handle;
2496 r.in.account_name = &name;
2497 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2498 r.out.user_handle = &user_handle;
2501 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2503 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2505 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2506 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2507 talloc_free(user_ctx);
2511 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2512 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2513 talloc_free(user_ctx);
2516 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2518 if (!NT_STATUS_IS_OK(status)) {
2519 talloc_free(user_ctx);
2520 printf("CreateUser failed - %s\n", nt_errstr(status));
2523 q.in.user_handle = &user_handle;
2526 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2527 if (!NT_STATUS_IS_OK(status)) {
2528 printf("QueryUserInfo level %u failed - %s\n",
2529 q.in.level, nt_errstr(status));
2532 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2533 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2534 q.out.info->info16.acct_flags,
2540 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2541 acct_flags, name.string, which_ops)) {
2545 if (user_handle_out) {
2546 *user_handle_out = user_handle;
2548 printf("Testing DeleteUser (createuser test)\n");
2550 d.in.user_handle = &user_handle;
2551 d.out.user_handle = &user_handle;
2553 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2554 if (!NT_STATUS_IS_OK(status)) {
2555 printf("DeleteUser failed - %s\n", nt_errstr(status));
2562 talloc_free(user_ctx);
2568 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2569 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2572 struct samr_CreateUser2 r;
2573 struct samr_QueryUserInfo q;
2574 struct samr_DeleteUser d;
2575 struct policy_handle user_handle;
2577 struct lsa_String name;
2582 uint32_t acct_flags;
2583 const char *account_name;
2585 } account_types[] = {
2586 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2587 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2588 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2589 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2590 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2591 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2592 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2593 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2594 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2595 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2596 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2597 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2598 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2599 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2600 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2603 for (i = 0; account_types[i].account_name; i++) {
2604 TALLOC_CTX *user_ctx;
2605 uint32_t acct_flags = account_types[i].acct_flags;
2606 uint32_t access_granted;
2607 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2608 init_lsa_String(&name, account_types[i].account_name);
2610 r.in.domain_handle = domain_handle;
2611 r.in.account_name = &name;
2612 r.in.acct_flags = acct_flags;
2613 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2614 r.out.user_handle = &user_handle;
2615 r.out.access_granted = &access_granted;
2618 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2620 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2622 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2623 talloc_free(user_ctx);
2624 printf("Server refused create of '%s'\n", r.in.account_name->string);
2627 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2628 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2629 talloc_free(user_ctx);
2633 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2636 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2637 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2638 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2642 if (NT_STATUS_IS_OK(status)) {
2643 q.in.user_handle = &user_handle;
2646 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2647 if (!NT_STATUS_IS_OK(status)) {
2648 printf("QueryUserInfo level %u failed - %s\n",
2649 q.in.level, nt_errstr(status));
2652 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2653 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2654 q.out.info->info5.acct_flags,
2658 switch (acct_flags) {
2660 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2661 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2662 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2667 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2668 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2669 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2674 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2675 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2676 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2683 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2684 acct_flags, name.string, which_ops)) {
2688 printf("Testing DeleteUser (createuser2 test)\n");
2690 d.in.user_handle = &user_handle;
2691 d.out.user_handle = &user_handle;
2693 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2694 if (!NT_STATUS_IS_OK(status)) {
2695 printf("DeleteUser failed - %s\n", nt_errstr(status));
2699 talloc_free(user_ctx);
2705 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2706 struct policy_handle *handle)
2709 struct samr_QueryAliasInfo r;
2710 uint16_t levels[] = {1, 2, 3};
2714 for (i=0;i<ARRAY_SIZE(levels);i++) {
2715 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2717 r.in.alias_handle = handle;
2718 r.in.level = levels[i];
2720 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2721 if (!NT_STATUS_IS_OK(status)) {
2722 printf("QueryAliasInfo level %u failed - %s\n",
2723 levels[i], nt_errstr(status));
2731 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2732 struct policy_handle *handle)
2735 struct samr_QueryGroupInfo r;
2736 uint16_t levels[] = {1, 2, 3, 4, 5};
2740 for (i=0;i<ARRAY_SIZE(levels);i++) {
2741 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2743 r.in.group_handle = handle;
2744 r.in.level = levels[i];
2746 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2747 if (!NT_STATUS_IS_OK(status)) {
2748 printf("QueryGroupInfo level %u failed - %s\n",
2749 levels[i], nt_errstr(status));
2757 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2758 struct policy_handle *handle)
2761 struct samr_QueryGroupMember r;
2764 printf("Testing QueryGroupMember\n");
2766 r.in.group_handle = handle;
2768 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2769 if (!NT_STATUS_IS_OK(status)) {
2770 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2778 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2779 struct policy_handle *handle)
2782 struct samr_QueryGroupInfo r;
2783 struct samr_SetGroupInfo s;
2784 uint16_t levels[] = {1, 2, 3, 4};
2785 uint16_t set_ok[] = {0, 1, 1, 1};
2789 for (i=0;i<ARRAY_SIZE(levels);i++) {
2790 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2792 r.in.group_handle = handle;
2793 r.in.level = levels[i];
2795 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2796 if (!NT_STATUS_IS_OK(status)) {
2797 printf("QueryGroupInfo level %u failed - %s\n",
2798 levels[i], nt_errstr(status));
2802 printf("Testing SetGroupInfo level %u\n", levels[i]);
2804 s.in.group_handle = handle;
2805 s.in.level = levels[i];
2806 s.in.info = r.out.info;
2809 /* disabled this, as it changes the name only from the point of view of samr,
2810 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2811 the name is still reserved, so creating the old name fails, but deleting by the old name
2813 if (s.in.level == 2) {
2814 init_lsa_String(&s.in.info->string, "NewName");
2818 if (s.in.level == 4) {
2819 init_lsa_String(&s.in.info->description, "test description");
2822 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2824 if (!NT_STATUS_IS_OK(status)) {
2825 printf("SetGroupInfo level %u failed - %s\n",
2826 r.in.level, nt_errstr(status));
2831 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2832 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2833 r.in.level, nt_errstr(status));
2843 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2844 struct policy_handle *handle)
2847 struct samr_QueryUserInfo r;
2848 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2849 11, 12, 13, 14, 16, 17, 20, 21};
2853 for (i=0;i<ARRAY_SIZE(levels);i++) {
2854 printf("Testing QueryUserInfo level %u\n", levels[i]);
2856 r.in.user_handle = handle;
2857 r.in.level = levels[i];
2859 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2860 if (!NT_STATUS_IS_OK(status)) {
2861 printf("QueryUserInfo level %u failed - %s\n",
2862 levels[i], nt_errstr(status));
2870 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2871 struct policy_handle *handle)
2874 struct samr_QueryUserInfo2 r;
2875 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2876 11, 12, 13, 14, 16, 17, 20, 21};
2880 for (i=0;i<ARRAY_SIZE(levels);i++) {
2881 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2883 r.in.user_handle = handle;
2884 r.in.level = levels[i];
2886 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2887 if (!NT_STATUS_IS_OK(status)) {
2888 printf("QueryUserInfo2 level %u failed - %s\n",
2889 levels[i], nt_errstr(status));
2897 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2898 struct policy_handle *handle, uint32_t rid)
2901 struct samr_OpenUser r;
2902 struct policy_handle user_handle;
2905 printf("Testing OpenUser(%u)\n", rid);
2907 r.in.domain_handle = handle;
2908 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2910 r.out.user_handle = &user_handle;
2912 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2913 if (!NT_STATUS_IS_OK(status)) {
2914 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2918 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2922 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2926 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2930 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2934 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2938 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2945 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2946 struct policy_handle *handle, uint32_t rid)
2949 struct samr_OpenGroup r;
2950 struct policy_handle group_handle;
2953 printf("Testing OpenGroup(%u)\n", rid);
2955 r.in.domain_handle = handle;
2956 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2958 r.out.group_handle = &group_handle;
2960 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2961 if (!NT_STATUS_IS_OK(status)) {
2962 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2966 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2970 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2974 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2978 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2985 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2986 struct policy_handle *handle, uint32_t rid)
2989 struct samr_OpenAlias r;
2990 struct policy_handle alias_handle;
2993 printf("Testing OpenAlias(%u)\n", rid);
2995 r.in.domain_handle = handle;
2996 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2998 r.out.alias_handle = &alias_handle;
3000 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3001 if (!NT_STATUS_IS_OK(status)) {
3002 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3006 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3010 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3014 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3018 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3025 static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3026 struct policy_handle *handle, uint32_t rid,
3027 uint32_t acct_flag_mask)
3030 struct samr_OpenUser r;
3031 struct samr_QueryUserInfo q;
3032 struct policy_handle user_handle;
3035 printf("Testing OpenUser(%u)\n", rid);
3037 r.in.domain_handle = handle;
3038 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3040 r.out.user_handle = &user_handle;
3042 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3043 if (!NT_STATUS_IS_OK(status)) {
3044 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3048 q.in.user_handle = &user_handle;
3051 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 printf("QueryUserInfo level 16 failed - %s\n",
3057 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3058 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3059 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3064 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3071 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3072 struct policy_handle *handle)
3074 NTSTATUS status = STATUS_MORE_ENTRIES;
3075 struct samr_EnumDomainUsers r;
3076 uint32_t mask, resume_handle=0;
3079 struct samr_LookupNames n;
3080 struct samr_LookupRids lr ;
3081 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3082 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3083 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3086 printf("Testing EnumDomainUsers\n");
3088 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3089 r.in.domain_handle = handle;
3090 r.in.resume_handle = &resume_handle;
3091 r.in.acct_flags = mask = masks[mask_idx];
3092 r.in.max_size = (uint32_t)-1;
3093 r.out.resume_handle = &resume_handle;
3095 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3096 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3097 !NT_STATUS_IS_OK(status)) {
3098 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3103 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3107 if (r.out.sam->count == 0) {
3111 for (i=0;i<r.out.sam->count;i++) {
3113 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3116 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3122 printf("Testing LookupNames\n");
3123 n.in.domain_handle = handle;
3124 n.in.num_names = r.out.sam->count;
3125 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3126 for (i=0;i<r.out.sam->count;i++) {
3127 n.in.names[i].string = r.out.sam->entries[i].name.string;
3129 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3130 if (!NT_STATUS_IS_OK(status)) {
3131 printf("LookupNames failed - %s\n", nt_errstr(status));
3136 printf("Testing LookupRids\n");
3137 lr.in.domain_handle = handle;
3138 lr.in.num_rids = r.out.sam->count;
3139 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3140 for (i=0;i<r.out.sam->count;i++) {
3141 lr.in.rids[i] = r.out.sam->entries[i].idx;
3143 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3144 if (!NT_STATUS_IS_OK(status)) {
3145 printf("LookupRids failed - %s\n", nt_errstr(status));
3153 try blasting the server with a bunch of sync requests
3155 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3156 struct policy_handle *handle)
3159 struct samr_EnumDomainUsers r;
3160 uint32_t resume_handle=0;
3162 #define ASYNC_COUNT 100
3163 struct rpc_request *req[ASYNC_COUNT];
3165 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
3166 printf("samr async test disabled - enable dangerous tests to use\n");
3170 printf("Testing EnumDomainUsers_async\n");
3172 r.in.domain_handle = handle;
3173 r.in.resume_handle = &resume_handle;
3174 r.in.acct_flags = 0;
3175 r.in.max_size = (uint32_t)-1;
3176 r.out.resume_handle = &resume_handle;
3178 for (i=0;i<ASYNC_COUNT;i++) {
3179 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
3182 for (i=0;i<ASYNC_COUNT;i++) {
3183 status = dcerpc_ndr_request_recv(req[i]);
3184 if (!NT_STATUS_IS_OK(status)) {
3185 printf("EnumDomainUsers[%d] failed - %s\n",
3186 i, nt_errstr(status));
3191 printf("%d async requests OK\n", i);
3196 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3197 struct policy_handle *handle)
3200 struct samr_EnumDomainGroups r;
3201 uint32_t resume_handle=0;
3205 printf("Testing EnumDomainGroups\n");
3207 r.in.domain_handle = handle;
3208 r.in.resume_handle = &resume_handle;
3209 r.in.max_size = (uint32_t)-1;
3210 r.out.resume_handle = &resume_handle;
3212 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3222 for (i=0;i<r.out.sam->count;i++) {
3223 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {