2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
63 struct policy_handle *handle)
69 r.out.handle = handle;
71 status = dcerpc_samr_Close(p, mem_ctx, &r);
72 if (!NT_STATUS_IS_OK(status)) {
73 printf("Close handle failed - %s\n", nt_errstr(status));
80 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
81 struct policy_handle *handle)
84 struct samr_Shutdown r;
86 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
87 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
91 r.in.connect_handle = handle;
93 printf("testing samr_Shutdown\n");
95 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
96 if (!NT_STATUS_IS_OK(status)) {
97 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
104 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
105 struct policy_handle *handle)
108 struct samr_SetDsrmPassword r;
109 struct lsa_String string;
110 struct samr_Password hash;
112 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
113 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 printf("testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
128 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
129 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
137 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
138 struct policy_handle *handle)
141 struct samr_QuerySecurity r;
142 struct samr_SetSecurity s;
144 r.in.handle = handle;
147 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
148 if (!NT_STATUS_IS_OK(status)) {
149 printf("QuerySecurity failed - %s\n", nt_errstr(status));
153 if (r.out.sdbuf == NULL) {
157 s.in.handle = handle;
159 s.in.sdbuf = r.out.sdbuf;
161 if (lp_parm_bool(-1, "torture", "samba4", False)) {
162 printf("skipping SetSecurity test against Samba4\n");
166 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
167 if (!NT_STATUS_IS_OK(status)) {
168 printf("SetSecurity failed - %s\n", nt_errstr(status));
172 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
173 if (!NT_STATUS_IS_OK(status)) {
174 printf("QuerySecurity failed - %s\n", nt_errstr(status));
182 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
183 struct policy_handle *handle, uint32_t base_acct_flags,
184 const char *base_account_name)
187 struct samr_SetUserInfo s;
188 struct samr_SetUserInfo2 s2;
189 struct samr_QueryUserInfo q;
190 struct samr_QueryUserInfo q0;
191 union samr_UserInfo u;
193 const char *test_account_name;
195 uint32_t user_extra_flags = 0;
196 if (base_acct_flags == ACB_NORMAL) {
197 /* When created, accounts are expired by default */
198 user_extra_flags = ACB_PW_EXPIRED;
201 s.in.user_handle = handle;
204 s2.in.user_handle = handle;
207 q.in.user_handle = handle;
211 #define TESTCALL(call, r) \
212 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
213 if (!NT_STATUS_IS_OK(status)) { \
214 printf(#call " level %u failed - %s (%s)\n", \
215 r.in.level, nt_errstr(status), __location__); \
220 #define STRING_EQUAL(s1, s2, field) \
221 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
222 printf("Failed to set %s to '%s' (%s)\n", \
223 #field, s2, __location__); \
228 #define INT_EQUAL(i1, i2, field) \
230 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
231 #field, i2, i1, __location__); \
236 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
237 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
239 TESTCALL(QueryUserInfo, q) \
241 s2.in.level = lvl1; \
244 ZERO_STRUCT(u.info21); \
245 u.info21.fields_present = fpval; \
247 init_lsa_String(&u.info ## lvl1.field1, value); \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 init_lsa_String(&u.info ## lvl1.field1, ""); \
251 TESTCALL(QueryUserInfo, q); \
253 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
255 TESTCALL(QueryUserInfo, q) \
257 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
261 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
263 TESTCALL(QueryUserInfo, q) \
265 s2.in.level = lvl1; \
268 uint8_t *bits = u.info21.logon_hours.bits; \
269 ZERO_STRUCT(u.info21); \
270 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
271 u.info21.logon_hours.units_per_week = 168; \
272 u.info21.logon_hours.bits = bits; \
274 u.info21.fields_present = fpval; \
276 u.info ## lvl1.field1 = value; \
277 TESTCALL(SetUserInfo, s) \
278 TESTCALL(SetUserInfo2, s2) \
279 u.info ## lvl1.field1 = 0; \
280 TESTCALL(QueryUserInfo, q); \
282 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
284 TESTCALL(QueryUserInfo, q) \
286 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
289 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
290 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
294 do { TESTCALL(QueryUserInfo, q0) } while (0);
296 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
297 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
298 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
301 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
302 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
303 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
304 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
305 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
306 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
307 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
308 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
309 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
310 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
311 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
312 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
313 test_account_name = base_account_name;
314 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
315 SAMR_FIELD_ACCOUNT_NAME);
317 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
318 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
319 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
323 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
324 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
325 SAMR_FIELD_FULL_NAME);
327 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
328 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
329 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
333 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
334 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
335 SAMR_FIELD_FULL_NAME);
337 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
338 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
339 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
340 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
341 SAMR_FIELD_LOGON_SCRIPT);
343 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
344 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
345 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
346 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
347 SAMR_FIELD_PROFILE_PATH);
349 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
350 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
351 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
352 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
353 SAMR_FIELD_HOME_DIRECTORY);
354 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
355 SAMR_FIELD_HOME_DIRECTORY);
357 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
358 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
359 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
360 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
361 SAMR_FIELD_HOME_DRIVE);
362 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
363 SAMR_FIELD_HOME_DRIVE);
365 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
366 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
367 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
368 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
369 SAMR_FIELD_DESCRIPTION);
371 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
372 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
373 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
374 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
375 SAMR_FIELD_WORKSTATIONS);
377 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
378 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
379 SAMR_FIELD_PARAMETERS);
381 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
382 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
383 SAMR_FIELD_COUNTRY_CODE);
385 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
386 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
387 SAMR_FIELD_CODE_PAGE);
389 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
390 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
391 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
392 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
393 SAMR_FIELD_LOGON_HOURS);
395 if (lp_parm_bool(-1, "torture", "samba4", False)) {
396 printf("skipping Set Account Flag tests against Samba4\n");
400 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
401 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
402 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
404 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
405 (base_acct_flags | ACB_DISABLED),
406 (base_acct_flags | ACB_DISABLED | user_extra_flags),
409 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
410 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
411 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
412 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
414 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
415 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
416 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
420 /* The 'autolock' flag doesn't stick - check this */
421 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
422 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
423 (base_acct_flags | ACB_DISABLED | user_extra_flags),
426 /* Removing the 'disabled' flag doesn't stick - check this */
427 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
429 (base_acct_flags | ACB_DISABLED | user_extra_flags),
432 /* The 'store plaintext' flag does stick */
433 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
434 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
435 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
437 /* The 'use DES' flag does stick */
438 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
440 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
442 /* The 'don't require kerberos pre-authentication flag does stick */
443 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
444 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
445 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
447 /* The 'no kerberos PAC required' flag sticks */
448 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
449 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
450 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
453 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
454 (base_acct_flags | ACB_DISABLED),
455 (base_acct_flags | ACB_DISABLED | user_extra_flags),
456 SAMR_FIELD_ACCT_FLAGS);
459 /* these fail with win2003 - it appears you can't set the primary gid?
460 the set succeeds, but the gid isn't changed. Very weird! */
461 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
462 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
463 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
464 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
471 generate a random password for password change tests
473 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
475 size_t len = MAX(8, min_len) + (random() % 6);
476 char *s = generate_random_str(mem_ctx, len);
477 printf("Generated password '%s'\n", s);
482 generate a random password for password change tests (fixed length)
484 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
486 char *s = generate_random_str(mem_ctx, len);
487 printf("Generated password '%s'\n", s);
491 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
492 struct policy_handle *handle, char **password)
495 struct samr_SetUserInfo s;
496 union samr_UserInfo u;
498 DATA_BLOB session_key;
500 struct samr_GetUserPwInfo pwp;
501 int policy_min_pw_len = 0;
502 pwp.in.user_handle = handle;
504 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
505 if (NT_STATUS_IS_OK(status)) {
506 policy_min_pw_len = pwp.out.info.min_password_length;
508 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
510 s.in.user_handle = handle;
514 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
515 /* w2k3 ignores this length */
516 u.info24.pw_len = strlen_m(newpass) * 2;
518 status = dcerpc_fetch_session_key(p, &session_key);
519 if (!NT_STATUS_IS_OK(status)) {
520 printf("SetUserInfo level %u - no session key - %s\n",
521 s.in.level, nt_errstr(status));
525 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
527 printf("Testing SetUserInfo level 24 (set password)\n");
529 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
530 if (!NT_STATUS_IS_OK(status)) {
531 printf("SetUserInfo level %u failed - %s\n",
532 s.in.level, nt_errstr(status));
542 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
543 struct policy_handle *handle, uint32_t fields_present,
547 struct samr_SetUserInfo s;
548 union samr_UserInfo u;
550 DATA_BLOB session_key;
552 struct samr_GetUserPwInfo pwp;
553 int policy_min_pw_len = 0;
554 pwp.in.user_handle = handle;
556 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
557 if (NT_STATUS_IS_OK(status)) {
558 policy_min_pw_len = pwp.out.info.min_password_length;
560 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
562 s.in.user_handle = handle;
568 u.info23.info.fields_present = fields_present;
570 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
572 status = dcerpc_fetch_session_key(p, &session_key);
573 if (!NT_STATUS_IS_OK(status)) {
574 printf("SetUserInfo level %u - no session key - %s\n",
575 s.in.level, nt_errstr(status));
579 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
581 printf("Testing SetUserInfo level 23 (set password)\n");
583 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
584 if (!NT_STATUS_IS_OK(status)) {
585 printf("SetUserInfo level %u failed - %s\n",
586 s.in.level, nt_errstr(status));
592 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
594 status = dcerpc_fetch_session_key(p, &session_key);
595 if (!NT_STATUS_IS_OK(status)) {
596 printf("SetUserInfo level %u - no session key - %s\n",
597 s.in.level, nt_errstr(status));
601 /* This should break the key nicely */
602 session_key.length--;
603 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
605 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
607 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
608 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
609 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
610 s.in.level, nt_errstr(status));
618 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
619 struct policy_handle *handle, char **password)
622 struct samr_SetUserInfo s;
623 union samr_UserInfo u;
625 DATA_BLOB session_key;
626 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
627 uint8_t confounder[16];
629 struct MD5Context ctx;
630 struct samr_GetUserPwInfo pwp;
631 int policy_min_pw_len = 0;
632 pwp.in.user_handle = handle;
634 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
635 if (NT_STATUS_IS_OK(status)) {
636 policy_min_pw_len = pwp.out.info.min_password_length;
638 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
640 s.in.user_handle = handle;
644 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
645 u.info26.pw_len = strlen(newpass);
647 status = dcerpc_fetch_session_key(p, &session_key);
648 if (!NT_STATUS_IS_OK(status)) {
649 printf("SetUserInfo level %u - no session key - %s\n",
650 s.in.level, nt_errstr(status));
654 generate_random_buffer((uint8_t *)confounder, 16);
657 MD5Update(&ctx, confounder, 16);
658 MD5Update(&ctx, session_key.data, session_key.length);
659 MD5Final(confounded_session_key.data, &ctx);
661 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
662 memcpy(&u.info26.password.data[516], confounder, 16);
664 printf("Testing SetUserInfo level 26 (set password ex)\n");
666 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
667 if (!NT_STATUS_IS_OK(status)) {
668 printf("SetUserInfo level %u failed - %s\n",
669 s.in.level, nt_errstr(status));
675 /* This should break the key nicely */
676 confounded_session_key.data[0]++;
678 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
679 memcpy(&u.info26.password.data[516], confounder, 16);
681 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
683 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
684 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
685 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
686 s.in.level, nt_errstr(status));
695 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
696 struct policy_handle *handle, uint32_t fields_present,
700 struct samr_SetUserInfo s;
701 union samr_UserInfo u;
703 DATA_BLOB session_key;
704 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
705 struct MD5Context ctx;
706 uint8_t confounder[16];
708 struct samr_GetUserPwInfo pwp;
709 int policy_min_pw_len = 0;
710 pwp.in.user_handle = handle;
712 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
713 if (NT_STATUS_IS_OK(status)) {
714 policy_min_pw_len = pwp.out.info.min_password_length;
716 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
718 s.in.user_handle = handle;
724 u.info25.info.fields_present = fields_present;
726 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
728 status = dcerpc_fetch_session_key(p, &session_key);
729 if (!NT_STATUS_IS_OK(status)) {
730 printf("SetUserInfo level %u - no session key - %s\n",
731 s.in.level, nt_errstr(status));
735 generate_random_buffer((uint8_t *)confounder, 16);
738 MD5Update(&ctx, confounder, 16);
739 MD5Update(&ctx, session_key.data, session_key.length);
740 MD5Final(confounded_session_key.data, &ctx);
742 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
743 memcpy(&u.info25.password.data[516], confounder, 16);
745 printf("Testing SetUserInfo level 25 (set password ex)\n");
747 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
748 if (!NT_STATUS_IS_OK(status)) {
749 printf("SetUserInfo level %u failed - %s\n",
750 s.in.level, nt_errstr(status));
756 /* This should break the key nicely */
757 confounded_session_key.data[0]++;
759 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
760 memcpy(&u.info25.password.data[516], confounder, 16);
762 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
764 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
765 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
766 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
767 s.in.level, nt_errstr(status));
774 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
775 struct policy_handle *handle)
778 struct samr_SetAliasInfo r;
779 struct samr_QueryAliasInfo q;
780 uint16_t levels[] = {2, 3};
784 /* Ignoring switch level 1, as that includes the number of members for the alias
785 * and setting this to a wrong value might have negative consequences
788 for (i=0;i<ARRAY_SIZE(levels);i++) {
789 printf("Testing SetAliasInfo level %u\n", levels[i]);
791 r.in.alias_handle = handle;
792 r.in.level = levels[i];
793 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
794 switch (r.in.level) {
795 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
796 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
797 "Test Description, should test I18N as well"); break;
800 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
801 if (!NT_STATUS_IS_OK(status)) {
802 printf("SetAliasInfo level %u failed - %s\n",
803 levels[i], nt_errstr(status));
807 q.in.alias_handle = handle;
808 q.in.level = levels[i];
810 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
811 if (!NT_STATUS_IS_OK(status)) {
812 printf("QueryAliasInfo level %u failed - %s\n",
813 levels[i], nt_errstr(status));
821 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
822 struct policy_handle *user_handle)
824 struct samr_GetGroupsForUser r;
828 printf("testing GetGroupsForUser\n");
830 r.in.user_handle = user_handle;
832 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
833 if (!NT_STATUS_IS_OK(status)) {
834 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
842 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
843 struct lsa_String *domain_name)
846 struct samr_GetDomPwInfo r;
849 r.in.domain_name = domain_name;
850 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
852 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
853 if (!NT_STATUS_IS_OK(status)) {
854 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
858 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
859 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
861 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
862 if (!NT_STATUS_IS_OK(status)) {
863 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
867 r.in.domain_name->string = "\\\\__NONAME__";
868 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
870 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
871 if (!NT_STATUS_IS_OK(status)) {
872 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
876 r.in.domain_name->string = "\\\\Builtin";
877 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
879 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
880 if (!NT_STATUS_IS_OK(status)) {
881 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
889 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
890 struct policy_handle *handle)
893 struct samr_GetUserPwInfo r;
896 printf("Testing GetUserPwInfo\n");
898 r.in.user_handle = handle;
900 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
901 if (!NT_STATUS_IS_OK(status)) {
902 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
909 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
910 struct policy_handle *domain_handle, const char *name,
914 struct samr_LookupNames n;
915 struct lsa_String sname[2];
917 init_lsa_String(&sname[0], name);
919 n.in.domain_handle = domain_handle;
922 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
923 if (NT_STATUS_IS_OK(status)) {
924 *rid = n.out.rids.ids[0];
929 init_lsa_String(&sname[1], "xxNONAMExx");
931 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
932 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
933 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
934 if (NT_STATUS_IS_OK(status)) {
935 return NT_STATUS_UNSUCCESSFUL;
941 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
942 if (!NT_STATUS_IS_OK(status)) {
943 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
947 init_lsa_String(&sname[0], "xxNONAMExx");
949 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
950 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
951 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
952 if (NT_STATUS_IS_OK(status)) {
953 return NT_STATUS_UNSUCCESSFUL;
958 init_lsa_String(&sname[0], "xxNONAMExx");
959 init_lsa_String(&sname[1], "xxNONAME2xx");
961 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
962 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
963 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
964 if (NT_STATUS_IS_OK(status)) {
965 return NT_STATUS_UNSUCCESSFUL;
973 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
974 struct policy_handle *domain_handle,
975 const char *name, struct policy_handle *user_handle)
978 struct samr_OpenUser r;
981 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
982 if (!NT_STATUS_IS_OK(status)) {
986 r.in.domain_handle = domain_handle;
987 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
989 r.out.user_handle = user_handle;
990 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
991 if (!NT_STATUS_IS_OK(status)) {
992 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
999 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1000 struct policy_handle *handle)
1003 struct samr_ChangePasswordUser r;
1005 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1006 struct policy_handle user_handle;
1007 char *oldpass = "test";
1008 char *newpass = "test2";
1009 uint8_t old_nt_hash[16], new_nt_hash[16];
1010 uint8_t old_lm_hash[16], new_lm_hash[16];
1012 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1013 if (!NT_STATUS_IS_OK(status)) {
1017 printf("Testing ChangePasswordUser for user 'testuser'\n");
1019 printf("old password: %s\n", oldpass);
1020 printf("new password: %s\n", newpass);
1022 E_md4hash(oldpass, old_nt_hash);
1023 E_md4hash(newpass, new_nt_hash);
1024 E_deshash(oldpass, old_lm_hash);
1025 E_deshash(newpass, new_lm_hash);
1027 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1028 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1029 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1030 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1031 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1032 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1034 r.in.handle = &user_handle;
1035 r.in.lm_present = 1;
1036 r.in.old_lm_crypted = &hash1;
1037 r.in.new_lm_crypted = &hash2;
1038 r.in.nt_present = 1;
1039 r.in.old_nt_crypted = &hash3;
1040 r.in.new_nt_crypted = &hash4;
1041 r.in.cross1_present = 1;
1042 r.in.nt_cross = &hash5;
1043 r.in.cross2_present = 1;
1044 r.in.lm_cross = &hash6;
1046 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1047 if (!NT_STATUS_IS_OK(status)) {
1048 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1052 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1060 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1061 const char *acct_name,
1062 struct policy_handle *handle, char **password)
1065 struct samr_ChangePasswordUser r;
1067 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1068 struct policy_handle user_handle;
1070 uint8_t old_nt_hash[16], new_nt_hash[16];
1071 uint8_t old_lm_hash[16], new_lm_hash[16];
1072 BOOL changed = True;
1075 struct samr_GetUserPwInfo pwp;
1076 int policy_min_pw_len = 0;
1078 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1079 if (!NT_STATUS_IS_OK(status)) {
1082 pwp.in.user_handle = &user_handle;
1084 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1085 if (NT_STATUS_IS_OK(status)) {
1086 policy_min_pw_len = pwp.out.info.min_password_length;
1088 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1090 printf("Testing ChangePasswordUser\n");
1093 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1097 oldpass = *password;
1099 E_md4hash(oldpass, old_nt_hash);
1100 E_md4hash(newpass, new_nt_hash);
1101 E_deshash(oldpass, old_lm_hash);
1102 E_deshash(newpass, new_lm_hash);
1104 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1105 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1106 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1107 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1108 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1109 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1111 r.in.user_handle = &user_handle;
1112 r.in.lm_present = 1;
1113 r.in.old_lm_crypted = &hash1;
1114 r.in.new_lm_crypted = &hash2;
1115 r.in.nt_present = 1;
1116 r.in.old_nt_crypted = &hash3;
1117 r.in.new_nt_crypted = &hash4;
1118 r.in.cross1_present = 1;
1119 r.in.nt_cross = &hash5;
1120 r.in.cross2_present = 0;
1121 r.in.lm_cross = NULL;
1123 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1124 if (!NT_STATUS_EQUAL(status, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED)) {
1125 printf("ChangePasswordUser failed: expected NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1130 r.in.user_handle = &user_handle;
1131 r.in.lm_present = 1;
1132 r.in.old_lm_crypted = &hash1;
1133 r.in.new_lm_crypted = &hash2;
1134 r.in.nt_present = 1;
1135 r.in.old_nt_crypted = &hash3;
1136 r.in.new_nt_crypted = &hash4;
1137 r.in.cross1_present = 0;
1138 r.in.nt_cross = NULL;
1139 r.in.cross2_present = 1;
1140 r.in.lm_cross = &hash6;
1142 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1143 if (!NT_STATUS_EQUAL(status, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED)) {
1144 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1148 r.in.user_handle = &user_handle;
1149 r.in.lm_present = 1;
1150 /* Break the LM hash */
1152 r.in.old_lm_crypted = &hash1;
1153 r.in.new_lm_crypted = &hash2;
1154 r.in.nt_present = 1;
1155 r.in.old_nt_crypted = &hash3;
1156 r.in.new_nt_crypted = &hash4;
1157 r.in.cross1_present = 1;
1158 r.in.nt_cross = &hash5;
1159 r.in.cross2_present = 1;
1160 r.in.lm_cross = &hash6;
1162 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1163 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1164 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1168 /* Unbreak the LM hash */
1171 r.in.user_handle = &user_handle;
1172 r.in.lm_present = 1;
1173 r.in.old_lm_crypted = &hash1;
1174 r.in.new_lm_crypted = &hash2;
1175 /* Break the NT hash */
1177 r.in.nt_present = 1;
1178 r.in.old_nt_crypted = &hash3;
1179 r.in.new_nt_crypted = &hash4;
1180 r.in.cross1_present = 1;
1181 r.in.nt_cross = &hash5;
1182 r.in.cross2_present = 1;
1183 r.in.lm_cross = &hash6;
1185 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1186 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1187 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1191 /* Unbreak the NT hash */
1194 r.in.user_handle = &user_handle;
1195 r.in.lm_present = 1;
1196 r.in.old_lm_crypted = &hash1;
1197 r.in.new_lm_crypted = &hash2;
1198 r.in.nt_present = 1;
1199 r.in.old_nt_crypted = &hash3;
1200 r.in.new_nt_crypted = &hash4;
1201 r.in.cross1_present = 1;
1202 r.in.nt_cross = &hash5;
1203 r.in.cross2_present = 1;
1204 /* Break the LM cross */
1206 r.in.lm_cross = &hash6;
1208 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1209 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1210 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1214 /* Unbreak the LM cross */
1217 r.in.user_handle = &user_handle;
1218 r.in.lm_present = 1;
1219 r.in.old_lm_crypted = &hash1;
1220 r.in.new_lm_crypted = &hash2;
1221 r.in.nt_present = 1;
1222 r.in.old_nt_crypted = &hash3;
1223 r.in.new_nt_crypted = &hash4;
1224 r.in.cross1_present = 1;
1225 /* Break the NT cross */
1227 r.in.nt_cross = &hash5;
1228 r.in.cross2_present = 1;
1229 r.in.lm_cross = &hash6;
1231 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1232 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1233 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1237 /* Unbreak the NT cross */
1240 /* Reset the hashes to not broken values */
1241 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1242 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1243 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1244 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1245 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1246 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1248 r.in.user_handle = &user_handle;
1249 r.in.lm_present = 1;
1250 r.in.old_lm_crypted = &hash1;
1251 r.in.new_lm_crypted = &hash2;
1252 r.in.nt_present = 1;
1253 r.in.old_nt_crypted = &hash3;
1254 r.in.new_nt_crypted = &hash4;
1255 r.in.cross1_present = 1;
1256 r.in.nt_cross = &hash5;
1257 r.in.cross2_present = 1;
1258 r.in.lm_cross = &hash6;
1260 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1261 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1262 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1263 } else if (!NT_STATUS_IS_OK(status)) {
1264 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1268 *password = newpass;
1271 r.in.user_handle = &user_handle;
1272 r.in.lm_present = 1;
1273 r.in.old_lm_crypted = &hash1;
1274 r.in.new_lm_crypted = &hash2;
1275 r.in.nt_present = 1;
1276 r.in.old_nt_crypted = &hash3;
1277 r.in.new_nt_crypted = &hash4;
1278 r.in.cross1_present = 1;
1279 r.in.nt_cross = &hash5;
1280 r.in.cross2_present = 1;
1281 r.in.lm_cross = &hash6;
1284 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1285 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1286 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1291 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1299 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1300 const char *acct_name,
1301 struct policy_handle *handle, char **password)
1304 struct samr_OemChangePasswordUser2 r;
1306 struct samr_Password lm_verifier;
1307 struct samr_CryptPassword lm_pass;
1308 struct lsa_AsciiString server, account, account_bad;
1311 uint8_t old_lm_hash[16], new_lm_hash[16];
1313 struct samr_GetDomPwInfo dom_pw_info;
1314 int policy_min_pw_len = 0;
1316 struct lsa_String domain_name;
1318 domain_name.string = "";
1319 dom_pw_info.in.domain_name = &domain_name;
1321 printf("Testing OemChangePasswordUser2\n");
1324 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1328 oldpass = *password;
1330 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1331 if (NT_STATUS_IS_OK(status)) {
1332 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1335 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1337 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1338 account.string = acct_name;
1340 E_deshash(oldpass, old_lm_hash);
1341 E_deshash(newpass, new_lm_hash);
1343 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1344 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1345 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1347 r.in.server = &server;
1348 r.in.account = &account;
1349 r.in.password = &lm_pass;
1350 r.in.hash = &lm_verifier;
1352 /* Break the verification */
1353 lm_verifier.hash[0]++;
1355 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1357 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1358 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1359 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1364 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1365 /* Break the old password */
1367 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1368 /* unbreak it for the next operation */
1370 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1372 r.in.server = &server;
1373 r.in.account = &account;
1374 r.in.password = &lm_pass;
1375 r.in.hash = &lm_verifier;
1377 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1379 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1380 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1381 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1386 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1387 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1389 r.in.server = &server;
1390 r.in.account = &account;
1391 r.in.password = &lm_pass;
1394 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1396 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1397 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1398 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1403 /* This shouldn't be a valid name */
1404 account_bad.string = TEST_ACCOUNT_NAME "XX";
1405 r.in.account = &account_bad;
1407 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1409 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1410 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1415 E_deshash(oldpass, old_lm_hash);
1416 E_deshash(newpass, new_lm_hash);
1418 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1419 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1420 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1422 r.in.server = &server;
1423 r.in.account = &account;
1424 r.in.password = &lm_pass;
1425 r.in.hash = &lm_verifier;
1427 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1428 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1429 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1430 } else if (!NT_STATUS_IS_OK(status)) {
1431 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1434 *password = newpass;
1441 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1442 const char *acct_name,
1443 struct policy_handle *handle, char **password)
1446 struct samr_ChangePasswordUser2 r;
1448 struct lsa_String server, account;
1449 struct samr_CryptPassword nt_pass, lm_pass;
1450 struct samr_Password nt_verifier, lm_verifier;
1453 uint8_t old_nt_hash[16], new_nt_hash[16];
1454 uint8_t old_lm_hash[16], new_lm_hash[16];
1456 struct samr_GetDomPwInfo dom_pw_info;
1457 int policy_min_pw_len = 0;
1459 struct lsa_String domain_name;
1462 domain_name.string = "";
1463 dom_pw_info.in.domain_name = &domain_name;
1465 printf("Testing ChangePasswordUser2\n");
1468 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1471 oldpass = *password;
1473 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1474 if (NT_STATUS_IS_OK(status)) {
1475 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1478 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1480 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1481 init_lsa_String(&account, acct_name);
1483 E_md4hash(oldpass, old_nt_hash);
1484 E_md4hash(newpass, new_nt_hash);
1486 E_deshash(oldpass, old_lm_hash);
1487 E_deshash(newpass, new_lm_hash);
1489 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1490 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1491 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1493 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1494 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1495 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1497 r.in.server = &server;
1498 r.in.account = &account;
1499 r.in.nt_password = &nt_pass;
1500 r.in.nt_verifier = &nt_verifier;
1502 r.in.lm_password = &lm_pass;
1503 r.in.lm_verifier = &lm_verifier;
1505 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1506 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1507 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1508 } else if (!NT_STATUS_IS_OK(status)) {
1509 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1512 *password = newpass;
1519 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1520 const char *account_string,
1521 int policy_min_pw_len,
1523 const char *newpass,
1524 NTTIME last_password_change,
1525 BOOL handle_reject_reason)
1528 struct samr_ChangePasswordUser3 r;
1530 struct lsa_String server, account, account_bad;
1531 struct samr_CryptPassword nt_pass, lm_pass;
1532 struct samr_Password nt_verifier, lm_verifier;
1534 uint8_t old_nt_hash[16], new_nt_hash[16];
1535 uint8_t old_lm_hash[16], new_lm_hash[16];
1538 printf("Testing ChangePasswordUser3\n");
1540 if (newpass == NULL) {
1542 if (policy_min_pw_len == 0) {
1543 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1545 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1547 } while (check_password_quality(newpass) == False);
1549 printf("Using password '%s'\n", newpass);
1553 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1557 oldpass = *password;
1558 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1559 init_lsa_String(&account, account_string);
1561 E_md4hash(oldpass, old_nt_hash);
1562 E_md4hash(newpass, new_nt_hash);
1564 E_deshash(oldpass, old_lm_hash);
1565 E_deshash(newpass, new_lm_hash);
1567 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1568 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1569 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1571 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1572 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1573 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1575 /* Break the verification */
1576 nt_verifier.hash[0]++;
1578 r.in.server = &server;
1579 r.in.account = &account;
1580 r.in.nt_password = &nt_pass;
1581 r.in.nt_verifier = &nt_verifier;
1583 r.in.lm_password = &lm_pass;
1584 r.in.lm_verifier = &lm_verifier;
1585 r.in.password3 = NULL;
1587 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1588 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1589 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1590 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1595 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1596 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1597 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1599 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1600 /* Break the NT hash */
1602 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1603 /* Unbreak it again */
1605 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1607 r.in.server = &server;
1608 r.in.account = &account;
1609 r.in.nt_password = &nt_pass;
1610 r.in.nt_verifier = &nt_verifier;
1612 r.in.lm_password = &lm_pass;
1613 r.in.lm_verifier = &lm_verifier;
1614 r.in.password3 = NULL;
1616 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1617 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1618 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1619 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1624 /* This shouldn't be a valid name */
1625 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1627 r.in.account = &account_bad;
1628 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1629 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1630 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1635 E_md4hash(oldpass, old_nt_hash);
1636 E_md4hash(newpass, new_nt_hash);
1638 E_deshash(oldpass, old_lm_hash);
1639 E_deshash(newpass, new_lm_hash);
1641 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1642 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1643 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1645 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1646 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1647 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1649 r.in.server = &server;
1650 r.in.account = &account;
1651 r.in.nt_password = &nt_pass;
1652 r.in.nt_verifier = &nt_verifier;
1654 r.in.lm_password = &lm_pass;
1655 r.in.lm_verifier = &lm_verifier;
1656 r.in.password3 = NULL;
1658 unix_to_nt_time(&t, time(NULL));
1660 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1662 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1663 r.out.dominfo && r.out.reject && handle_reject_reason) {
1665 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1667 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1668 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1669 SAMR_REJECT_OTHER, r.out.reject->reason);
1674 /* We tested the order of precendence which is as follows:
1683 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1684 (last_password_change + r.out.dominfo->min_password_age > t)) {
1686 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1687 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1688 SAMR_REJECT_OTHER, r.out.reject->reason);
1692 } else if ((r.out.dominfo->min_password_length > 0) &&
1693 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1695 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1696 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1697 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1701 } else if ((r.out.dominfo->password_history_length > 0) &&
1702 strequal(oldpass, newpass)) {
1704 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1705 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1706 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1709 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1711 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1712 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1713 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1719 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1720 /* retry with adjusted size */
1721 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1722 r.out.dominfo->min_password_length,
1723 password, NULL, 0, False);
1727 } else if (!NT_STATUS_IS_OK(status)) {
1728 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1731 *password = talloc_strdup(mem_ctx, newpass);
1738 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1739 struct policy_handle *alias_handle)
1741 struct samr_GetMembersInAlias r;
1742 struct lsa_SidArray sids;
1746 printf("Testing GetMembersInAlias\n");
1748 r.in.alias_handle = alias_handle;
1751 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1752 if (!NT_STATUS_IS_OK(status)) {
1753 printf("GetMembersInAlias failed - %s\n",
1761 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1762 struct policy_handle *alias_handle,
1763 const struct dom_sid *domain_sid)
1765 struct samr_AddAliasMember r;
1766 struct samr_DeleteAliasMember d;
1769 struct dom_sid *sid;
1771 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1773 printf("testing AddAliasMember\n");
1774 r.in.alias_handle = alias_handle;
1777 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1778 if (!NT_STATUS_IS_OK(status)) {
1779 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1783 d.in.alias_handle = alias_handle;
1786 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1787 if (!NT_STATUS_IS_OK(status)) {
1788 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1795 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1796 struct policy_handle *alias_handle)
1798 struct samr_AddMultipleMembersToAlias a;
1799 struct samr_RemoveMultipleMembersFromAlias r;
1802 struct lsa_SidArray sids;
1804 printf("testing AddMultipleMembersToAlias\n");
1805 a.in.alias_handle = alias_handle;
1809 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1811 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1812 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1813 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1815 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1816 if (!NT_STATUS_IS_OK(status)) {
1817 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1822 printf("testing RemoveMultipleMembersFromAlias\n");
1823 r.in.alias_handle = alias_handle;
1826 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1827 if (!NT_STATUS_IS_OK(status)) {
1828 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1832 /* strange! removing twice doesn't give any error */
1833 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1834 if (!NT_STATUS_IS_OK(status)) {
1835 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1839 /* but removing an alias that isn't there does */
1840 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1842 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1843 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1844 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1851 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1852 struct policy_handle *user_handle)
1854 struct samr_TestPrivateFunctionsUser r;
1858 printf("Testing TestPrivateFunctionsUser\n");
1860 r.in.user_handle = user_handle;
1862 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1863 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1864 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1872 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1873 struct policy_handle *user_handle,
1874 struct policy_handle *domain_handle,
1875 uint32_t base_acct_flags,
1876 const char *base_acct_name, enum torture_samr_choice which_ops)
1878 TALLOC_CTX *user_ctx;
1879 char *password = NULL;
1883 const uint32_t password_fields[] = {
1884 SAMR_FIELD_PASSWORD,
1885 SAMR_FIELD_PASSWORD2,
1886 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1890 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1891 switch (which_ops) {
1892 case TORTURE_SAMR_USER_ATTRIBUTES:
1893 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1897 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1901 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1905 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
1910 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
1914 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
1918 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1922 case TORTURE_SAMR_PASSWORDS:
1923 for (i = 0; password_fields[i]; i++) {
1924 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1928 /* check it was set right */
1929 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
1934 for (i = 0; password_fields[i]; i++) {
1935 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1939 /* check it was set right */
1940 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
1945 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1949 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
1953 case TORTURE_SAMR_OTHER:
1954 /* We just need the account to exist */
1957 talloc_free(user_ctx);
1961 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1962 struct policy_handle *alias_handle,
1963 const struct dom_sid *domain_sid)
1967 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1971 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1975 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1979 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1983 if (lp_parm_bool(-1, "torture", "samba4", False)) {
1984 printf("skipping MultipleMembers Alias tests against Samba4\n");
1988 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1996 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1997 struct policy_handle *user_handle)
1999 struct samr_DeleteUser d;
2002 printf("Testing DeleteUser\n");
2004 d.in.user_handle = user_handle;
2005 d.out.user_handle = user_handle;
2007 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2008 if (!NT_STATUS_IS_OK(status)) {
2009 printf("DeleteUser failed - %s\n", nt_errstr(status));
2016 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2017 struct policy_handle *handle, const char *name)
2020 struct samr_DeleteUser d;
2021 struct policy_handle user_handle;
2024 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2025 if (!NT_STATUS_IS_OK(status)) {
2029 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2030 if (!NT_STATUS_IS_OK(status)) {
2034 d.in.user_handle = &user_handle;
2035 d.out.user_handle = &user_handle;
2036 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2037 if (!NT_STATUS_IS_OK(status)) {
2044 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2049 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2050 struct policy_handle *handle, const char *name)
2053 struct samr_OpenGroup r;
2054 struct samr_DeleteDomainGroup d;
2055 struct policy_handle group_handle;
2058 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2059 if (!NT_STATUS_IS_OK(status)) {
2063 r.in.domain_handle = handle;
2064 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2066 r.out.group_handle = &group_handle;
2067 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2068 if (!NT_STATUS_IS_OK(status)) {
2072 d.in.group_handle = &group_handle;
2073 d.out.group_handle = &group_handle;
2074 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2075 if (!NT_STATUS_IS_OK(status)) {
2082 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2087 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2088 struct policy_handle *domain_handle, const char *name)
2091 struct samr_OpenAlias r;
2092 struct samr_DeleteDomAlias d;
2093 struct policy_handle alias_handle;
2096 printf("testing DeleteAlias_byname\n");
2098 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2099 if (!NT_STATUS_IS_OK(status)) {
2103 r.in.domain_handle = domain_handle;
2104 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2106 r.out.alias_handle = &alias_handle;
2107 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2108 if (!NT_STATUS_IS_OK(status)) {
2112 d.in.alias_handle = &alias_handle;
2113 d.out.alias_handle = &alias_handle;
2114 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2115 if (!NT_STATUS_IS_OK(status)) {
2122 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2126 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2127 struct policy_handle *alias_handle)
2129 struct samr_DeleteDomAlias d;
2132 printf("Testing DeleteAlias\n");
2134 d.in.alias_handle = alias_handle;
2135 d.out.alias_handle = alias_handle;
2137 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2138 if (!NT_STATUS_IS_OK(status)) {
2139 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2146 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2147 struct policy_handle *domain_handle,
2148 struct policy_handle *alias_handle,
2149 const struct dom_sid *domain_sid)
2152 struct samr_CreateDomAlias r;
2153 struct lsa_String name;
2157 init_lsa_String(&name, TEST_ALIASNAME);
2158 r.in.domain_handle = domain_handle;
2159 r.in.alias_name = &name;
2160 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2161 r.out.alias_handle = alias_handle;
2164 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2166 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2168 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2169 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2173 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2174 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2177 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 printf("CreateAlias failed - %s\n", nt_errstr(status));
2185 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2192 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2193 const char *acct_name,
2194 struct policy_handle *domain_handle, char **password)
2202 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2206 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2210 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2214 /* test what happens when setting the old password again */
2215 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2220 char simple_pass[9];
2221 char *v = generate_random_str(mem_ctx, 1);
2223 ZERO_STRUCT(simple_pass);
2224 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2226 /* test what happens when picking a simple password */
2227 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2232 /* set samr_SetDomainInfo level 1 with min_length 5 */
2234 struct samr_QueryDomainInfo r;
2235 struct samr_SetDomainInfo s;
2236 uint16_t len_old, len;
2237 uint32_t pwd_prop_old;
2242 r.in.domain_handle = domain_handle;
2245 printf("testing samr_QueryDomainInfo level 1\n");
2246 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2247 if (!NT_STATUS_IS_OK(status)) {
2251 s.in.domain_handle = domain_handle;
2253 s.in.info = r.out.info;
2255 /* remember the old min length, so we can reset it */
2256 len_old = s.in.info->info1.min_password_length;
2257 s.in.info->info1.min_password_length = len;
2258 pwd_prop_old = s.in.info->info1.password_properties;
2259 /* turn off password complexity checks for this test */
2260 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2262 printf("testing samr_SetDomainInfo level 1\n");
2263 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2264 if (!NT_STATUS_IS_OK(status)) {
2268 printf("calling test_ChangePasswordUser3 with too short password\n");
2270 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2274 s.in.info->info1.min_password_length = len_old;
2275 s.in.info->info1.password_properties = pwd_prop_old;
2277 printf("testing samr_SetDomainInfo level 1\n");
2278 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2279 if (!NT_STATUS_IS_OK(status)) {
2287 struct samr_OpenUser r;
2288 struct samr_QueryUserInfo q;
2289 struct samr_LookupNames n;
2290 struct policy_handle user_handle;
2292 n.in.domain_handle = domain_handle;
2294 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2295 n.in.names[0].string = acct_name;
2297 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2298 if (!NT_STATUS_IS_OK(status)) {
2299 printf("LookupNames failed - %s\n", nt_errstr(status));
2303 r.in.domain_handle = domain_handle;
2304 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2305 r.in.rid = n.out.rids.ids[0];
2306 r.out.user_handle = &user_handle;
2308 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2309 if (!NT_STATUS_IS_OK(status)) {
2310 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2314 q.in.user_handle = &user_handle;
2317 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2318 if (!NT_STATUS_IS_OK(status)) {
2319 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2323 printf("calling test_ChangePasswordUser3 with too early password change\n");
2325 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2326 q.out.info->info5.last_password_change, True)) {
2331 /* we change passwords twice - this has the effect of verifying
2332 they were changed correctly for the final call */
2333 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2337 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2344 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2345 struct policy_handle *domain_handle,
2346 struct policy_handle *user_handle_out,
2347 enum torture_samr_choice which_ops)
2350 TALLOC_CTX *user_ctx;
2353 struct samr_CreateUser r;
2354 struct samr_QueryUserInfo q;
2355 struct samr_DeleteUser d;
2358 /* This call creates a 'normal' account - check that it really does */
2359 const uint32_t acct_flags = ACB_NORMAL;
2360 struct lsa_String name;
2363 struct policy_handle user_handle;
2364 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2365 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2367 r.in.domain_handle = domain_handle;
2368 r.in.account_name = &name;
2369 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2370 r.out.user_handle = &user_handle;
2373 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2375 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2377 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2378 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2379 talloc_free(user_ctx);
2383 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2384 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2385 talloc_free(user_ctx);
2388 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2390 if (!NT_STATUS_IS_OK(status)) {
2391 talloc_free(user_ctx);
2392 printf("CreateUser failed - %s\n", nt_errstr(status));
2395 q.in.user_handle = &user_handle;
2398 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2399 if (!NT_STATUS_IS_OK(status)) {
2400 printf("QueryUserInfo level %u failed - %s\n",
2401 q.in.level, nt_errstr(status));
2404 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2405 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2406 q.out.info->info16.acct_flags,
2412 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2413 acct_flags, name.string, which_ops)) {
2417 if (user_handle_out) {
2418 *user_handle_out = user_handle;
2420 printf("Testing DeleteUser (createuser test)\n");
2422 d.in.user_handle = &user_handle;
2423 d.out.user_handle = &user_handle;
2425 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2426 if (!NT_STATUS_IS_OK(status)) {
2427 printf("DeleteUser failed - %s\n", nt_errstr(status));
2434 talloc_free(user_ctx);
2440 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2441 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2444 struct samr_CreateUser2 r;
2445 struct samr_QueryUserInfo q;
2446 struct samr_DeleteUser d;
2447 struct policy_handle user_handle;
2449 struct lsa_String name;
2454 uint32_t acct_flags;
2455 const char *account_name;
2457 } account_types[] = {
2458 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2459 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2460 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2461 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2462 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2463 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2464 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2465 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2466 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2467 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2468 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2469 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2470 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2471 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2472 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2475 for (i = 0; account_types[i].account_name; i++) {
2476 TALLOC_CTX *user_ctx;
2477 uint32_t acct_flags = account_types[i].acct_flags;
2478 uint32_t access_granted;
2479 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2480 init_lsa_String(&name, account_types[i].account_name);
2482 r.in.domain_handle = domain_handle;
2483 r.in.account_name = &name;
2484 r.in.acct_flags = acct_flags;
2485 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2486 r.out.user_handle = &user_handle;
2487 r.out.access_granted = &access_granted;
2490 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2492 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2494 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2495 talloc_free(user_ctx);
2496 printf("Server refused create of '%s'\n", r.in.account_name->string);
2499 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2500 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2501 talloc_free(user_ctx);
2505 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2508 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2509 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2510 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2514 if (NT_STATUS_IS_OK(status)) {
2515 q.in.user_handle = &user_handle;
2518 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2519 if (!NT_STATUS_IS_OK(status)) {
2520 printf("QueryUserInfo level %u failed - %s\n",
2521 q.in.level, nt_errstr(status));
2524 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2525 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2526 q.out.info->info5.acct_flags,
2530 switch (acct_flags) {
2532 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2533 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2534 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2539 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2540 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2541 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2546 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2547 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2548 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2555 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2556 acct_flags, name.string, which_ops)) {
2560 printf("Testing DeleteUser (createuser2 test)\n");
2562 d.in.user_handle = &user_handle;
2563 d.out.user_handle = &user_handle;
2565 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2566 if (!NT_STATUS_IS_OK(status)) {
2567 printf("DeleteUser failed - %s\n", nt_errstr(status));
2571 talloc_free(user_ctx);
2577 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2578 struct policy_handle *handle)
2581 struct samr_QueryAliasInfo r;
2582 uint16_t levels[] = {1, 2, 3};
2586 for (i=0;i<ARRAY_SIZE(levels);i++) {
2587 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2589 r.in.alias_handle = handle;
2590 r.in.level = levels[i];
2592 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2593 if (!NT_STATUS_IS_OK(status)) {
2594 printf("QueryAliasInfo level %u failed - %s\n",
2595 levels[i], nt_errstr(status));
2603 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2604 struct policy_handle *handle)
2607 struct samr_QueryGroupInfo r;
2608 uint16_t levels[] = {1, 2, 3, 4, 5};
2612 for (i=0;i<ARRAY_SIZE(levels);i++) {
2613 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2615 r.in.group_handle = handle;
2616 r.in.level = levels[i];
2618 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2619 if (!NT_STATUS_IS_OK(status)) {
2620 printf("QueryGroupInfo level %u failed - %s\n",
2621 levels[i], nt_errstr(status));
2629 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2630 struct policy_handle *handle)
2633 struct samr_QueryGroupMember r;
2636 printf("Testing QueryGroupMember\n");
2638 r.in.group_handle = handle;
2640 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2641 if (!NT_STATUS_IS_OK(status)) {
2642 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2650 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2651 struct policy_handle *handle)
2654 struct samr_QueryGroupInfo r;
2655 struct samr_SetGroupInfo s;
2656 uint16_t levels[] = {1, 2, 3, 4};
2657 uint16_t set_ok[] = {0, 1, 1, 1};
2661 for (i=0;i<ARRAY_SIZE(levels);i++) {
2662 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2664 r.in.group_handle = handle;
2665 r.in.level = levels[i];
2667 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2668 if (!NT_STATUS_IS_OK(status)) {
2669 printf("QueryGroupInfo level %u failed - %s\n",
2670 levels[i], nt_errstr(status));
2674 printf("Testing SetGroupInfo level %u\n", levels[i]);
2676 s.in.group_handle = handle;
2677 s.in.level = levels[i];
2678 s.in.info = r.out.info;
2681 /* disabled this, as it changes the name only from the point of view of samr,
2682 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2683 the name is still reserved, so creating the old name fails, but deleting by the old name
2685 if (s.in.level == 2) {
2686 init_lsa_String(&s.in.info->string, "NewName");
2690 if (s.in.level == 4) {
2691 init_lsa_String(&s.in.info->description, "test description");
2694 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2696 if (!NT_STATUS_IS_OK(status)) {
2697 printf("SetGroupInfo level %u failed - %s\n",
2698 r.in.level, nt_errstr(status));
2703 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2704 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2705 r.in.level, nt_errstr(status));
2715 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2716 struct policy_handle *handle)
2719 struct samr_QueryUserInfo r;
2720 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2721 11, 12, 13, 14, 16, 17, 20, 21};
2725 for (i=0;i<ARRAY_SIZE(levels);i++) {
2726 printf("Testing QueryUserInfo level %u\n", levels[i]);
2728 r.in.user_handle = handle;
2729 r.in.level = levels[i];
2731 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2732 if (!NT_STATUS_IS_OK(status)) {
2733 printf("QueryUserInfo level %u failed - %s\n",
2734 levels[i], nt_errstr(status));
2742 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2743 struct policy_handle *handle)
2746 struct samr_QueryUserInfo2 r;
2747 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2748 11, 12, 13, 14, 16, 17, 20, 21};
2752 for (i=0;i<ARRAY_SIZE(levels);i++) {
2753 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2755 r.in.user_handle = handle;
2756 r.in.level = levels[i];
2758 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2759 if (!NT_STATUS_IS_OK(status)) {
2760 printf("QueryUserInfo2 level %u failed - %s\n",
2761 levels[i], nt_errstr(status));
2769 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2770 struct policy_handle *handle, uint32_t rid)
2773 struct samr_OpenUser r;
2774 struct policy_handle user_handle;
2777 printf("Testing OpenUser(%u)\n", rid);
2779 r.in.domain_handle = handle;
2780 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2782 r.out.user_handle = &user_handle;
2784 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2785 if (!NT_STATUS_IS_OK(status)) {
2786 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2790 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2794 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2798 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2802 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2806 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2810 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2817 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2818 struct policy_handle *handle, uint32_t rid)
2821 struct samr_OpenGroup r;
2822 struct policy_handle group_handle;
2825 printf("Testing OpenGroup(%u)\n", rid);
2827 r.in.domain_handle = handle;
2828 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2830 r.out.group_handle = &group_handle;
2832 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2833 if (!NT_STATUS_IS_OK(status)) {
2834 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2838 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2842 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2846 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2850 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2857 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2858 struct policy_handle *handle, uint32_t rid)
2861 struct samr_OpenAlias r;
2862 struct policy_handle alias_handle;
2865 printf("Testing OpenAlias(%u)\n", rid);
2867 r.in.domain_handle = handle;
2868 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2870 r.out.alias_handle = &alias_handle;
2872 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2873 if (!NT_STATUS_IS_OK(status)) {
2874 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2878 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2882 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2886 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2890 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2897 static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2898 struct policy_handle *handle, uint32_t rid,
2899 uint32_t acct_flag_mask)
2902 struct samr_OpenUser r;
2903 struct samr_QueryUserInfo q;
2904 struct policy_handle user_handle;
2907 printf("Testing OpenUser(%u)\n", rid);
2909 r.in.domain_handle = handle;
2910 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2912 r.out.user_handle = &user_handle;
2914 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2915 if (!NT_STATUS_IS_OK(status)) {
2916 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2920 q.in.user_handle = &user_handle;
2923 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2924 if (!NT_STATUS_IS_OK(status)) {
2925 printf("QueryUserInfo level 16 failed - %s\n",
2929 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
2930 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
2931 acct_flag_mask, q.out.info->info16.acct_flags, rid);
2936 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2943 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2944 struct policy_handle *handle)
2946 NTSTATUS status = STATUS_MORE_ENTRIES;
2947 struct samr_EnumDomainUsers r;
2948 uint32_t mask, resume_handle=0;
2951 struct samr_LookupNames n;
2952 struct samr_LookupRids lr ;
2953 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
2954 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
2955 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
2958 printf("Testing EnumDomainUsers\n");
2960 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
2961 r.in.domain_handle = handle;
2962 r.in.resume_handle = &resume_handle;
2963 r.in.acct_flags = mask = masks[mask_idx];
2964 r.in.max_size = (uint32_t)-1;
2965 r.out.resume_handle = &resume_handle;
2967 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2968 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2969 !NT_STATUS_IS_OK(status)) {
2970 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2975 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
2979 if (r.out.sam->count == 0) {
2983 for (i=0;i<r.out.sam->count;i++) {
2985 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
2988 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2994 printf("Testing LookupNames\n");
2995 n.in.domain_handle = handle;
2996 n.in.num_names = r.out.sam->count;
2997 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2998 for (i=0;i<r.out.sam->count;i++) {
2999 n.in.names[i].string = r.out.sam->entries[i].name.string;
3001 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3002 if (!NT_STATUS_IS_OK(status)) {
3003 printf("LookupNames failed - %s\n", nt_errstr(status));
3008 printf("Testing LookupRids\n");
3009 lr.in.domain_handle = handle;
3010 lr.in.num_rids = r.out.sam->count;
3011 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3012 for (i=0;i<r.out.sam->count;i++) {
3013 lr.in.rids[i] = r.out.sam->entries[i].idx;
3015 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3016 if (!NT_STATUS_IS_OK(status)) {
3017 printf("LookupRids failed - %s\n", nt_errstr(status));
3025 try blasting the server with a bunch of sync requests
3027 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3028 struct policy_handle *handle)
3031 struct samr_EnumDomainUsers r;
3032 uint32_t resume_handle=0;
3034 #define ASYNC_COUNT 100
3035 struct rpc_request *req[ASYNC_COUNT];
3037 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
3038 printf("samr async test disabled - enable dangerous tests to use\n");
3042 printf("Testing EnumDomainUsers_async\n");
3044 r.in.domain_handle = handle;
3045 r.in.resume_handle = &resume_handle;
3046 r.in.acct_flags = 0;
3047 r.in.max_size = (uint32_t)-1;
3048 r.out.resume_handle = &resume_handle;
3050 for (i=0;i<ASYNC_COUNT;i++) {
3051 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
3054 for (i=0;i<ASYNC_COUNT;i++) {
3055 status = dcerpc_ndr_request_recv(req[i]);
3056 if (!NT_STATUS_IS_OK(status)) {
3057 printf("EnumDomainUsers[%d] failed - %s\n",
3058 i, nt_errstr(status));
3063 printf("%d async requests OK\n", i);
3068 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3069 struct policy_handle *handle)
3072 struct samr_EnumDomainGroups r;
3073 uint32_t resume_handle=0;
3077 printf("Testing EnumDomainGroups\n");
3079 r.in.domain_handle = handle;
3080 r.in.resume_handle = &resume_handle;
3081 r.in.max_size = (uint32_t)-1;
3082 r.out.resume_handle = &resume_handle;
3084 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3085 if (!NT_STATUS_IS_OK(status)) {
3086 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3094 for (i=0;i<r.out.sam->count;i++) {
3095 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3103 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3104 struct policy_handle *handle)
3107 struct samr_EnumDomainAliases r;
3108 uint32_t resume_handle=0;
3112 printf("Testing EnumDomainAliases\n");
3114 r.in.domain_handle = handle;
3115 r.in.resume_handle = &resume_handle;
3116 r.in.acct_flags = (uint32_t)-1;
3117 r.out.resume_handle = &resume_handle;
3119 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3120 if (!NT_STATUS_IS_OK(status)) {
3121 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3129 for (i=0;i<r.out.sam->count;i++) {
3130 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3138 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3139 struct policy_handle *handle)
3142 struct samr_GetDisplayEnumerationIndex r;
3144 uint16_t levels[] = {1, 2, 3, 4, 5};
3145 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3148 for (i=0;i<ARRAY_SIZE(levels);i++) {
3149 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3151 r.in.domain_handle = handle;
3152 r.in.level = levels[i];
3153 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3155 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3158 !NT_STATUS_IS_OK(status) &&
3159 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3160 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3161 levels[i], nt_errstr(status));
3165 init_lsa_String(&r.in.name, "zzzzzzzz");
3167 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3169 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3170 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3171 levels[i], nt_errstr(status));
3179 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3180 struct policy_handle *handle)
3183 struct samr_GetDisplayEnumerationIndex2 r;
3185 uint16_t levels[] = {1, 2, 3, 4, 5};
3186 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3189 for (i=0;i<ARRAY_SIZE(levels);i++) {
3190 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3192 r.in.domain_handle = handle;
3193 r.in.level = levels[i];
3194 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3196 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3198 !NT_STATUS_IS_OK(status) &&
3199 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3200 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3201 levels[i], nt_errstr(status));
3205 init_lsa_String(&r.in.name, "zzzzzzzz");
3207 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3208 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3209 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3210 levels[i], nt_errstr(status));
3218 #define STRING_EQUAL_QUERY(s1, s2, user) \
3219 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3220 /* odd, but valid */ \
3221 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3222 printf("%s mismatch for %s: %s != %s (%s)\n", \
3223 #s1, user.string, s1.string, s2.string, __location__); \
3226 #define INT_EQUAL_QUERY(s1, s2, user) \
3228 printf("%s mismatch for %s: 0x%x != 0x%x (%s)\n", \
3229 #s1, user.string, (unsigned int)s1, (unsigned int)s2, __location__); \
3233 static BOOL test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3234 struct samr_QueryDisplayInfo *querydisplayinfo,
3235 bool *seen_testuser)
3237 struct samr_OpenUser r;
3238 struct samr_QueryUserInfo q;
3239 struct policy_handle user_handle;
3242 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3243 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3244 for (i = 0; ; i++) {
3245 switch (querydisplayinfo->in.level) {
3247 if (i >= querydisplayinfo->out.info.info1.count) {
3250 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3253 if (i >= querydisplayinfo->out.info.info2.count) {
3256 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3262 /* Not interested in validating just the account name */
3266 r.out.user_handle = &user_handle;
3268 switch (querydisplayinfo->in.level) {
3271 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3272 if (!NT_STATUS_IS_OK(status)) {
3273 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3278 q.in.user_handle = &user_handle;
3280 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3281 if (!NT_STATUS_IS_OK(status)) {
3282 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3286 switch (querydisplayinfo->in.level) {
3288 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3289 *seen_testuser = true;
3291 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3292 q.out.info->info21.full_name, q.out.info->info21.account_name);
3293 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3294 q.out.info->info21.account_name, q.out.info->info21.account_name);
3295 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3296 q.out.info->info21.description, q.out.info->info21.account_name);
3297 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3298 q.out.info->info21.rid, q.out.info->info21.account_name);
3299 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3300 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3304 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3305 q.out.info->info21.account_name, q.out.info->info21.account_name);
3306 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3307 q.out.info->info21.description, q.out.info->info21.account_name);
3308 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3309 q.out.info->info21.rid, q.out.info->info21.account_name);
3310 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3311 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3313 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3314 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3315 q.out.info->info21.account_name.string);
3318 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3319 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3320 q.out.info->info21.account_name.string,
3321 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3322 q.out.info->info21.acct_flags);
3329 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3336 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3337 struct policy_handle *handle)
3340 struct samr_QueryDisplayInfo r;
3341 struct samr_QueryDomainInfo dom_info;
3343 uint16_t levels[] = {1, 2, 3, 4, 5};
3345 bool seen_testuser = false;
3347 for (i=0;i<ARRAY_SIZE(levels);i++) {
3348 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3351 status = STATUS_MORE_ENTRIES;
3352 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3353 r.in.domain_handle = handle;
3354 r.in.level = levels[i];
3355 r.in.max_entries = 2;
3356 r.in.buf_size = (uint32_t)-1;
3358 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3359 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3360 printf("QueryDisplayInfo level %u failed - %s\n",
3361 levels[i], nt_errstr(status));
3364 switch (r.in.level) {
3366 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3369 r.in.start_idx += r.out.info.info1.count;
3372 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3375 r.in.start_idx += r.out.info.info2.count;
3378 r.in.start_idx += r.out.info.info3.count;
3381 r.in.start_idx += r.out.info.info4.count;
3384 r.in.start_idx += r.out.info.info5.count;
3388 dom_info.in.domain_handle = handle;
3389 dom_info.in.level = 2;
3390 /* Check number of users returned is correct */
3391 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3392 if (!NT_STATUS_IS_OK(status)) {
3393 printf("QueryDomainInfo level %u failed - %s\n",
3394 r.in.level, nt_errstr(status));
3398 switch (r.in.level) {
3401 if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3402 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3403 r.in.start_idx, dom_info.out.info->info2.num_groups,
3404 dom_info.out.info->info2.domain_name.string);
3407 if (!seen_testuser) {
3408 struct policy_handle user_handle;
3409 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3410 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3411 dom_info.out.info->info2.domain_name.string);
3413 test_samr_handle_Close(p, mem_ctx, &user_handle);
3419 if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3420 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3421 r.in.start_idx, dom_info.out.info->info2.num_groups,
3422 dom_info.out.info->info2.domain_name.string);
3434 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3435 struct policy_handle *handle)
3438 struct samr_QueryDisplayInfo2 r;
3440 uint16_t levels[] = {1, 2, 3, 4, 5};
3443 for (i=0;i<ARRAY_SIZE(levels);i++) {
3444 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3446 r.in.domain_handle = handle;
3447 r.in.level = levels[i];
3449 r.in.max_entries = 1000;
3450 r.in.buf_size = (uint32_t)-1;
3452 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3453 if (!NT_STATUS_IS_OK(status)) {
3454 printf("QueryDisplayInfo2 level %u failed - %s\n",
3455 levels[i], nt_errstr(status));
3463 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3464 struct policy_handle *handle)
3467 struct samr_QueryDisplayInfo3 r;
3469 uint16_t levels[] = {1, 2, 3, 4, 5};
3472 for (i=0;i<ARRAY_SIZE(levels);i++) {
3473 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3475 r.in.domain_handle = handle;
3476 r.in.level = levels[i];
3478 r.in.max_entries = 1000;
3479 r.in.buf_size = (uint32_t)-1;
3481 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3482 if (!NT_STATUS_IS_OK(status)) {
3483 printf("QueryDisplayInfo3 level %u failed - %s\n",
3484 levels[i], nt_errstr(status));
3493 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3494 struct policy_handle *handle)
3497 struct samr_QueryDisplayInfo r;
3500 printf("Testing QueryDisplayInfo continuation\n");
3502 r.in.domain_handle = handle;
3505 r.in.max_entries = 1;
3506 r.in.buf_size = (uint32_t)-1;
3509 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3510 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3511 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3512 printf("expected idx %d but got %d\n",
3514 r.out.info.info1.entries[0].idx);
3518 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3519 !NT_STATUS_IS_OK(status)) {
3520 printf("QueryDisplayInfo level %u failed - %s\n",
3521 r.in.level, nt_errstr(status));
3526 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3527 NT_STATUS_IS_OK(status)) &&
3528 r.out.returned_size != 0);
3533 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3534 struct policy_handle *handle)
3537 struct samr_QueryDomainInfo r;
3538 struct samr_SetDomainInfo s;
3539 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3540 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3543 const char *domain_comment = talloc_asprintf(mem_ctx,
3544 "Tortured by Samba4 RPC-SAMR: %s",
3545 timestring(mem_ctx, time(NULL)));
3547 s.in.domain_handle = handle;
3549 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3551 s.in.info->info4.comment.string = domain_comment;
3552 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3553 if (!NT_STATUS_IS_OK(status)) {
3554 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3555 r.in.level, nt_errstr(status));
3559 for (i=0;i<ARRAY_SIZE(levels);i++) {
3560 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3562 r.in.domain_handle = handle;
3563 r.in.level = levels[i];
3565 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3566 if (!NT_STATUS_IS_OK(status)) {
3567 printf("QueryDomainInfo level %u failed - %s\n",
3568 r.in.level, nt_errstr(status));
3573 switch (levels[i]) {
3575 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3576 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3577 levels[i], r.out.info->info2.comment.string, domain_comment);
3580 if (!r.out.info->info2.primary.string) {
3581 printf("QueryDomainInfo level %u returned no PDC name\n",
3584 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3585 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3586 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3587 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3592 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3593 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3594 levels[i], r.out.info->info4.comment.string, domain_comment);
3599 if (!r.out.info->info6.primary.string) {
3600 printf("QueryDomainInfo level %u returned no PDC name\n",
3606 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3607 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3608 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3614 printf("Testing SetDomainInfo level %u\n", levels[i]);
3616 s.in.domain_handle = handle;
3617 s.in.level = levels[i];
3618 s.in.info = r.out.info;
3620 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3622 if (!NT_STATUS_IS_OK(status)) {
3623 printf("SetDomainInfo level %u failed - %s\n",
3624 r.in.level, nt_errstr(status));
3629 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3630 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3631 r.in.level, nt_errstr(status));
3637 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3638 if (!NT_STATUS_IS_OK(status)) {
3639 printf("QueryDomainInfo level %u failed - %s\n",
3640 r.in.level, nt_errstr(status));
3650 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3651 struct policy_handle *handle)
3654 struct samr_QueryDomainInfo2 r;
3655 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3659 for (i=0;i<ARRAY_SIZE(levels);i++) {
3660 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3662 r.in.domain_handle = handle;
3663 r.in.level = levels[i];
3665 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3666 if (!NT_STATUS_IS_OK(status)) {
3667 printf("QueryDomainInfo2 level %u failed - %s\n",
3668 r.in.level, nt_errstr(status));
3677 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3678 set of group names. */
3679 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3680 struct policy_handle *handle)
3682 struct samr_EnumDomainGroups q1;
3683 struct samr_QueryDisplayInfo q2;
3685 uint32_t resume_handle=0;
3690 const char **names = NULL;
3692 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3694 q1.in.domain_handle = handle;
3695 q1.in.resume_handle = &resume_handle;
3697 q1.out.resume_handle = &resume_handle;
3699 status = STATUS_MORE_ENTRIES;
3700 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3701 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3703 if (!NT_STATUS_IS_OK(status) &&
3704 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3707 for (i=0; i<q1.out.num_entries; i++) {
3708 add_string_to_array(mem_ctx,
3709 q1.out.sam->entries[i].name.string,
3710 &names, &num_names);
3714 if (!NT_STATUS_IS_OK(status)) {
3715 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3723 q2.in.domain_handle = handle;
3725 q2.in.start_idx = 0;
3726 q2.in.max_entries = 5;
3727 q2.in.buf_size = (uint32_t)-1;
3729 status = STATUS_MORE_ENTRIES;
3730 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3731 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3733 if (!NT_STATUS_IS_OK(status) &&
3734 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3737 for (i=0; i<q2.out.info.info5.count; i++) {
3739 const char *name = q2.out.info.info5.entries[i].account_name.string;
3741 for (j=0; j<num_names; j++) {
3742 if (names[j] == NULL)
3744 /* Hmm. No strequal in samba4 */
3745 if (strequal(names[j], name)) {
3753 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3758 q2.in.start_idx += q2.out.info.info5.count;
3761 if (!NT_STATUS_IS_OK(status)) {
3762 printf("QueryDisplayInfo level 5 failed - %s\n",
3767 for (i=0; i<num_names; i++) {
3768 if (names[i] != NULL) {
3769 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3778 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3779 struct policy_handle *group_handle)
3781 struct samr_DeleteDomainGroup d;
3785 printf("Testing DeleteDomainGroup\n");
3787 d.in.group_handle = group_handle;
3788 d.out.group_handle = group_handle;
3790 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3791 if (!NT_STATUS_IS_OK(status)) {
3792 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3799 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3800 struct policy_handle *domain_handle)
3802 struct samr_TestPrivateFunctionsDomain r;
3806 printf("Testing TestPrivateFunctionsDomain\n");
3808 r.in.domain_handle = domain_handle;
3810 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3811 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3812 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3819 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3820 struct dom_sid *domain_sid,
3821 struct policy_handle *domain_handle)
3823 struct samr_RidToSid r;
3826 struct dom_sid *calc_sid;
3827 int rids[] = { 0, 42, 512, 10200 };
3830 for (i=0;i<ARRAY_SIZE(rids);i++) {
3832 printf("Testing RidToSid\n");
3834 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3835 r.in.domain_handle = domain_handle;
3838 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3839 if (!NT_STATUS_IS_OK(status)) {
3840 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3843 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3845 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3846 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3847 dom_sid_string(mem_ctx, r.out.sid),
3848 dom_sid_string(mem_ctx, calc_sid));
3857 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3858 struct policy_handle *domain_handle)
3860 struct samr_GetBootKeyInformation r;
3864 printf("Testing GetBootKeyInformation\n");
3866 r.in.domain_handle = domain_handle;
3868 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
3869 if (!NT_STATUS_IS_OK(status)) {
3870 /* w2k3 seems to fail this sometimes and pass it sometimes */
3871 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
3877 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3878 struct policy_handle *domain_handle,
3879 struct policy_handle *group_handle)
3882 struct samr_AddGroupMember r;
3883 struct samr_DeleteGroupMember d;
3884 struct samr_QueryGroupMember q;
3885 struct samr_SetMemberAttributesOfGroup s;
3889 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
3890 if (!NT_STATUS_IS_OK(status)) {
3891 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
3895 r.in.group_handle = group_handle;
3897 r.in.flags = 0; /* ??? */
3899 printf("Testing AddGroupMember and DeleteGroupMember\n");
3901 d.in.group_handle = group_handle;
3904 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3905 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
3906 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
3911 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3912 if (!NT_STATUS_IS_OK(status)) {
3913 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3917 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3918 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
3919 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
3924 if (lp_parm_bool(-1, "torture", "samba4", False)) {
3925 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
3927 /* this one is quite strange. I am using random inputs in the
3928 hope of triggering an error that might give us a clue */
3930 s.in.group_handle = group_handle;
3931 s.in.unknown1 = random();
3932 s.in.unknown2 = random();
3934 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
3935 if (!NT_STATUS_IS_OK(status)) {
3936 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
3941 q.in.group_handle = group_handle;
3943 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
3944 if (!NT_STATUS_IS_OK(status)) {
3945 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
3949 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3950 if (!NT_STATUS_IS_OK(status)) {
3951 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
3955 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3956 if (!NT_STATUS_IS_OK(status)) {
3957 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3965 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3966 struct policy_handle *domain_handle, struct policy_handle *group_handle)
3969 struct samr_CreateDomainGroup r;
3971 struct lsa_String name;
3974 init_lsa_String(&name, TEST_GROUPNAME);
3976 r.in.domain_handle = domain_handle;
3978 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3979 r.out.group_handle = group_handle;
3982 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3984 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3986 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3987 printf("Server refused create of '%s'\n", r.in.name->string);
3988 ZERO_STRUCTP(group_handle);
3992 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
3993 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3995 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
3999 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4001 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4002 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4004 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4008 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4010 if (!NT_STATUS_IS_OK(status)) {
4011 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4015 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4016 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4020 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4029 its not totally clear what this does. It seems to accept any sid you like.
4031 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4032 TALLOC_CTX *mem_ctx,
4033 struct policy_handle *domain_handle)
4036 struct samr_RemoveMemberFromForeignDomain r;
4038 r.in.domain_handle = domain_handle;
4039 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4041 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4042 if (!NT_STATUS_IS_OK(status)) {
4043 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4052 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4053 struct policy_handle *handle);
4055 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4056 struct policy_handle *handle, struct dom_sid *sid,
4057 enum torture_samr_choice which_ops)
4060 struct samr_OpenDomain r;
4061 struct policy_handle domain_handle;
4062 struct policy_handle alias_handle;
4063 struct policy_handle user_handle;
4064 struct policy_handle group_handle;
4067 ZERO_STRUCT(alias_handle);
4068 ZERO_STRUCT(user_handle);
4069 ZERO_STRUCT(group_handle);
4070 ZERO_STRUCT(domain_handle);
4072 printf("Testing OpenDomain\n");
4074 r.in.connect_handle = handle;
4075 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4077 r.out.domain_handle = &domain_handle;
4079 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("OpenDomain failed - %s\n", nt_errstr(status));
4085 /* run the domain tests with the main handle closed - this tests
4086 the servers reference counting */
4087 ret &= test_samr_handle_Close(p, mem_ctx, handle);
4089 switch (which_ops) {
4090 case TORTURE_SAMR_USER_ATTRIBUTES:
4091 case TORTURE_SAMR_PASSWORDS:
4092 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
4093 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4094 /* This test needs 'complex' users to validate */
4095 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
4097 case TORTURE_SAMR_OTHER:
4098 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4099 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
4100 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
4101 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
4102 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
4103 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
4104 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
4105 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
4106 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
4107 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
4108 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
4109 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
4110 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
4111 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
4113 if (lp_parm_bool(-1, "torture", "samba4", False)) {
4114 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4116 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
4117 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
4119 ret &= test_GroupList(p, mem_ctx, &domain_handle);
4120 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
4121 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
4122 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
4126 if (!policy_handle_empty(&user_handle) &&
4127 !test_DeleteUser(p, mem_ctx, &user_handle)) {
4131 if (!policy_handle_empty(&alias_handle) &&
4132 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
4136 if (!policy_handle_empty(&group_handle) &&
4137 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
4141 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
4143 /* reconnect the main handle */
4144 ret &= test_Connect(p, mem_ctx, handle);
4147 printf("Testing domain %s failed!\n", dom_sid_string(mem_ctx, sid));
4153 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4154 struct policy_handle *handle, const char *domain,
4155 enum torture_samr_choice which_ops)
4158 struct samr_LookupDomain r;
4159 struct lsa_String n1;
4160 struct lsa_String n2;
4163 printf("Testing LookupDomain(%s)\n", domain);
4165 /* check for correct error codes */
4166 r.in.connect_handle = handle;
4167 r.in.domain_name = &n2;
4170 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4171 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4172 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4176 init_lsa_String(&n2, "xxNODOMAINxx");
4178 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4179 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4180 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4184 r.in.connect_handle = handle;
4186 init_lsa_String(&n1, domain);
4187 r.in.domain_name = &n1;
4189 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4190 if (!NT_STATUS_IS_OK(status)) {
4191 printf("LookupDomain failed - %s\n", nt_errstr(status));
4195 if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
4199 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
4207 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4208 struct policy_handle *handle, enum torture_samr_choice which_ops)
4211 struct samr_EnumDomains r;
4212 uint32_t resume_handle = 0;
4216 r.in.connect_handle = handle;
4217 r.in.resume_handle = &resume_handle;
4218 r.in.buf_size = (uint32_t)-1;
4219 r.out.resume_handle = &resume_handle;
4221 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4222 if (!NT_STATUS_IS_OK(status)) {
4223 printf("EnumDomains failed - %s\n", nt_errstr(status));
4231 for (i=0;i<r.out.sam->count;i++) {
4232 if (!test_LookupDomain(p, mem_ctx, handle,
4233 r.out.sam->entries[i].name.string, which_ops)) {
4238 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4239 if (!NT_STATUS_IS_OK(status)) {
4240 printf("EnumDomains failed - %s\n", nt_errstr(status));
4248 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4249 struct policy_handle *handle)
4252 struct samr_Connect r;
4253 struct samr_Connect2 r2;
4254 struct samr_Connect3 r3;
4255 struct samr_Connect4 r4;
4256 struct samr_Connect5 r5;
4257 union samr_ConnectInfo info;
4258 struct policy_handle h;
4259 BOOL ret = True, got_handle = False;
4261 printf("testing samr_Connect\n");
4263 r.in.system_name = 0;
4264 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4265 r.out.connect_handle = &h;
4267 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4268 if (!NT_STATUS_IS_OK(status)) {
4269 printf("Connect failed - %s\n", nt_errstr(status));
4276 printf("testing samr_Connect2\n");
4278 r2.in.system_name = NULL;
4279 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4280 r2.out.connect_handle = &h;
4282 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4283 if (!NT_STATUS_IS_OK(status)) {
4284 printf("Connect2 failed - %s\n", nt_errstr(status));
4288 test_samr_handle_Close(p, mem_ctx, handle);
4294 printf("testing samr_Connect3\n");
4296 r3.in.system_name = NULL;
4298 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4299 r3.out.connect_handle = &h;
4301 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4302 if (!NT_STATUS_IS_OK(status)) {
4303 printf("Connect3 failed - %s\n", nt_errstr(status));
4307 test_samr_handle_Close(p, mem_ctx, handle);
4313 printf("testing samr_Connect4\n");
4315 r4.in.system_name = "";
4317 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4318 r4.out.connect_handle = &h;
4320 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4321 if (!NT_STATUS_IS_OK(status)) {
4322 printf("Connect4 failed - %s\n", nt_errstr(status));
4326 test_samr_handle_Close(p, mem_ctx, handle);
4332 printf("testing samr_Connect5\n");
4334 info.info1.unknown1 = 0;
4335 info.info1.unknown2 = 0;
4337 r5.in.system_name = "";
4338 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4341 r5.out.info = &info;
4342 r5.out.connect_handle = &h;
4344 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4345 if (!NT_STATUS_IS_OK(status)) {
4346 printf("Connect5 failed - %s\n", nt_errstr(status));
4350 test_samr_handle_Close(p, mem_ctx, handle);
4360 BOOL torture_rpc_samr(struct torture_context *torture)
4363 struct dcerpc_pipe *p;
4365 struct policy_handle handle;
4367 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4368 if (!NT_STATUS_IS_OK(status)) {
4372 ret &= test_Connect(p, torture, &handle);
4374 ret &= test_QuerySecurity(p, torture, &handle);
4376 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4378 ret &= test_SetDsrmPassword(p, torture, &handle);
4380 ret &= test_Shutdown(p, torture, &handle);
4382 ret &= test_samr_handle_Close(p, torture, &handle);
4388 BOOL torture_rpc_samr_users(struct torture_context *torture)
4391 struct dcerpc_pipe *p;
4393 struct policy_handle handle;
4395 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4396 if (!NT_STATUS_IS_OK(status)) {
4400 ret &= test_Connect(p, torture, &handle);
4402 ret &= test_QuerySecurity(p, torture, &handle);
4404 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4406 ret &= test_SetDsrmPassword(p, torture, &handle);
4408 ret &= test_Shutdown(p, torture, &handle);
4410 ret &= test_samr_handle_Close(p, torture, &handle);
4416 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
4419 struct dcerpc_pipe *p;
4421 struct policy_handle handle;
4423 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4424 if (!NT_STATUS_IS_OK(status)) {
4428 ret &= test_Connect(p, torture, &handle);
4430 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4432 ret &= test_samr_handle_Close(p, torture, &handle);