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(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
328 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
329 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
330 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
331 SAMR_FIELD_LOGON_SCRIPT);
333 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
334 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
335 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
336 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
337 SAMR_FIELD_PROFILE_PATH);
339 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
340 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
341 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
342 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
343 SAMR_FIELD_HOME_DIRECTORY);
344 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
345 SAMR_FIELD_HOME_DIRECTORY);
347 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
348 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
349 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
350 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
351 SAMR_FIELD_HOME_DRIVE);
352 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
353 SAMR_FIELD_HOME_DRIVE);
355 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
356 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
357 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
358 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
359 SAMR_FIELD_DESCRIPTION);
361 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
362 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
363 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
364 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
365 SAMR_FIELD_WORKSTATIONS);
367 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
368 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
369 SAMR_FIELD_PARAMETERS);
371 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
372 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
373 SAMR_FIELD_COUNTRY_CODE);
375 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
376 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
377 SAMR_FIELD_CODE_PAGE);
379 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
380 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
381 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
382 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
383 SAMR_FIELD_LOGON_HOURS);
385 if (lp_parm_bool(-1, "torture", "samba4", False)) {
386 printf("skipping Set Account Flag tests against Samba4\n");
390 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
391 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
392 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
394 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
395 (base_acct_flags | ACB_DISABLED),
396 (base_acct_flags | ACB_DISABLED | user_extra_flags),
399 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
400 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
401 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
402 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
404 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
405 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
406 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
410 /* The 'autolock' flag doesn't stick - check this */
411 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
412 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
413 (base_acct_flags | ACB_DISABLED | user_extra_flags),
416 /* Removing the 'disabled' flag doesn't stick - check this */
417 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
419 (base_acct_flags | ACB_DISABLED | user_extra_flags),
422 /* The 'store plaintext' flag does stick */
423 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
424 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
425 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
427 /* The 'use DES' flag does stick */
428 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
429 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
430 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
432 /* The 'don't require kerberos pre-authentication flag does stick */
433 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
434 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
435 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
437 /* The 'no kerberos PAC required' flag sticks */
438 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
440 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
443 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
444 (base_acct_flags | ACB_DISABLED),
445 (base_acct_flags | ACB_DISABLED | user_extra_flags),
446 SAMR_FIELD_ACCT_FLAGS);
449 /* these fail with win2003 - it appears you can't set the primary gid?
450 the set succeeds, but the gid isn't changed. Very weird! */
451 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
452 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
453 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
454 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
461 generate a random password for password change tests
463 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
465 size_t len = MAX(8, min_len) + (random() % 6);
466 char *s = generate_random_str(mem_ctx, len);
467 printf("Generated password '%s'\n", s);
472 generate a random password for password change tests (fixed length)
474 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
476 char *s = generate_random_str(mem_ctx, len);
477 printf("Generated password '%s'\n", s);
481 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
482 struct policy_handle *handle, char **password)
485 struct samr_SetUserInfo s;
486 union samr_UserInfo u;
488 DATA_BLOB session_key;
490 struct samr_GetUserPwInfo pwp;
491 int policy_min_pw_len = 0;
492 pwp.in.user_handle = handle;
494 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
495 if (NT_STATUS_IS_OK(status)) {
496 policy_min_pw_len = pwp.out.info.min_password_length;
498 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
500 s.in.user_handle = handle;
504 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
505 /* w2k3 ignores this length */
506 u.info24.pw_len = strlen_m(newpass) * 2;
508 status = dcerpc_fetch_session_key(p, &session_key);
509 if (!NT_STATUS_IS_OK(status)) {
510 printf("SetUserInfo level %u - no session key - %s\n",
511 s.in.level, nt_errstr(status));
515 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
517 printf("Testing SetUserInfo level 24 (set password)\n");
519 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
520 if (!NT_STATUS_IS_OK(status)) {
521 printf("SetUserInfo level %u failed - %s\n",
522 s.in.level, nt_errstr(status));
532 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
533 struct policy_handle *handle, uint32_t fields_present,
537 struct samr_SetUserInfo s;
538 union samr_UserInfo u;
540 DATA_BLOB session_key;
542 struct samr_GetUserPwInfo pwp;
543 int policy_min_pw_len = 0;
544 pwp.in.user_handle = handle;
546 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
547 if (NT_STATUS_IS_OK(status)) {
548 policy_min_pw_len = pwp.out.info.min_password_length;
550 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
552 s.in.user_handle = handle;
558 u.info23.info.fields_present = fields_present;
560 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
562 status = dcerpc_fetch_session_key(p, &session_key);
563 if (!NT_STATUS_IS_OK(status)) {
564 printf("SetUserInfo level %u - no session key - %s\n",
565 s.in.level, nt_errstr(status));
569 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
571 printf("Testing SetUserInfo level 23 (set password)\n");
573 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
574 if (!NT_STATUS_IS_OK(status)) {
575 printf("SetUserInfo level %u failed - %s\n",
576 s.in.level, nt_errstr(status));
582 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
584 status = dcerpc_fetch_session_key(p, &session_key);
585 if (!NT_STATUS_IS_OK(status)) {
586 printf("SetUserInfo level %u - no session key - %s\n",
587 s.in.level, nt_errstr(status));
591 /* This should break the key nicely */
592 session_key.length--;
593 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
595 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
597 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
598 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
599 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
600 s.in.level, nt_errstr(status));
608 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
609 struct policy_handle *handle, char **password)
612 struct samr_SetUserInfo s;
613 union samr_UserInfo u;
615 DATA_BLOB session_key;
616 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
617 uint8_t confounder[16];
619 struct MD5Context ctx;
620 struct samr_GetUserPwInfo pwp;
621 int policy_min_pw_len = 0;
622 pwp.in.user_handle = handle;
624 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
625 if (NT_STATUS_IS_OK(status)) {
626 policy_min_pw_len = pwp.out.info.min_password_length;
628 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
630 s.in.user_handle = handle;
634 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
635 u.info26.pw_len = strlen(newpass);
637 status = dcerpc_fetch_session_key(p, &session_key);
638 if (!NT_STATUS_IS_OK(status)) {
639 printf("SetUserInfo level %u - no session key - %s\n",
640 s.in.level, nt_errstr(status));
644 generate_random_buffer((uint8_t *)confounder, 16);
647 MD5Update(&ctx, confounder, 16);
648 MD5Update(&ctx, session_key.data, session_key.length);
649 MD5Final(confounded_session_key.data, &ctx);
651 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
652 memcpy(&u.info26.password.data[516], confounder, 16);
654 printf("Testing SetUserInfo level 26 (set password ex)\n");
656 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
657 if (!NT_STATUS_IS_OK(status)) {
658 printf("SetUserInfo level %u failed - %s\n",
659 s.in.level, nt_errstr(status));
665 /* This should break the key nicely */
666 confounded_session_key.data[0]++;
668 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
669 memcpy(&u.info26.password.data[516], confounder, 16);
671 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
673 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
674 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
675 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
676 s.in.level, nt_errstr(status));
685 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
686 struct policy_handle *handle, uint32_t fields_present,
690 struct samr_SetUserInfo s;
691 union samr_UserInfo u;
693 DATA_BLOB session_key;
694 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
695 struct MD5Context ctx;
696 uint8_t confounder[16];
698 struct samr_GetUserPwInfo pwp;
699 int policy_min_pw_len = 0;
700 pwp.in.user_handle = handle;
702 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
703 if (NT_STATUS_IS_OK(status)) {
704 policy_min_pw_len = pwp.out.info.min_password_length;
706 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
708 s.in.user_handle = handle;
714 u.info25.info.fields_present = fields_present;
716 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
718 status = dcerpc_fetch_session_key(p, &session_key);
719 if (!NT_STATUS_IS_OK(status)) {
720 printf("SetUserInfo level %u - no session key - %s\n",
721 s.in.level, nt_errstr(status));
725 generate_random_buffer((uint8_t *)confounder, 16);
728 MD5Update(&ctx, confounder, 16);
729 MD5Update(&ctx, session_key.data, session_key.length);
730 MD5Final(confounded_session_key.data, &ctx);
732 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
733 memcpy(&u.info25.password.data[516], confounder, 16);
735 printf("Testing SetUserInfo level 25 (set password ex)\n");
737 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
738 if (!NT_STATUS_IS_OK(status)) {
739 printf("SetUserInfo level %u failed - %s\n",
740 s.in.level, nt_errstr(status));
746 /* This should break the key nicely */
747 confounded_session_key.data[0]++;
749 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
750 memcpy(&u.info25.password.data[516], confounder, 16);
752 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
754 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
755 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
756 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
757 s.in.level, nt_errstr(status));
764 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
765 struct policy_handle *handle)
768 struct samr_SetAliasInfo r;
769 struct samr_QueryAliasInfo q;
770 uint16_t levels[] = {2, 3};
774 /* Ignoring switch level 1, as that includes the number of members for the alias
775 * and setting this to a wrong value might have negative consequences
778 for (i=0;i<ARRAY_SIZE(levels);i++) {
779 printf("Testing SetAliasInfo level %u\n", levels[i]);
781 r.in.alias_handle = handle;
782 r.in.level = levels[i];
783 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
784 switch (r.in.level) {
785 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
786 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
787 "Test Description, should test I18N as well"); break;
790 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
791 if (!NT_STATUS_IS_OK(status)) {
792 printf("SetAliasInfo level %u failed - %s\n",
793 levels[i], nt_errstr(status));
797 q.in.alias_handle = handle;
798 q.in.level = levels[i];
800 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
801 if (!NT_STATUS_IS_OK(status)) {
802 printf("QueryAliasInfo level %u failed - %s\n",
803 levels[i], nt_errstr(status));
811 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
812 struct policy_handle *user_handle)
814 struct samr_GetGroupsForUser r;
818 printf("testing GetGroupsForUser\n");
820 r.in.user_handle = user_handle;
822 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
832 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
833 struct lsa_String *domain_name)
836 struct samr_GetDomPwInfo r;
839 r.in.domain_name = domain_name;
840 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
842 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
843 if (!NT_STATUS_IS_OK(status)) {
844 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
848 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
849 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
851 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
852 if (!NT_STATUS_IS_OK(status)) {
853 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
857 r.in.domain_name->string = "\\\\__NONAME__";
858 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
860 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
861 if (!NT_STATUS_IS_OK(status)) {
862 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
866 r.in.domain_name->string = "\\\\Builtin";
867 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
869 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
879 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
880 struct policy_handle *handle)
883 struct samr_GetUserPwInfo r;
886 printf("Testing GetUserPwInfo\n");
888 r.in.user_handle = handle;
890 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
891 if (!NT_STATUS_IS_OK(status)) {
892 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
899 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
900 struct policy_handle *domain_handle, const char *name,
904 struct samr_LookupNames n;
905 struct lsa_String sname[2];
907 init_lsa_String(&sname[0], name);
909 n.in.domain_handle = domain_handle;
912 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
913 if (NT_STATUS_IS_OK(status)) {
914 *rid = n.out.rids.ids[0];
919 init_lsa_String(&sname[1], "xxNONAMExx");
921 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
922 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
923 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
924 if (NT_STATUS_IS_OK(status)) {
925 return NT_STATUS_UNSUCCESSFUL;
931 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
932 if (!NT_STATUS_IS_OK(status)) {
933 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
937 init_lsa_String(&sname[0], "xxNONAMExx");
939 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
940 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
941 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
942 if (NT_STATUS_IS_OK(status)) {
943 return NT_STATUS_UNSUCCESSFUL;
948 init_lsa_String(&sname[0], "xxNONAMExx");
949 init_lsa_String(&sname[1], "xxNONAME2xx");
951 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
952 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
953 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
954 if (NT_STATUS_IS_OK(status)) {
955 return NT_STATUS_UNSUCCESSFUL;
963 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
964 struct policy_handle *domain_handle,
965 const char *name, struct policy_handle *user_handle)
968 struct samr_OpenUser r;
971 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
972 if (!NT_STATUS_IS_OK(status)) {
976 r.in.domain_handle = domain_handle;
977 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
979 r.out.user_handle = user_handle;
980 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
981 if (!NT_STATUS_IS_OK(status)) {
982 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
989 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
990 struct policy_handle *handle)
993 struct samr_ChangePasswordUser r;
995 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
996 struct policy_handle user_handle;
997 char *oldpass = "test";
998 char *newpass = "test2";
999 uint8_t old_nt_hash[16], new_nt_hash[16];
1000 uint8_t old_lm_hash[16], new_lm_hash[16];
1002 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1003 if (!NT_STATUS_IS_OK(status)) {
1007 printf("Testing ChangePasswordUser for user 'testuser'\n");
1009 printf("old password: %s\n", oldpass);
1010 printf("new password: %s\n", newpass);
1012 E_md4hash(oldpass, old_nt_hash);
1013 E_md4hash(newpass, new_nt_hash);
1014 E_deshash(oldpass, old_lm_hash);
1015 E_deshash(newpass, new_lm_hash);
1017 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1018 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1019 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1020 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1021 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1022 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1024 r.in.handle = &user_handle;
1025 r.in.lm_present = 1;
1026 r.in.old_lm_crypted = &hash1;
1027 r.in.new_lm_crypted = &hash2;
1028 r.in.nt_present = 1;
1029 r.in.old_nt_crypted = &hash3;
1030 r.in.new_nt_crypted = &hash4;
1031 r.in.cross1_present = 1;
1032 r.in.nt_cross = &hash5;
1033 r.in.cross2_present = 1;
1034 r.in.lm_cross = &hash6;
1036 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1042 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1050 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1051 const char *acct_name,
1052 struct policy_handle *handle, char **password)
1055 struct samr_ChangePasswordUser r;
1057 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1058 struct policy_handle user_handle;
1060 uint8_t old_nt_hash[16], new_nt_hash[16];
1061 uint8_t old_lm_hash[16], new_lm_hash[16];
1062 BOOL changed = True;
1065 struct samr_GetUserPwInfo pwp;
1066 int policy_min_pw_len = 0;
1068 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1069 if (!NT_STATUS_IS_OK(status)) {
1072 pwp.in.user_handle = &user_handle;
1074 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1075 if (NT_STATUS_IS_OK(status)) {
1076 policy_min_pw_len = pwp.out.info.min_password_length;
1078 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1080 printf("Testing ChangePasswordUser\n");
1083 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1087 oldpass = *password;
1089 E_md4hash(oldpass, old_nt_hash);
1090 E_md4hash(newpass, new_nt_hash);
1091 E_deshash(oldpass, old_lm_hash);
1092 E_deshash(newpass, new_lm_hash);
1094 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1095 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1096 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1097 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1098 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1099 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1101 r.in.user_handle = &user_handle;
1102 r.in.lm_present = 1;
1103 r.in.old_lm_crypted = &hash1;
1104 r.in.new_lm_crypted = &hash2;
1105 r.in.nt_present = 1;
1106 r.in.old_nt_crypted = &hash3;
1107 r.in.new_nt_crypted = &hash4;
1108 r.in.cross1_present = 1;
1109 r.in.nt_cross = &hash5;
1110 r.in.cross2_present = 0;
1111 r.in.lm_cross = NULL;
1113 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1114 if (!NT_STATUS_EQUAL(status, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED)) {
1115 printf("ChangePasswordUser failed: expected NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1120 r.in.user_handle = &user_handle;
1121 r.in.lm_present = 1;
1122 r.in.old_lm_crypted = &hash1;
1123 r.in.new_lm_crypted = &hash2;
1124 r.in.nt_present = 1;
1125 r.in.old_nt_crypted = &hash3;
1126 r.in.new_nt_crypted = &hash4;
1127 r.in.cross1_present = 0;
1128 r.in.nt_cross = NULL;
1129 r.in.cross2_present = 1;
1130 r.in.lm_cross = &hash6;
1132 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1133 if (!NT_STATUS_EQUAL(status, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED)) {
1134 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1138 r.in.user_handle = &user_handle;
1139 r.in.lm_present = 1;
1140 /* Break the LM hash */
1142 r.in.old_lm_crypted = &hash1;
1143 r.in.new_lm_crypted = &hash2;
1144 r.in.nt_present = 1;
1145 r.in.old_nt_crypted = &hash3;
1146 r.in.new_nt_crypted = &hash4;
1147 r.in.cross1_present = 1;
1148 r.in.nt_cross = &hash5;
1149 r.in.cross2_present = 1;
1150 r.in.lm_cross = &hash6;
1152 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1153 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1154 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1158 /* Unbreak the LM hash */
1161 r.in.user_handle = &user_handle;
1162 r.in.lm_present = 1;
1163 r.in.old_lm_crypted = &hash1;
1164 r.in.new_lm_crypted = &hash2;
1165 /* Break the NT hash */
1167 r.in.nt_present = 1;
1168 r.in.old_nt_crypted = &hash3;
1169 r.in.new_nt_crypted = &hash4;
1170 r.in.cross1_present = 1;
1171 r.in.nt_cross = &hash5;
1172 r.in.cross2_present = 1;
1173 r.in.lm_cross = &hash6;
1175 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1176 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1177 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1181 /* Unbreak the NT hash */
1184 r.in.user_handle = &user_handle;
1185 r.in.lm_present = 1;
1186 r.in.old_lm_crypted = &hash1;
1187 r.in.new_lm_crypted = &hash2;
1188 r.in.nt_present = 1;
1189 r.in.old_nt_crypted = &hash3;
1190 r.in.new_nt_crypted = &hash4;
1191 r.in.cross1_present = 1;
1192 r.in.nt_cross = &hash5;
1193 r.in.cross2_present = 1;
1194 /* Break the LM cross */
1196 r.in.lm_cross = &hash6;
1198 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1199 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1200 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1204 /* Unbreak the LM cross */
1207 r.in.user_handle = &user_handle;
1208 r.in.lm_present = 1;
1209 r.in.old_lm_crypted = &hash1;
1210 r.in.new_lm_crypted = &hash2;
1211 r.in.nt_present = 1;
1212 r.in.old_nt_crypted = &hash3;
1213 r.in.new_nt_crypted = &hash4;
1214 r.in.cross1_present = 1;
1215 /* Break the NT cross */
1217 r.in.nt_cross = &hash5;
1218 r.in.cross2_present = 1;
1219 r.in.lm_cross = &hash6;
1221 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1222 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1223 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1227 /* Unbreak the NT cross */
1230 /* Reset the hashes to not broken values */
1231 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1232 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1233 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1234 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1235 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1236 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1238 r.in.user_handle = &user_handle;
1239 r.in.lm_present = 1;
1240 r.in.old_lm_crypted = &hash1;
1241 r.in.new_lm_crypted = &hash2;
1242 r.in.nt_present = 1;
1243 r.in.old_nt_crypted = &hash3;
1244 r.in.new_nt_crypted = &hash4;
1245 r.in.cross1_present = 1;
1246 r.in.nt_cross = &hash5;
1247 r.in.cross2_present = 1;
1248 r.in.lm_cross = &hash6;
1250 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1251 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1252 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1253 } else if (!NT_STATUS_IS_OK(status)) {
1254 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1258 *password = newpass;
1261 r.in.user_handle = &user_handle;
1262 r.in.lm_present = 1;
1263 r.in.old_lm_crypted = &hash1;
1264 r.in.new_lm_crypted = &hash2;
1265 r.in.nt_present = 1;
1266 r.in.old_nt_crypted = &hash3;
1267 r.in.new_nt_crypted = &hash4;
1268 r.in.cross1_present = 1;
1269 r.in.nt_cross = &hash5;
1270 r.in.cross2_present = 1;
1271 r.in.lm_cross = &hash6;
1274 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1275 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1276 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1281 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1289 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1290 const char *acct_name,
1291 struct policy_handle *handle, char **password)
1294 struct samr_OemChangePasswordUser2 r;
1296 struct samr_Password lm_verifier;
1297 struct samr_CryptPassword lm_pass;
1298 struct lsa_AsciiString server, account, account_bad;
1301 uint8_t old_lm_hash[16], new_lm_hash[16];
1303 struct samr_GetDomPwInfo dom_pw_info;
1304 int policy_min_pw_len = 0;
1306 struct lsa_String domain_name;
1308 domain_name.string = "";
1309 dom_pw_info.in.domain_name = &domain_name;
1311 printf("Testing OemChangePasswordUser2\n");
1314 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1318 oldpass = *password;
1320 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1321 if (NT_STATUS_IS_OK(status)) {
1322 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1325 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1327 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1328 account.string = acct_name;
1330 E_deshash(oldpass, old_lm_hash);
1331 E_deshash(newpass, new_lm_hash);
1333 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1334 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1335 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1337 r.in.server = &server;
1338 r.in.account = &account;
1339 r.in.password = &lm_pass;
1340 r.in.hash = &lm_verifier;
1342 /* Break the verification */
1343 lm_verifier.hash[0]++;
1345 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1347 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1348 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1349 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1354 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1355 /* Break the old password */
1357 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1358 /* unbreak it for the next operation */
1360 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1362 r.in.server = &server;
1363 r.in.account = &account;
1364 r.in.password = &lm_pass;
1365 r.in.hash = &lm_verifier;
1367 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1369 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1370 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1371 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1376 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1377 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1379 r.in.server = &server;
1380 r.in.account = &account;
1381 r.in.password = &lm_pass;
1384 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1386 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1387 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1388 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1393 /* This shouldn't be a valid name */
1394 account_bad.string = TEST_ACCOUNT_NAME "XX";
1395 r.in.account = &account_bad;
1397 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1399 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1400 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1405 E_deshash(oldpass, old_lm_hash);
1406 E_deshash(newpass, new_lm_hash);
1408 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1409 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1410 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1412 r.in.server = &server;
1413 r.in.account = &account;
1414 r.in.password = &lm_pass;
1415 r.in.hash = &lm_verifier;
1417 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1418 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1419 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1420 } else if (!NT_STATUS_IS_OK(status)) {
1421 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1424 *password = newpass;
1431 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1432 const char *acct_name,
1433 struct policy_handle *handle, char **password)
1436 struct samr_ChangePasswordUser2 r;
1438 struct lsa_String server, account;
1439 struct samr_CryptPassword nt_pass, lm_pass;
1440 struct samr_Password nt_verifier, lm_verifier;
1443 uint8_t old_nt_hash[16], new_nt_hash[16];
1444 uint8_t old_lm_hash[16], new_lm_hash[16];
1446 struct samr_GetDomPwInfo dom_pw_info;
1447 int policy_min_pw_len = 0;
1449 struct lsa_String domain_name;
1452 domain_name.string = "";
1453 dom_pw_info.in.domain_name = &domain_name;
1455 printf("Testing ChangePasswordUser2\n");
1458 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1461 oldpass = *password;
1463 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1464 if (NT_STATUS_IS_OK(status)) {
1465 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1468 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1470 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1471 init_lsa_String(&account, acct_name);
1473 E_md4hash(oldpass, old_nt_hash);
1474 E_md4hash(newpass, new_nt_hash);
1476 E_deshash(oldpass, old_lm_hash);
1477 E_deshash(newpass, new_lm_hash);
1479 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1480 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1481 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1483 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1484 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1485 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1487 r.in.server = &server;
1488 r.in.account = &account;
1489 r.in.nt_password = &nt_pass;
1490 r.in.nt_verifier = &nt_verifier;
1492 r.in.lm_password = &lm_pass;
1493 r.in.lm_verifier = &lm_verifier;
1495 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1496 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1497 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1498 } else if (!NT_STATUS_IS_OK(status)) {
1499 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1502 *password = newpass;
1509 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1510 const char *account_string,
1511 int policy_min_pw_len,
1513 const char *newpass,
1514 NTTIME last_password_change,
1515 BOOL handle_reject_reason)
1518 struct samr_ChangePasswordUser3 r;
1520 struct lsa_String server, account, account_bad;
1521 struct samr_CryptPassword nt_pass, lm_pass;
1522 struct samr_Password nt_verifier, lm_verifier;
1524 uint8_t old_nt_hash[16], new_nt_hash[16];
1525 uint8_t old_lm_hash[16], new_lm_hash[16];
1528 printf("Testing ChangePasswordUser3\n");
1530 if (newpass == NULL) {
1532 if (policy_min_pw_len == 0) {
1533 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1535 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1537 } while (check_password_quality(newpass) == False);
1539 printf("Using password '%s'\n", newpass);
1543 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1547 oldpass = *password;
1548 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1549 init_lsa_String(&account, account_string);
1551 E_md4hash(oldpass, old_nt_hash);
1552 E_md4hash(newpass, new_nt_hash);
1554 E_deshash(oldpass, old_lm_hash);
1555 E_deshash(newpass, new_lm_hash);
1557 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1558 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1559 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1561 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1562 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1563 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1565 /* Break the verification */
1566 nt_verifier.hash[0]++;
1568 r.in.server = &server;
1569 r.in.account = &account;
1570 r.in.nt_password = &nt_pass;
1571 r.in.nt_verifier = &nt_verifier;
1573 r.in.lm_password = &lm_pass;
1574 r.in.lm_verifier = &lm_verifier;
1575 r.in.password3 = NULL;
1577 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1578 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1579 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1580 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1585 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1586 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1587 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1589 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1590 /* Break the NT hash */
1592 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1593 /* Unbreak it again */
1595 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1597 r.in.server = &server;
1598 r.in.account = &account;
1599 r.in.nt_password = &nt_pass;
1600 r.in.nt_verifier = &nt_verifier;
1602 r.in.lm_password = &lm_pass;
1603 r.in.lm_verifier = &lm_verifier;
1604 r.in.password3 = NULL;
1606 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1607 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1608 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1609 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1614 /* This shouldn't be a valid name */
1615 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1617 r.in.account = &account_bad;
1618 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1619 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1620 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1625 E_md4hash(oldpass, old_nt_hash);
1626 E_md4hash(newpass, new_nt_hash);
1628 E_deshash(oldpass, old_lm_hash);
1629 E_deshash(newpass, new_lm_hash);
1631 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1632 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1633 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1635 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1636 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1637 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1639 r.in.server = &server;
1640 r.in.account = &account;
1641 r.in.nt_password = &nt_pass;
1642 r.in.nt_verifier = &nt_verifier;
1644 r.in.lm_password = &lm_pass;
1645 r.in.lm_verifier = &lm_verifier;
1646 r.in.password3 = NULL;
1648 unix_to_nt_time(&t, time(NULL));
1650 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1652 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1653 r.out.dominfo && r.out.reject && handle_reject_reason) {
1655 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1657 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1658 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1659 SAMR_REJECT_OTHER, r.out.reject->reason);
1664 /* We tested the order of precendence which is as follows:
1673 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1674 (last_password_change + r.out.dominfo->min_password_age > t)) {
1676 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1677 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1678 SAMR_REJECT_OTHER, r.out.reject->reason);
1682 } else if ((r.out.dominfo->min_password_length > 0) &&
1683 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1685 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1686 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1687 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1691 } else if ((r.out.dominfo->password_history_length > 0) &&
1692 strequal(oldpass, newpass)) {
1694 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1695 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1696 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1699 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1701 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1702 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1703 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1709 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1710 /* retry with adjusted size */
1711 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1712 r.out.dominfo->min_password_length,
1713 password, NULL, 0, False);
1717 } else if (!NT_STATUS_IS_OK(status)) {
1718 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1721 *password = talloc_strdup(mem_ctx, newpass);
1728 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1729 struct policy_handle *alias_handle)
1731 struct samr_GetMembersInAlias r;
1732 struct lsa_SidArray sids;
1736 printf("Testing GetMembersInAlias\n");
1738 r.in.alias_handle = alias_handle;
1741 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1742 if (!NT_STATUS_IS_OK(status)) {
1743 printf("GetMembersInAlias failed - %s\n",
1751 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1752 struct policy_handle *alias_handle,
1753 const struct dom_sid *domain_sid)
1755 struct samr_AddAliasMember r;
1756 struct samr_DeleteAliasMember d;
1759 struct dom_sid *sid;
1761 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1763 printf("testing AddAliasMember\n");
1764 r.in.alias_handle = alias_handle;
1767 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1768 if (!NT_STATUS_IS_OK(status)) {
1769 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1773 d.in.alias_handle = alias_handle;
1776 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1777 if (!NT_STATUS_IS_OK(status)) {
1778 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1785 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1786 struct policy_handle *alias_handle)
1788 struct samr_AddMultipleMembersToAlias a;
1789 struct samr_RemoveMultipleMembersFromAlias r;
1792 struct lsa_SidArray sids;
1794 printf("testing AddMultipleMembersToAlias\n");
1795 a.in.alias_handle = alias_handle;
1799 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1801 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1802 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1803 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1805 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1806 if (!NT_STATUS_IS_OK(status)) {
1807 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1812 printf("testing RemoveMultipleMembersFromAlias\n");
1813 r.in.alias_handle = alias_handle;
1816 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1817 if (!NT_STATUS_IS_OK(status)) {
1818 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1822 /* strange! removing twice doesn't give any error */
1823 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1824 if (!NT_STATUS_IS_OK(status)) {
1825 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1829 /* but removing an alias that isn't there does */
1830 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1832 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1833 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1834 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1841 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1842 struct policy_handle *user_handle)
1844 struct samr_TestPrivateFunctionsUser r;
1848 printf("Testing TestPrivateFunctionsUser\n");
1850 r.in.user_handle = user_handle;
1852 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1853 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1854 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1862 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1863 struct policy_handle *user_handle,
1864 struct policy_handle *domain_handle,
1865 uint32_t base_acct_flags,
1866 const char *base_acct_name, enum torture_samr_choice which_ops)
1868 TALLOC_CTX *user_ctx;
1869 char *password = NULL;
1873 const uint32_t password_fields[] = {
1874 SAMR_FIELD_PASSWORD,
1875 SAMR_FIELD_PASSWORD2,
1876 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1880 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1881 switch (which_ops) {
1882 case TORTURE_SAMR_USER_ATTRIBUTES:
1883 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1887 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1891 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1895 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
1900 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
1904 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
1908 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1912 case TORTURE_SAMR_PASSWORDS:
1913 for (i = 0; password_fields[i]; i++) {
1914 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1918 /* check it was set right */
1919 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
1924 for (i = 0; password_fields[i]; i++) {
1925 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1929 /* check it was set right */
1930 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
1935 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1939 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
1943 case TORTURE_SAMR_OTHER:
1944 /* We just need the account to exist */
1947 talloc_free(user_ctx);
1951 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1952 struct policy_handle *alias_handle,
1953 const struct dom_sid *domain_sid)
1957 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1961 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1965 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1969 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1973 if (lp_parm_bool(-1, "torture", "samba4", False)) {
1974 printf("skipping MultipleMembers Alias tests against Samba4\n");
1978 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1986 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1987 struct policy_handle *user_handle)
1989 struct samr_DeleteUser d;
1992 printf("Testing DeleteUser\n");
1994 d.in.user_handle = user_handle;
1995 d.out.user_handle = user_handle;
1997 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1998 if (!NT_STATUS_IS_OK(status)) {
1999 printf("DeleteUser failed - %s\n", nt_errstr(status));
2006 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2007 struct policy_handle *handle, const char *name)
2010 struct samr_DeleteUser d;
2011 struct policy_handle user_handle;
2014 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2015 if (!NT_STATUS_IS_OK(status)) {
2019 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2020 if (!NT_STATUS_IS_OK(status)) {
2024 d.in.user_handle = &user_handle;
2025 d.out.user_handle = &user_handle;
2026 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2027 if (!NT_STATUS_IS_OK(status)) {
2034 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2039 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2040 struct policy_handle *handle, const char *name)
2043 struct samr_OpenGroup r;
2044 struct samr_DeleteDomainGroup d;
2045 struct policy_handle group_handle;
2048 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2049 if (!NT_STATUS_IS_OK(status)) {
2053 r.in.domain_handle = handle;
2054 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2056 r.out.group_handle = &group_handle;
2057 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2058 if (!NT_STATUS_IS_OK(status)) {
2062 d.in.group_handle = &group_handle;
2063 d.out.group_handle = &group_handle;
2064 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2065 if (!NT_STATUS_IS_OK(status)) {
2072 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2077 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2078 struct policy_handle *domain_handle, const char *name)
2081 struct samr_OpenAlias r;
2082 struct samr_DeleteDomAlias d;
2083 struct policy_handle alias_handle;
2086 printf("testing DeleteAlias_byname\n");
2088 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2089 if (!NT_STATUS_IS_OK(status)) {
2093 r.in.domain_handle = domain_handle;
2094 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2096 r.out.alias_handle = &alias_handle;
2097 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2098 if (!NT_STATUS_IS_OK(status)) {
2102 d.in.alias_handle = &alias_handle;
2103 d.out.alias_handle = &alias_handle;
2104 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2105 if (!NT_STATUS_IS_OK(status)) {
2112 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2116 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2117 struct policy_handle *alias_handle)
2119 struct samr_DeleteDomAlias d;
2122 printf("Testing DeleteAlias\n");
2124 d.in.alias_handle = alias_handle;
2125 d.out.alias_handle = alias_handle;
2127 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2128 if (!NT_STATUS_IS_OK(status)) {
2129 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2136 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2137 struct policy_handle *domain_handle,
2138 struct policy_handle *alias_handle,
2139 const struct dom_sid *domain_sid)
2142 struct samr_CreateDomAlias r;
2143 struct lsa_String name;
2147 init_lsa_String(&name, TEST_ALIASNAME);
2148 r.in.domain_handle = domain_handle;
2149 r.in.alias_name = &name;
2150 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2151 r.out.alias_handle = alias_handle;
2154 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2156 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2158 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2159 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2163 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2164 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2167 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2170 if (!NT_STATUS_IS_OK(status)) {
2171 printf("CreateAlias failed - %s\n", nt_errstr(status));
2175 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2182 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2183 const char *acct_name,
2184 struct policy_handle *domain_handle, char **password)
2192 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2196 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2200 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2204 /* test what happens when setting the old password again */
2205 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2210 char simple_pass[9];
2211 char *v = generate_random_str(mem_ctx, 1);
2213 ZERO_STRUCT(simple_pass);
2214 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2216 /* test what happens when picking a simple password */
2217 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2222 /* set samr_SetDomainInfo level 1 with min_length 5 */
2224 struct samr_QueryDomainInfo r;
2225 struct samr_SetDomainInfo s;
2226 uint16_t len_old, len;
2227 uint32_t pwd_prop_old;
2232 r.in.domain_handle = domain_handle;
2235 printf("testing samr_QueryDomainInfo level 1\n");
2236 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2237 if (!NT_STATUS_IS_OK(status)) {
2241 s.in.domain_handle = domain_handle;
2243 s.in.info = r.out.info;
2245 /* remember the old min length, so we can reset it */
2246 len_old = s.in.info->info1.min_password_length;
2247 s.in.info->info1.min_password_length = len;
2248 pwd_prop_old = s.in.info->info1.password_properties;
2249 /* turn off password complexity checks for this test */
2250 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2252 printf("testing samr_SetDomainInfo level 1\n");
2253 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2254 if (!NT_STATUS_IS_OK(status)) {
2258 printf("calling test_ChangePasswordUser3 with too short password\n");
2260 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2264 s.in.info->info1.min_password_length = len_old;
2265 s.in.info->info1.password_properties = pwd_prop_old;
2267 printf("testing samr_SetDomainInfo level 1\n");
2268 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2269 if (!NT_STATUS_IS_OK(status)) {
2277 struct samr_OpenUser r;
2278 struct samr_QueryUserInfo q;
2279 struct samr_LookupNames n;
2280 struct policy_handle user_handle;
2282 n.in.domain_handle = domain_handle;
2284 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2285 n.in.names[0].string = acct_name;
2287 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2288 if (!NT_STATUS_IS_OK(status)) {
2289 printf("LookupNames failed - %s\n", nt_errstr(status));
2293 r.in.domain_handle = domain_handle;
2294 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2295 r.in.rid = n.out.rids.ids[0];
2296 r.out.user_handle = &user_handle;
2298 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2299 if (!NT_STATUS_IS_OK(status)) {
2300 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2304 q.in.user_handle = &user_handle;
2307 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2308 if (!NT_STATUS_IS_OK(status)) {
2309 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2313 printf("calling test_ChangePasswordUser3 with too early password change\n");
2315 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2316 q.out.info->info5.last_password_change, True)) {
2321 /* we change passwords twice - this has the effect of verifying
2322 they were changed correctly for the final call */
2323 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2327 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2334 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2335 struct policy_handle *domain_handle,
2336 struct policy_handle *user_handle_out,
2337 enum torture_samr_choice which_ops)
2340 TALLOC_CTX *user_ctx;
2343 struct samr_CreateUser r;
2344 struct samr_QueryUserInfo q;
2345 struct samr_DeleteUser d;
2348 /* This call creates a 'normal' account - check that it really does */
2349 const uint32_t acct_flags = ACB_NORMAL;
2350 struct lsa_String name;
2353 struct policy_handle user_handle;
2354 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2355 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2357 r.in.domain_handle = domain_handle;
2358 r.in.account_name = &name;
2359 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2360 r.out.user_handle = &user_handle;
2363 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2365 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2367 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2368 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2369 talloc_free(user_ctx);
2373 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2374 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2375 talloc_free(user_ctx);
2378 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2380 if (!NT_STATUS_IS_OK(status)) {
2381 talloc_free(user_ctx);
2382 printf("CreateUser failed - %s\n", nt_errstr(status));
2385 q.in.user_handle = &user_handle;
2388 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2389 if (!NT_STATUS_IS_OK(status)) {
2390 printf("QueryUserInfo level %u failed - %s\n",
2391 q.in.level, nt_errstr(status));
2394 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2395 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2396 q.out.info->info16.acct_flags,
2402 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2403 acct_flags, name.string, which_ops)) {
2407 if (user_handle_out) {
2408 *user_handle_out = user_handle;
2410 printf("Testing DeleteUser (createuser test)\n");
2412 d.in.user_handle = &user_handle;
2413 d.out.user_handle = &user_handle;
2415 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2416 if (!NT_STATUS_IS_OK(status)) {
2417 printf("DeleteUser failed - %s\n", nt_errstr(status));
2424 talloc_free(user_ctx);
2430 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2431 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2434 struct samr_CreateUser2 r;
2435 struct samr_QueryUserInfo q;
2436 struct samr_DeleteUser d;
2437 struct policy_handle user_handle;
2439 struct lsa_String name;
2444 uint32_t acct_flags;
2445 const char *account_name;
2447 } account_types[] = {
2448 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2449 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2450 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2451 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2452 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2453 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2454 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2455 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2456 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2457 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2458 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2459 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2460 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2461 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2462 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2465 for (i = 0; account_types[i].account_name; i++) {
2466 TALLOC_CTX *user_ctx;
2467 uint32_t acct_flags = account_types[i].acct_flags;
2468 uint32_t access_granted;
2469 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2470 init_lsa_String(&name, account_types[i].account_name);
2472 r.in.domain_handle = domain_handle;
2473 r.in.account_name = &name;
2474 r.in.acct_flags = acct_flags;
2475 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2476 r.out.user_handle = &user_handle;
2477 r.out.access_granted = &access_granted;
2480 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2482 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2484 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2485 talloc_free(user_ctx);
2486 printf("Server refused create of '%s'\n", r.in.account_name->string);
2489 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2490 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2491 talloc_free(user_ctx);
2495 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2498 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2499 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2500 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2504 if (NT_STATUS_IS_OK(status)) {
2505 q.in.user_handle = &user_handle;
2508 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2509 if (!NT_STATUS_IS_OK(status)) {
2510 printf("QueryUserInfo level %u failed - %s\n",
2511 q.in.level, nt_errstr(status));
2514 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2515 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2516 q.out.info->info16.acct_flags,
2522 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2523 acct_flags, name.string, which_ops)) {
2527 printf("Testing DeleteUser (createuser2 test)\n");
2529 d.in.user_handle = &user_handle;
2530 d.out.user_handle = &user_handle;
2532 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2533 if (!NT_STATUS_IS_OK(status)) {
2534 printf("DeleteUser failed - %s\n", nt_errstr(status));
2538 talloc_free(user_ctx);
2544 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2545 struct policy_handle *handle)
2548 struct samr_QueryAliasInfo r;
2549 uint16_t levels[] = {1, 2, 3};
2553 for (i=0;i<ARRAY_SIZE(levels);i++) {
2554 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2556 r.in.alias_handle = handle;
2557 r.in.level = levels[i];
2559 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 printf("QueryAliasInfo level %u failed - %s\n",
2562 levels[i], nt_errstr(status));
2570 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2571 struct policy_handle *handle)
2574 struct samr_QueryGroupInfo r;
2575 uint16_t levels[] = {1, 2, 3, 4, 5};
2579 for (i=0;i<ARRAY_SIZE(levels);i++) {
2580 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2582 r.in.group_handle = handle;
2583 r.in.level = levels[i];
2585 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2586 if (!NT_STATUS_IS_OK(status)) {
2587 printf("QueryGroupInfo level %u failed - %s\n",
2588 levels[i], nt_errstr(status));
2596 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2597 struct policy_handle *handle)
2600 struct samr_QueryGroupMember r;
2603 printf("Testing QueryGroupMember\n");
2605 r.in.group_handle = handle;
2607 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2608 if (!NT_STATUS_IS_OK(status)) {
2609 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2617 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2618 struct policy_handle *handle)
2621 struct samr_QueryGroupInfo r;
2622 struct samr_SetGroupInfo s;
2623 uint16_t levels[] = {1, 2, 3, 4};
2624 uint16_t set_ok[] = {0, 1, 1, 1};
2628 for (i=0;i<ARRAY_SIZE(levels);i++) {
2629 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2631 r.in.group_handle = handle;
2632 r.in.level = levels[i];
2634 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2635 if (!NT_STATUS_IS_OK(status)) {
2636 printf("QueryGroupInfo level %u failed - %s\n",
2637 levels[i], nt_errstr(status));
2641 printf("Testing SetGroupInfo level %u\n", levels[i]);
2643 s.in.group_handle = handle;
2644 s.in.level = levels[i];
2645 s.in.info = r.out.info;
2648 /* disabled this, as it changes the name only from the point of view of samr,
2649 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2650 the name is still reserved, so creating the old name fails, but deleting by the old name
2652 if (s.in.level == 2) {
2653 init_lsa_String(&s.in.info->string, "NewName");
2657 if (s.in.level == 4) {
2658 init_lsa_String(&s.in.info->description, "test description");
2661 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2663 if (!NT_STATUS_IS_OK(status)) {
2664 printf("SetGroupInfo level %u failed - %s\n",
2665 r.in.level, nt_errstr(status));
2670 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2671 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2672 r.in.level, nt_errstr(status));
2682 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2683 struct policy_handle *handle)
2686 struct samr_QueryUserInfo r;
2687 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2688 11, 12, 13, 14, 16, 17, 20, 21};
2692 for (i=0;i<ARRAY_SIZE(levels);i++) {
2693 printf("Testing QueryUserInfo level %u\n", levels[i]);
2695 r.in.user_handle = handle;
2696 r.in.level = levels[i];
2698 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2699 if (!NT_STATUS_IS_OK(status)) {
2700 printf("QueryUserInfo level %u failed - %s\n",
2701 levels[i], nt_errstr(status));
2709 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2710 struct policy_handle *handle)
2713 struct samr_QueryUserInfo2 r;
2714 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2715 11, 12, 13, 14, 16, 17, 20, 21};
2719 for (i=0;i<ARRAY_SIZE(levels);i++) {
2720 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2722 r.in.user_handle = handle;
2723 r.in.level = levels[i];
2725 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2726 if (!NT_STATUS_IS_OK(status)) {
2727 printf("QueryUserInfo2 level %u failed - %s\n",
2728 levels[i], nt_errstr(status));
2736 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2737 struct policy_handle *handle, uint32_t rid)
2740 struct samr_OpenUser r;
2741 struct policy_handle user_handle;
2744 printf("Testing OpenUser(%u)\n", rid);
2746 r.in.domain_handle = handle;
2747 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2749 r.out.user_handle = &user_handle;
2751 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2752 if (!NT_STATUS_IS_OK(status)) {
2753 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2757 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2761 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2765 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2769 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2773 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2777 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2784 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2785 struct policy_handle *handle, uint32_t rid)
2788 struct samr_OpenGroup r;
2789 struct policy_handle group_handle;
2792 printf("Testing OpenGroup(%u)\n", rid);
2794 r.in.domain_handle = handle;
2795 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2797 r.out.group_handle = &group_handle;
2799 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2805 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2809 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2813 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2817 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2824 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2825 struct policy_handle *handle, uint32_t rid)
2828 struct samr_OpenAlias r;
2829 struct policy_handle alias_handle;
2832 printf("Testing OpenAlias(%u)\n", rid);
2834 r.in.domain_handle = handle;
2835 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2837 r.out.alias_handle = &alias_handle;
2839 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2840 if (!NT_STATUS_IS_OK(status)) {
2841 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2845 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2849 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2853 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2857 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2864 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2865 struct policy_handle *handle)
2868 struct samr_EnumDomainUsers r;
2869 uint32_t resume_handle=0;
2872 struct samr_LookupNames n;
2873 struct samr_LookupRids lr ;
2875 printf("Testing EnumDomainUsers\n");
2877 r.in.domain_handle = handle;
2878 r.in.resume_handle = &resume_handle;
2879 r.in.acct_flags = 0;
2880 r.in.max_size = (uint32_t)-1;
2881 r.out.resume_handle = &resume_handle;
2883 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2884 if (!NT_STATUS_IS_OK(status)) {
2885 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2893 if (r.out.sam->count == 0) {
2897 for (i=0;i<r.out.sam->count;i++) {
2898 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2903 printf("Testing LookupNames\n");
2904 n.in.domain_handle = handle;
2905 n.in.num_names = r.out.sam->count;
2906 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2907 for (i=0;i<r.out.sam->count;i++) {
2908 n.in.names[i].string = r.out.sam->entries[i].name.string;
2910 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2911 if (!NT_STATUS_IS_OK(status)) {
2912 printf("LookupNames failed - %s\n", nt_errstr(status));
2917 printf("Testing LookupRids\n");
2918 lr.in.domain_handle = handle;
2919 lr.in.num_rids = r.out.sam->count;
2920 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2921 for (i=0;i<r.out.sam->count;i++) {
2922 lr.in.rids[i] = r.out.sam->entries[i].idx;
2924 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2925 if (!NT_STATUS_IS_OK(status)) {
2926 printf("LookupRids failed - %s\n", nt_errstr(status));
2934 try blasting the server with a bunch of sync requests
2936 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2937 struct policy_handle *handle)
2940 struct samr_EnumDomainUsers r;
2941 uint32_t resume_handle=0;
2943 #define ASYNC_COUNT 100
2944 struct rpc_request *req[ASYNC_COUNT];
2946 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2947 printf("samr async test disabled - enable dangerous tests to use\n");
2951 printf("Testing EnumDomainUsers_async\n");
2953 r.in.domain_handle = handle;
2954 r.in.resume_handle = &resume_handle;
2955 r.in.acct_flags = 0;
2956 r.in.max_size = (uint32_t)-1;
2957 r.out.resume_handle = &resume_handle;
2959 for (i=0;i<ASYNC_COUNT;i++) {
2960 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2963 for (i=0;i<ASYNC_COUNT;i++) {
2964 status = dcerpc_ndr_request_recv(req[i]);
2965 if (!NT_STATUS_IS_OK(status)) {
2966 printf("EnumDomainUsers[%d] failed - %s\n",
2967 i, nt_errstr(status));
2972 printf("%d async requests OK\n", i);
2977 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2978 struct policy_handle *handle)
2981 struct samr_EnumDomainGroups r;
2982 uint32_t resume_handle=0;
2986 printf("Testing EnumDomainGroups\n");
2988 r.in.domain_handle = handle;
2989 r.in.resume_handle = &resume_handle;
2990 r.in.max_size = (uint32_t)-1;
2991 r.out.resume_handle = &resume_handle;
2993 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3003 for (i=0;i<r.out.sam->count;i++) {
3004 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3012 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3013 struct policy_handle *handle)
3016 struct samr_EnumDomainAliases r;
3017 uint32_t resume_handle=0;
3021 printf("Testing EnumDomainAliases\n");
3023 r.in.domain_handle = handle;
3024 r.in.resume_handle = &resume_handle;
3025 r.in.acct_flags = (uint32_t)-1;
3026 r.out.resume_handle = &resume_handle;
3028 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3029 if (!NT_STATUS_IS_OK(status)) {
3030 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3038 for (i=0;i<r.out.sam->count;i++) {
3039 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3047 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3048 struct policy_handle *handle)
3051 struct samr_GetDisplayEnumerationIndex r;
3053 uint16_t levels[] = {1, 2, 3, 4, 5};
3054 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3057 for (i=0;i<ARRAY_SIZE(levels);i++) {
3058 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3060 r.in.domain_handle = handle;
3061 r.in.level = levels[i];
3062 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3064 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3067 !NT_STATUS_IS_OK(status) &&
3068 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3069 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3070 levels[i], nt_errstr(status));
3074 init_lsa_String(&r.in.name, "zzzzzzzz");
3076 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3078 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3079 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3080 levels[i], nt_errstr(status));
3088 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3089 struct policy_handle *handle)
3092 struct samr_GetDisplayEnumerationIndex2 r;
3094 uint16_t levels[] = {1, 2, 3, 4, 5};
3095 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3098 for (i=0;i<ARRAY_SIZE(levels);i++) {
3099 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3101 r.in.domain_handle = handle;
3102 r.in.level = levels[i];
3103 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3105 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3107 !NT_STATUS_IS_OK(status) &&
3108 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3109 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3110 levels[i], nt_errstr(status));
3114 init_lsa_String(&r.in.name, "zzzzzzzz");
3116 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3117 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3118 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3119 levels[i], nt_errstr(status));
3127 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3128 struct policy_handle *handle)
3131 struct samr_QueryDisplayInfo r;
3133 uint16_t levels[] = {1, 2, 3, 4, 5};
3136 for (i=0;i<ARRAY_SIZE(levels);i++) {
3137 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3139 r.in.domain_handle = handle;
3140 r.in.level = levels[i];
3142 r.in.max_entries = 1000;
3143 r.in.buf_size = (uint32_t)-1;
3145 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3146 if (!NT_STATUS_IS_OK(status)) {
3147 printf("QueryDisplayInfo level %u failed - %s\n",
3148 levels[i], nt_errstr(status));
3156 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3157 struct policy_handle *handle)
3160 struct samr_QueryDisplayInfo2 r;
3162 uint16_t levels[] = {1, 2, 3, 4, 5};
3165 for (i=0;i<ARRAY_SIZE(levels);i++) {
3166 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3168 r.in.domain_handle = handle;
3169 r.in.level = levels[i];
3171 r.in.max_entries = 1000;
3172 r.in.buf_size = (uint32_t)-1;
3174 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3175 if (!NT_STATUS_IS_OK(status)) {
3176 printf("QueryDisplayInfo2 level %u failed - %s\n",
3177 levels[i], nt_errstr(status));
3185 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3186 struct policy_handle *handle)
3189 struct samr_QueryDisplayInfo3 r;
3191 uint16_t levels[] = {1, 2, 3, 4, 5};
3194 for (i=0;i<ARRAY_SIZE(levels);i++) {
3195 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3197 r.in.domain_handle = handle;
3198 r.in.level = levels[i];
3200 r.in.max_entries = 1000;
3201 r.in.buf_size = (uint32_t)-1;
3203 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3204 if (!NT_STATUS_IS_OK(status)) {
3205 printf("QueryDisplayInfo3 level %u failed - %s\n",
3206 levels[i], nt_errstr(status));
3215 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3216 struct policy_handle *handle)
3219 struct samr_QueryDisplayInfo r;
3222 printf("Testing QueryDisplayInfo continuation\n");
3224 r.in.domain_handle = handle;
3227 r.in.max_entries = 1;
3228 r.in.buf_size = (uint32_t)-1;
3231 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3232 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3233 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3234 printf("expected idx %d but got %d\n",
3236 r.out.info.info1.entries[0].idx);
3240 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3241 !NT_STATUS_IS_OK(status)) {
3242 printf("QueryDisplayInfo level %u failed - %s\n",
3243 r.in.level, nt_errstr(status));
3248 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3249 NT_STATUS_IS_OK(status)) &&
3250 r.out.returned_size != 0);
3255 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3256 struct policy_handle *handle)
3259 struct samr_QueryDomainInfo r;
3260 struct samr_SetDomainInfo s;
3261 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3262 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3265 const char *domain_comment = talloc_asprintf(mem_ctx,
3266 "Tortured by Samba4 RPC-SAMR: %s",
3267 timestring(mem_ctx, time(NULL)));
3269 s.in.domain_handle = handle;
3271 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3273 s.in.info->info4.comment.string = domain_comment;
3274 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3275 if (!NT_STATUS_IS_OK(status)) {
3276 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3277 r.in.level, nt_errstr(status));
3281 for (i=0;i<ARRAY_SIZE(levels);i++) {
3282 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3284 r.in.domain_handle = handle;
3285 r.in.level = levels[i];
3287 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3288 if (!NT_STATUS_IS_OK(status)) {
3289 printf("QueryDomainInfo level %u failed - %s\n",
3290 r.in.level, nt_errstr(status));
3295 switch (levels[i]) {
3297 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3298 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3299 levels[i], r.out.info->info2.comment.string, domain_comment);
3302 if (!r.out.info->info2.primary.string) {
3303 printf("QueryDomainInfo level %u returned no PDC name\n",
3306 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3307 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3308 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3309 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3314 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3315 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3316 levels[i], r.out.info->info4.comment.string, domain_comment);
3321 if (!r.out.info->info6.primary.string) {
3322 printf("QueryDomainInfo level %u returned no PDC name\n",
3328 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3329 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3330 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3336 printf("Testing SetDomainInfo level %u\n", levels[i]);
3338 s.in.domain_handle = handle;
3339 s.in.level = levels[i];
3340 s.in.info = r.out.info;
3342 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3344 if (!NT_STATUS_IS_OK(status)) {
3345 printf("SetDomainInfo level %u failed - %s\n",
3346 r.in.level, nt_errstr(status));
3351 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3352 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3353 r.in.level, nt_errstr(status));
3359 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3360 if (!NT_STATUS_IS_OK(status)) {
3361 printf("QueryDomainInfo level %u failed - %s\n",
3362 r.in.level, nt_errstr(status));
3372 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3373 struct policy_handle *handle)
3376 struct samr_QueryDomainInfo2 r;
3377 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3381 for (i=0;i<ARRAY_SIZE(levels);i++) {
3382 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3384 r.in.domain_handle = handle;
3385 r.in.level = levels[i];
3387 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3388 if (!NT_STATUS_IS_OK(status)) {
3389 printf("QueryDomainInfo2 level %u failed - %s\n",
3390 r.in.level, nt_errstr(status));
3399 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3400 set of group names. */
3401 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3402 struct policy_handle *handle)
3404 struct samr_EnumDomainGroups q1;
3405 struct samr_QueryDisplayInfo q2;
3407 uint32_t resume_handle=0;
3412 const char **names = NULL;
3414 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3416 q1.in.domain_handle = handle;
3417 q1.in.resume_handle = &resume_handle;
3419 q1.out.resume_handle = &resume_handle;
3421 status = STATUS_MORE_ENTRIES;
3422 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3423 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3425 if (!NT_STATUS_IS_OK(status) &&
3426 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3429 for (i=0; i<q1.out.num_entries; i++) {
3430 add_string_to_array(mem_ctx,
3431 q1.out.sam->entries[i].name.string,
3432 &names, &num_names);
3436 if (!NT_STATUS_IS_OK(status)) {
3437 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3445 q2.in.domain_handle = handle;
3447 q2.in.start_idx = 0;
3448 q2.in.max_entries = 5;
3449 q2.in.buf_size = (uint32_t)-1;
3451 status = STATUS_MORE_ENTRIES;
3452 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3453 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3455 if (!NT_STATUS_IS_OK(status) &&
3456 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3459 for (i=0; i<q2.out.info.info5.count; i++) {
3461 const char *name = q2.out.info.info5.entries[i].account_name.string;
3463 for (j=0; j<num_names; j++) {
3464 if (names[j] == NULL)
3466 /* Hmm. No strequal in samba4 */
3467 if (strequal(names[j], name)) {
3475 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3480 q2.in.start_idx += q2.out.info.info5.count;
3483 if (!NT_STATUS_IS_OK(status)) {
3484 printf("QueryDisplayInfo level 5 failed - %s\n",
3489 for (i=0; i<num_names; i++) {
3490 if (names[i] != NULL) {
3491 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3500 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3501 struct policy_handle *group_handle)
3503 struct samr_DeleteDomainGroup d;
3507 printf("Testing DeleteDomainGroup\n");
3509 d.in.group_handle = group_handle;
3510 d.out.group_handle = group_handle;
3512 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3513 if (!NT_STATUS_IS_OK(status)) {
3514 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3521 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3522 struct policy_handle *domain_handle)
3524 struct samr_TestPrivateFunctionsDomain r;
3528 printf("Testing TestPrivateFunctionsDomain\n");
3530 r.in.domain_handle = domain_handle;
3532 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3533 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3534 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3541 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3542 struct dom_sid *domain_sid,
3543 struct policy_handle *domain_handle)
3545 struct samr_RidToSid r;
3548 struct dom_sid *calc_sid;
3549 int rids[] = { 0, 42, 512, 10200 };
3552 for (i=0;i<ARRAY_SIZE(rids);i++) {
3554 printf("Testing RidToSid\n");
3556 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3557 r.in.domain_handle = domain_handle;
3560 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3561 if (!NT_STATUS_IS_OK(status)) {
3562 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3565 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3567 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3568 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3569 dom_sid_string(mem_ctx, r.out.sid),
3570 dom_sid_string(mem_ctx, calc_sid));
3579 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3580 struct policy_handle *domain_handle)
3582 struct samr_GetBootKeyInformation r;
3586 printf("Testing GetBootKeyInformation\n");
3588 r.in.domain_handle = domain_handle;
3590 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
3591 if (!NT_STATUS_IS_OK(status)) {
3592 /* w2k3 seems to fail this sometimes and pass it sometimes */
3593 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
3599 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3600 struct policy_handle *domain_handle,
3601 struct policy_handle *group_handle)
3604 struct samr_AddGroupMember r;
3605 struct samr_DeleteGroupMember d;
3606 struct samr_QueryGroupMember q;
3607 struct samr_SetMemberAttributesOfGroup s;
3611 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
3612 if (!NT_STATUS_IS_OK(status)) {
3613 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
3617 r.in.group_handle = group_handle;
3619 r.in.flags = 0; /* ??? */
3621 printf("Testing AddGroupMember and DeleteGroupMember\n");
3623 d.in.group_handle = group_handle;
3626 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3627 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
3628 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
3633 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3634 if (!NT_STATUS_IS_OK(status)) {
3635 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3639 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3640 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
3641 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
3646 if (lp_parm_bool(-1, "torture", "samba4", False)) {
3647 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
3649 /* this one is quite strange. I am using random inputs in the
3650 hope of triggering an error that might give us a clue */
3652 s.in.group_handle = group_handle;
3653 s.in.unknown1 = random();
3654 s.in.unknown2 = random();
3656 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
3657 if (!NT_STATUS_IS_OK(status)) {
3658 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
3663 q.in.group_handle = group_handle;
3665 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
3666 if (!NT_STATUS_IS_OK(status)) {
3667 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
3671 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3672 if (!NT_STATUS_IS_OK(status)) {
3673 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
3677 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3678 if (!NT_STATUS_IS_OK(status)) {
3679 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3687 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3688 struct policy_handle *domain_handle, struct policy_handle *group_handle)
3691 struct samr_CreateDomainGroup r;
3693 struct lsa_String name;
3696 init_lsa_String(&name, TEST_GROUPNAME);
3698 r.in.domain_handle = domain_handle;
3700 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3701 r.out.group_handle = group_handle;
3704 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3706 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3708 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3709 printf("Server refused create of '%s'\n", r.in.name->string);
3710 ZERO_STRUCTP(group_handle);
3714 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
3715 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3717 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
3721 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3723 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3724 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3726 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
3730 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3732 if (!NT_STATUS_IS_OK(status)) {
3733 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3737 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3738 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3742 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3751 its not totally clear what this does. It seems to accept any sid you like.
3753 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3754 TALLOC_CTX *mem_ctx,
3755 struct policy_handle *domain_handle)
3758 struct samr_RemoveMemberFromForeignDomain r;
3760 r.in.domain_handle = domain_handle;
3761 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3763 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3764 if (!NT_STATUS_IS_OK(status)) {
3765 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3774 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3775 struct policy_handle *handle);
3777 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3778 struct policy_handle *handle, struct dom_sid *sid,
3779 enum torture_samr_choice which_ops)
3782 struct samr_OpenDomain r;
3783 struct policy_handle domain_handle;
3784 struct policy_handle alias_handle;
3785 struct policy_handle user_handle;
3786 struct policy_handle group_handle;
3789 ZERO_STRUCT(alias_handle);
3790 ZERO_STRUCT(user_handle);
3791 ZERO_STRUCT(group_handle);
3792 ZERO_STRUCT(domain_handle);
3794 printf("Testing OpenDomain\n");
3796 r.in.connect_handle = handle;
3797 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3799 r.out.domain_handle = &domain_handle;
3801 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3802 if (!NT_STATUS_IS_OK(status)) {
3803 printf("OpenDomain failed - %s\n", nt_errstr(status));
3807 /* run the domain tests with the main handle closed - this tests
3808 the servers reference counting */
3809 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3811 switch (which_ops) {
3812 case TORTURE_SAMR_USER_ATTRIBUTES:
3813 case TORTURE_SAMR_PASSWORDS:
3814 ret &= test_CreateUser(p, mem_ctx, &domain_handle, NULL, which_ops);
3815 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
3817 case TORTURE_SAMR_OTHER:
3818 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
3819 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3820 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3821 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3822 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3823 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3824 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3825 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3826 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3827 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3828 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3829 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3830 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3831 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3832 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3834 if (lp_parm_bool(-1, "torture", "samba4", False)) {
3835 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
3837 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3838 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3840 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3841 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3842 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3843 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3847 if (!policy_handle_empty(&user_handle) &&
3848 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3852 if (!policy_handle_empty(&alias_handle) &&
3853 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3857 if (!policy_handle_empty(&group_handle) &&
3858 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3862 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3864 /* reconnect the main handle */
3865 ret &= test_Connect(p, mem_ctx, handle);
3868 printf("Testing domain %s failed!\n", dom_sid_string(mem_ctx, sid));
3874 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3875 struct policy_handle *handle, const char *domain,
3876 enum torture_samr_choice which_ops)
3879 struct samr_LookupDomain r;
3880 struct lsa_String n1;
3881 struct lsa_String n2;
3884 printf("Testing LookupDomain(%s)\n", domain);
3886 /* check for correct error codes */
3887 r.in.connect_handle = handle;
3888 r.in.domain_name = &n2;
3891 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3892 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3893 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3897 init_lsa_String(&n2, "xxNODOMAINxx");
3899 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3900 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3901 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3905 r.in.connect_handle = handle;
3907 init_lsa_String(&n1, domain);
3908 r.in.domain_name = &n1;
3910 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3911 if (!NT_STATUS_IS_OK(status)) {
3912 printf("LookupDomain failed - %s\n", nt_errstr(status));
3916 if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
3920 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
3928 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3929 struct policy_handle *handle, enum torture_samr_choice which_ops)
3932 struct samr_EnumDomains r;
3933 uint32_t resume_handle = 0;
3937 r.in.connect_handle = handle;
3938 r.in.resume_handle = &resume_handle;
3939 r.in.buf_size = (uint32_t)-1;
3940 r.out.resume_handle = &resume_handle;
3942 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3943 if (!NT_STATUS_IS_OK(status)) {
3944 printf("EnumDomains failed - %s\n", nt_errstr(status));
3952 for (i=0;i<r.out.sam->count;i++) {
3953 if (!test_LookupDomain(p, mem_ctx, handle,
3954 r.out.sam->entries[i].name.string, which_ops)) {
3959 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3960 if (!NT_STATUS_IS_OK(status)) {
3961 printf("EnumDomains failed - %s\n", nt_errstr(status));
3969 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3970 struct policy_handle *handle)
3973 struct samr_Connect r;
3974 struct samr_Connect2 r2;
3975 struct samr_Connect3 r3;
3976 struct samr_Connect4 r4;
3977 struct samr_Connect5 r5;
3978 union samr_ConnectInfo info;
3979 struct policy_handle h;
3980 BOOL ret = True, got_handle = False;
3982 printf("testing samr_Connect\n");
3984 r.in.system_name = 0;
3985 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3986 r.out.connect_handle = &h;
3988 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3989 if (!NT_STATUS_IS_OK(status)) {
3990 printf("Connect failed - %s\n", nt_errstr(status));
3997 printf("testing samr_Connect2\n");
3999 r2.in.system_name = NULL;
4000 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4001 r2.out.connect_handle = &h;
4003 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4004 if (!NT_STATUS_IS_OK(status)) {
4005 printf("Connect2 failed - %s\n", nt_errstr(status));
4009 test_samr_handle_Close(p, mem_ctx, handle);
4015 printf("testing samr_Connect3\n");
4017 r3.in.system_name = NULL;
4019 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4020 r3.out.connect_handle = &h;
4022 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4023 if (!NT_STATUS_IS_OK(status)) {
4024 printf("Connect3 failed - %s\n", nt_errstr(status));
4028 test_samr_handle_Close(p, mem_ctx, handle);
4034 printf("testing samr_Connect4\n");
4036 r4.in.system_name = "";
4038 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4039 r4.out.connect_handle = &h;
4041 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4042 if (!NT_STATUS_IS_OK(status)) {
4043 printf("Connect4 failed - %s\n", nt_errstr(status));
4047 test_samr_handle_Close(p, mem_ctx, handle);
4053 printf("testing samr_Connect5\n");
4055 info.info1.unknown1 = 0;
4056 info.info1.unknown2 = 0;
4058 r5.in.system_name = "";
4059 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4062 r5.out.info = &info;
4063 r5.out.connect_handle = &h;
4065 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4066 if (!NT_STATUS_IS_OK(status)) {
4067 printf("Connect5 failed - %s\n", nt_errstr(status));
4071 test_samr_handle_Close(p, mem_ctx, handle);
4081 BOOL torture_rpc_samr(struct torture_context *torture)
4084 struct dcerpc_pipe *p;
4086 struct policy_handle handle;
4088 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
4089 if (!NT_STATUS_IS_OK(status)) {
4093 ret &= test_Connect(p, torture, &handle);
4095 ret &= test_QuerySecurity(p, torture, &handle);
4097 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4099 ret &= test_SetDsrmPassword(p, torture, &handle);
4101 ret &= test_Shutdown(p, torture, &handle);
4103 ret &= test_samr_handle_Close(p, torture, &handle);
4109 BOOL torture_rpc_samr_users(struct torture_context *torture)
4112 struct dcerpc_pipe *p;
4114 struct policy_handle handle;
4116 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
4117 if (!NT_STATUS_IS_OK(status)) {
4121 ret &= test_Connect(p, torture, &handle);
4123 ret &= test_QuerySecurity(p, torture, &handle);
4125 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4127 ret &= test_SetDsrmPassword(p, torture, &handle);
4129 ret &= test_Shutdown(p, torture, &handle);
4131 ret &= test_samr_handle_Close(p, torture, &handle);
4137 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
4140 struct dcerpc_pipe *p;
4142 struct policy_handle handle;
4144 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
4145 if (!NT_STATUS_IS_OK(status)) {
4149 ret &= test_Connect(p, torture, &handle);
4151 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4153 ret &= test_samr_handle_Close(p, torture, &handle);