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%llx - got 0x%llx (%s)\n", \
231 #field, (unsigned long long)i2, (unsigned long long)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);
376 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
377 SAMR_FIELD_WORKSTATIONS);
378 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
379 SAMR_FIELD_WORKSTATIONS);
380 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
381 SAMR_FIELD_WORKSTATIONS);
383 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
384 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
385 SAMR_FIELD_PARAMETERS);
386 TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
387 SAMR_FIELD_PARAMETERS);
389 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
390 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
391 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
392 SAMR_FIELD_COUNTRY_CODE);
393 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
394 SAMR_FIELD_COUNTRY_CODE);
396 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
397 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
398 SAMR_FIELD_CODE_PAGE);
399 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
400 SAMR_FIELD_CODE_PAGE);
402 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
403 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
404 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
405 SAMR_FIELD_ACCT_EXPIRY);
406 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
407 SAMR_FIELD_ACCT_EXPIRY);
408 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
409 SAMR_FIELD_ACCT_EXPIRY);
411 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
412 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
413 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
414 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
415 SAMR_FIELD_LOGON_HOURS);
417 if (lp_parm_bool(-1, "torture", "samba4", False)) {
418 printf("skipping Set Account Flag tests against Samba4\n");
422 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
423 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
424 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
426 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
427 (base_acct_flags | ACB_DISABLED),
428 (base_acct_flags | ACB_DISABLED | user_extra_flags),
431 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
432 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
433 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
434 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
436 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
437 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
438 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
442 /* The 'autolock' flag doesn't stick - check this */
443 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
444 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
445 (base_acct_flags | ACB_DISABLED | user_extra_flags),
448 /* Removing the 'disabled' flag doesn't stick - check this */
449 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
451 (base_acct_flags | ACB_DISABLED | user_extra_flags),
454 /* The 'store plaintext' flag does stick */
455 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
456 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
457 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
459 /* The 'use DES' flag does stick */
460 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
461 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
462 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
464 /* The 'don't require kerberos pre-authentication flag does stick */
465 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
466 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
467 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
469 /* The 'no kerberos PAC required' flag sticks */
470 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
471 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
472 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
475 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
476 (base_acct_flags | ACB_DISABLED),
477 (base_acct_flags | ACB_DISABLED | user_extra_flags),
478 SAMR_FIELD_ACCT_FLAGS);
481 /* these fail with win2003 - it appears you can't set the primary gid?
482 the set succeeds, but the gid isn't changed. Very weird! */
483 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
484 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
485 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
486 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
493 generate a random password for password change tests
495 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
497 size_t len = MAX(8, min_len) + (random() % 6);
498 char *s = generate_random_str(mem_ctx, len);
499 printf("Generated password '%s'\n", s);
504 generate a random password for password change tests (fixed length)
506 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
508 char *s = generate_random_str(mem_ctx, len);
509 printf("Generated password '%s'\n", s);
513 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
514 struct policy_handle *handle, char **password)
517 struct samr_SetUserInfo s;
518 union samr_UserInfo u;
520 DATA_BLOB session_key;
522 struct samr_GetUserPwInfo pwp;
523 int policy_min_pw_len = 0;
524 pwp.in.user_handle = handle;
526 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
527 if (NT_STATUS_IS_OK(status)) {
528 policy_min_pw_len = pwp.out.info.min_password_length;
530 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
532 s.in.user_handle = handle;
536 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
537 /* w2k3 ignores this length */
538 u.info24.pw_len = strlen_m(newpass) * 2;
540 status = dcerpc_fetch_session_key(p, &session_key);
541 if (!NT_STATUS_IS_OK(status)) {
542 printf("SetUserInfo level %u - no session key - %s\n",
543 s.in.level, nt_errstr(status));
547 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
549 printf("Testing SetUserInfo level 24 (set password)\n");
551 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
552 if (!NT_STATUS_IS_OK(status)) {
553 printf("SetUserInfo level %u failed - %s\n",
554 s.in.level, nt_errstr(status));
564 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
565 struct policy_handle *handle, uint32_t fields_present,
569 struct samr_SetUserInfo s;
570 union samr_UserInfo u;
572 DATA_BLOB session_key;
574 struct samr_GetUserPwInfo pwp;
575 int policy_min_pw_len = 0;
576 pwp.in.user_handle = handle;
578 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
579 if (NT_STATUS_IS_OK(status)) {
580 policy_min_pw_len = pwp.out.info.min_password_length;
582 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
584 s.in.user_handle = handle;
590 u.info23.info.fields_present = fields_present;
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 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
603 printf("Testing SetUserInfo level 23 (set password)\n");
605 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
606 if (!NT_STATUS_IS_OK(status)) {
607 printf("SetUserInfo level %u failed - %s\n",
608 s.in.level, nt_errstr(status));
614 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
616 status = dcerpc_fetch_session_key(p, &session_key);
617 if (!NT_STATUS_IS_OK(status)) {
618 printf("SetUserInfo level %u - no session key - %s\n",
619 s.in.level, nt_errstr(status));
623 /* This should break the key nicely */
624 session_key.length--;
625 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
627 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
629 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
630 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
631 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
632 s.in.level, nt_errstr(status));
640 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
641 struct policy_handle *handle, bool makeshort,
645 struct samr_SetUserInfo s;
646 union samr_UserInfo u;
648 DATA_BLOB session_key;
649 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
650 uint8_t confounder[16];
652 struct MD5Context ctx;
653 struct samr_GetUserPwInfo pwp;
654 int policy_min_pw_len = 0;
655 pwp.in.user_handle = handle;
657 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
658 if (NT_STATUS_IS_OK(status)) {
659 policy_min_pw_len = pwp.out.info.min_password_length;
661 if (makeshort && policy_min_pw_len) {
662 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
664 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
667 s.in.user_handle = handle;
671 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
672 u.info26.pw_len = strlen(newpass);
674 status = dcerpc_fetch_session_key(p, &session_key);
675 if (!NT_STATUS_IS_OK(status)) {
676 printf("SetUserInfo level %u - no session key - %s\n",
677 s.in.level, nt_errstr(status));
681 generate_random_buffer((uint8_t *)confounder, 16);
684 MD5Update(&ctx, confounder, 16);
685 MD5Update(&ctx, session_key.data, session_key.length);
686 MD5Final(confounded_session_key.data, &ctx);
688 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
689 memcpy(&u.info26.password.data[516], confounder, 16);
691 printf("Testing SetUserInfo level 26 (set password ex)\n");
693 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
694 if (!NT_STATUS_IS_OK(status)) {
695 printf("SetUserInfo level %u failed - %s\n",
696 s.in.level, nt_errstr(status));
702 /* This should break the key nicely */
703 confounded_session_key.data[0]++;
705 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
706 memcpy(&u.info26.password.data[516], confounder, 16);
708 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
710 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
711 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
712 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
713 s.in.level, nt_errstr(status));
722 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
723 struct policy_handle *handle, uint32_t fields_present,
727 struct samr_SetUserInfo s;
728 union samr_UserInfo u;
730 DATA_BLOB session_key;
731 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
732 struct MD5Context ctx;
733 uint8_t confounder[16];
735 struct samr_GetUserPwInfo pwp;
736 int policy_min_pw_len = 0;
737 pwp.in.user_handle = handle;
739 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
740 if (NT_STATUS_IS_OK(status)) {
741 policy_min_pw_len = pwp.out.info.min_password_length;
743 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
745 s.in.user_handle = handle;
751 u.info25.info.fields_present = fields_present;
753 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
755 status = dcerpc_fetch_session_key(p, &session_key);
756 if (!NT_STATUS_IS_OK(status)) {
757 printf("SetUserInfo level %u - no session key - %s\n",
758 s.in.level, nt_errstr(status));
762 generate_random_buffer((uint8_t *)confounder, 16);
765 MD5Update(&ctx, confounder, 16);
766 MD5Update(&ctx, session_key.data, session_key.length);
767 MD5Final(confounded_session_key.data, &ctx);
769 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
770 memcpy(&u.info25.password.data[516], confounder, 16);
772 printf("Testing SetUserInfo level 25 (set password ex)\n");
774 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
775 if (!NT_STATUS_IS_OK(status)) {
776 printf("SetUserInfo level %u failed - %s\n",
777 s.in.level, nt_errstr(status));
783 /* This should break the key nicely */
784 confounded_session_key.data[0]++;
786 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
787 memcpy(&u.info25.password.data[516], confounder, 16);
789 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
791 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
792 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
793 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
794 s.in.level, nt_errstr(status));
801 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
802 struct policy_handle *handle)
805 struct samr_SetAliasInfo r;
806 struct samr_QueryAliasInfo q;
807 uint16_t levels[] = {2, 3};
811 /* Ignoring switch level 1, as that includes the number of members for the alias
812 * and setting this to a wrong value might have negative consequences
815 for (i=0;i<ARRAY_SIZE(levels);i++) {
816 printf("Testing SetAliasInfo level %u\n", levels[i]);
818 r.in.alias_handle = handle;
819 r.in.level = levels[i];
820 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
821 switch (r.in.level) {
822 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
823 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
824 "Test Description, should test I18N as well"); break;
827 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
828 if (!NT_STATUS_IS_OK(status)) {
829 printf("SetAliasInfo level %u failed - %s\n",
830 levels[i], nt_errstr(status));
834 q.in.alias_handle = handle;
835 q.in.level = levels[i];
837 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
838 if (!NT_STATUS_IS_OK(status)) {
839 printf("QueryAliasInfo level %u failed - %s\n",
840 levels[i], nt_errstr(status));
848 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
849 struct policy_handle *user_handle)
851 struct samr_GetGroupsForUser r;
855 printf("testing GetGroupsForUser\n");
857 r.in.user_handle = user_handle;
859 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
860 if (!NT_STATUS_IS_OK(status)) {
861 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
869 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
870 struct lsa_String *domain_name)
873 struct samr_GetDomPwInfo r;
876 r.in.domain_name = domain_name;
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));
885 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
886 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
888 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
889 if (!NT_STATUS_IS_OK(status)) {
890 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
894 r.in.domain_name->string = "\\\\__NONAME__";
895 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
897 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
898 if (!NT_STATUS_IS_OK(status)) {
899 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
903 r.in.domain_name->string = "\\\\Builtin";
904 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
906 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
907 if (!NT_STATUS_IS_OK(status)) {
908 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
916 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
917 struct policy_handle *handle)
920 struct samr_GetUserPwInfo r;
923 printf("Testing GetUserPwInfo\n");
925 r.in.user_handle = handle;
927 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
928 if (!NT_STATUS_IS_OK(status)) {
929 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
936 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
937 struct policy_handle *domain_handle, const char *name,
941 struct samr_LookupNames n;
942 struct lsa_String sname[2];
944 init_lsa_String(&sname[0], name);
946 n.in.domain_handle = domain_handle;
949 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
950 if (NT_STATUS_IS_OK(status)) {
951 *rid = n.out.rids.ids[0];
956 init_lsa_String(&sname[1], "xxNONAMExx");
958 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
959 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
960 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
961 if (NT_STATUS_IS_OK(status)) {
962 return NT_STATUS_UNSUCCESSFUL;
968 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
969 if (!NT_STATUS_IS_OK(status)) {
970 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
974 init_lsa_String(&sname[0], "xxNONAMExx");
976 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
977 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
978 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
979 if (NT_STATUS_IS_OK(status)) {
980 return NT_STATUS_UNSUCCESSFUL;
985 init_lsa_String(&sname[0], "xxNONAMExx");
986 init_lsa_String(&sname[1], "xxNONAME2xx");
988 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
989 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
990 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
991 if (NT_STATUS_IS_OK(status)) {
992 return NT_STATUS_UNSUCCESSFUL;
1000 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1001 struct policy_handle *domain_handle,
1002 const char *name, struct policy_handle *user_handle)
1005 struct samr_OpenUser r;
1008 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1009 if (!NT_STATUS_IS_OK(status)) {
1013 r.in.domain_handle = domain_handle;
1014 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1016 r.out.user_handle = user_handle;
1017 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1018 if (!NT_STATUS_IS_OK(status)) {
1019 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1026 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1027 struct policy_handle *handle)
1030 struct samr_ChangePasswordUser r;
1032 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1033 struct policy_handle user_handle;
1034 char *oldpass = "test";
1035 char *newpass = "test2";
1036 uint8_t old_nt_hash[16], new_nt_hash[16];
1037 uint8_t old_lm_hash[16], new_lm_hash[16];
1039 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1040 if (!NT_STATUS_IS_OK(status)) {
1044 printf("Testing ChangePasswordUser for user 'testuser'\n");
1046 printf("old password: %s\n", oldpass);
1047 printf("new password: %s\n", newpass);
1049 E_md4hash(oldpass, old_nt_hash);
1050 E_md4hash(newpass, new_nt_hash);
1051 E_deshash(oldpass, old_lm_hash);
1052 E_deshash(newpass, new_lm_hash);
1054 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1055 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1056 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1057 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1058 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1059 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1061 r.in.handle = &user_handle;
1062 r.in.lm_present = 1;
1063 r.in.old_lm_crypted = &hash1;
1064 r.in.new_lm_crypted = &hash2;
1065 r.in.nt_present = 1;
1066 r.in.old_nt_crypted = &hash3;
1067 r.in.new_nt_crypted = &hash4;
1068 r.in.cross1_present = 1;
1069 r.in.nt_cross = &hash5;
1070 r.in.cross2_present = 1;
1071 r.in.lm_cross = &hash6;
1073 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1074 if (!NT_STATUS_IS_OK(status)) {
1075 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1079 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1087 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1088 const char *acct_name,
1089 struct policy_handle *handle, char **password)
1092 struct samr_ChangePasswordUser r;
1094 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1095 struct policy_handle user_handle;
1097 uint8_t old_nt_hash[16], new_nt_hash[16];
1098 uint8_t old_lm_hash[16], new_lm_hash[16];
1099 BOOL changed = True;
1102 struct samr_GetUserPwInfo pwp;
1103 int policy_min_pw_len = 0;
1105 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1106 if (!NT_STATUS_IS_OK(status)) {
1109 pwp.in.user_handle = &user_handle;
1111 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1112 if (NT_STATUS_IS_OK(status)) {
1113 policy_min_pw_len = pwp.out.info.min_password_length;
1115 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1117 printf("Testing ChangePasswordUser\n");
1120 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1124 oldpass = *password;
1126 E_md4hash(oldpass, old_nt_hash);
1127 E_md4hash(newpass, new_nt_hash);
1128 E_deshash(oldpass, old_lm_hash);
1129 E_deshash(newpass, new_lm_hash);
1131 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1132 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1133 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1134 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1135 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1136 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1138 r.in.user_handle = &user_handle;
1139 r.in.lm_present = 1;
1140 /* Break the LM hash */
1142 r.in.old_lm_crypted = &hash1;
1143 r.in.new_lm_crypted = &hash2;
1144 r.in.nt_present = 1;
1145 r.in.old_nt_crypted = &hash3;
1146 r.in.new_nt_crypted = &hash4;
1147 r.in.cross1_present = 1;
1148 r.in.nt_cross = &hash5;
1149 r.in.cross2_present = 1;
1150 r.in.lm_cross = &hash6;
1152 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1153 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1154 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1158 /* Unbreak the LM hash */
1161 r.in.user_handle = &user_handle;
1162 r.in.lm_present = 1;
1163 r.in.old_lm_crypted = &hash1;
1164 r.in.new_lm_crypted = &hash2;
1165 /* Break the NT hash */
1167 r.in.nt_present = 1;
1168 r.in.old_nt_crypted = &hash3;
1169 r.in.new_nt_crypted = &hash4;
1170 r.in.cross1_present = 1;
1171 r.in.nt_cross = &hash5;
1172 r.in.cross2_present = 1;
1173 r.in.lm_cross = &hash6;
1175 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1176 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1177 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1181 /* Unbreak the NT hash */
1184 r.in.user_handle = &user_handle;
1185 r.in.lm_present = 1;
1186 r.in.old_lm_crypted = &hash1;
1187 r.in.new_lm_crypted = &hash2;
1188 r.in.nt_present = 1;
1189 r.in.old_nt_crypted = &hash3;
1190 r.in.new_nt_crypted = &hash4;
1191 r.in.cross1_present = 1;
1192 r.in.nt_cross = &hash5;
1193 r.in.cross2_present = 1;
1194 /* Break the LM cross */
1196 r.in.lm_cross = &hash6;
1198 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1199 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1200 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1204 /* Unbreak the LM cross */
1207 r.in.user_handle = &user_handle;
1208 r.in.lm_present = 1;
1209 r.in.old_lm_crypted = &hash1;
1210 r.in.new_lm_crypted = &hash2;
1211 r.in.nt_present = 1;
1212 r.in.old_nt_crypted = &hash3;
1213 r.in.new_nt_crypted = &hash4;
1214 r.in.cross1_present = 1;
1215 /* Break the NT cross */
1217 r.in.nt_cross = &hash5;
1218 r.in.cross2_present = 1;
1219 r.in.lm_cross = &hash6;
1221 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1222 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1223 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1227 /* Unbreak the NT cross */
1231 /* Reset the hashes to not broken values */
1232 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1233 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1234 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1235 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1236 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1237 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1239 r.in.user_handle = &user_handle;
1240 r.in.lm_present = 1;
1241 r.in.old_lm_crypted = &hash1;
1242 r.in.new_lm_crypted = &hash2;
1243 r.in.nt_present = 1;
1244 r.in.old_nt_crypted = &hash3;
1245 r.in.new_nt_crypted = &hash4;
1246 r.in.cross1_present = 1;
1247 r.in.nt_cross = &hash5;
1248 r.in.cross2_present = 0;
1249 r.in.lm_cross = NULL;
1251 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1252 if (NT_STATUS_IS_OK(status)) {
1254 *password = newpass;
1255 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1256 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1261 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1263 E_md4hash(oldpass, old_nt_hash);
1264 E_md4hash(newpass, new_nt_hash);
1265 E_deshash(oldpass, old_lm_hash);
1266 E_deshash(newpass, new_lm_hash);
1269 /* Reset the hashes to not broken values */
1270 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1271 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1272 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1273 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1274 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1275 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1277 r.in.user_handle = &user_handle;
1278 r.in.lm_present = 1;
1279 r.in.old_lm_crypted = &hash1;
1280 r.in.new_lm_crypted = &hash2;
1281 r.in.nt_present = 1;
1282 r.in.old_nt_crypted = &hash3;
1283 r.in.new_nt_crypted = &hash4;
1284 r.in.cross1_present = 0;
1285 r.in.nt_cross = NULL;
1286 r.in.cross2_present = 1;
1287 r.in.lm_cross = &hash6;
1289 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1290 if (NT_STATUS_IS_OK(status)) {
1292 *password = newpass;
1293 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1294 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1299 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1301 E_md4hash(oldpass, old_nt_hash);
1302 E_md4hash(newpass, new_nt_hash);
1303 E_deshash(oldpass, old_lm_hash);
1304 E_deshash(newpass, new_lm_hash);
1307 /* Reset the hashes to not broken values */
1308 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1309 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1310 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1311 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1312 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1313 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1315 r.in.user_handle = &user_handle;
1316 r.in.lm_present = 1;
1317 r.in.old_lm_crypted = &hash1;
1318 r.in.new_lm_crypted = &hash2;
1319 r.in.nt_present = 1;
1320 r.in.old_nt_crypted = &hash3;
1321 r.in.new_nt_crypted = &hash4;
1322 r.in.cross1_present = 1;
1323 r.in.nt_cross = &hash5;
1324 r.in.cross2_present = 1;
1325 r.in.lm_cross = &hash6;
1327 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1328 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1329 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1330 } else if (!NT_STATUS_IS_OK(status)) {
1331 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1335 *password = newpass;
1338 r.in.user_handle = &user_handle;
1339 r.in.lm_present = 1;
1340 r.in.old_lm_crypted = &hash1;
1341 r.in.new_lm_crypted = &hash2;
1342 r.in.nt_present = 1;
1343 r.in.old_nt_crypted = &hash3;
1344 r.in.new_nt_crypted = &hash4;
1345 r.in.cross1_present = 1;
1346 r.in.nt_cross = &hash5;
1347 r.in.cross2_present = 1;
1348 r.in.lm_cross = &hash6;
1351 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1352 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1353 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1354 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1355 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1361 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1369 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1370 const char *acct_name,
1371 struct policy_handle *handle, char **password)
1374 struct samr_OemChangePasswordUser2 r;
1376 struct samr_Password lm_verifier;
1377 struct samr_CryptPassword lm_pass;
1378 struct lsa_AsciiString server, account, account_bad;
1381 uint8_t old_lm_hash[16], new_lm_hash[16];
1383 struct samr_GetDomPwInfo dom_pw_info;
1384 int policy_min_pw_len = 0;
1386 struct lsa_String domain_name;
1388 domain_name.string = "";
1389 dom_pw_info.in.domain_name = &domain_name;
1391 printf("Testing OemChangePasswordUser2\n");
1394 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1398 oldpass = *password;
1400 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1401 if (NT_STATUS_IS_OK(status)) {
1402 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1405 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1407 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1408 account.string = acct_name;
1410 E_deshash(oldpass, old_lm_hash);
1411 E_deshash(newpass, new_lm_hash);
1413 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1414 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1415 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1417 r.in.server = &server;
1418 r.in.account = &account;
1419 r.in.password = &lm_pass;
1420 r.in.hash = &lm_verifier;
1422 /* Break the verification */
1423 lm_verifier.hash[0]++;
1425 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1427 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1428 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1429 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1434 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1435 /* Break the old password */
1437 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1438 /* unbreak it for the next operation */
1440 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1442 r.in.server = &server;
1443 r.in.account = &account;
1444 r.in.password = &lm_pass;
1445 r.in.hash = &lm_verifier;
1447 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1449 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1450 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1451 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1456 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1457 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1459 r.in.server = &server;
1460 r.in.account = &account;
1461 r.in.password = &lm_pass;
1464 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1466 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1467 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1468 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1473 /* This shouldn't be a valid name */
1474 account_bad.string = TEST_ACCOUNT_NAME "XX";
1475 r.in.account = &account_bad;
1477 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1479 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1480 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1485 /* This shouldn't be a valid name */
1486 account_bad.string = TEST_ACCOUNT_NAME "XX";
1487 r.in.account = &account_bad;
1488 r.in.password = &lm_pass;
1489 r.in.hash = &lm_verifier;
1491 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1493 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1494 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1499 /* This shouldn't be a valid name */
1500 account_bad.string = TEST_ACCOUNT_NAME "XX";
1501 r.in.account = &account_bad;
1502 r.in.password = NULL;
1503 r.in.hash = &lm_verifier;
1505 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1507 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1508 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1513 E_deshash(oldpass, old_lm_hash);
1514 E_deshash(newpass, new_lm_hash);
1516 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1517 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1518 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1520 r.in.server = &server;
1521 r.in.account = &account;
1522 r.in.password = &lm_pass;
1523 r.in.hash = &lm_verifier;
1525 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1526 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1527 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1528 } else if (!NT_STATUS_IS_OK(status)) {
1529 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1532 *password = newpass;
1539 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1540 const char *acct_name,
1542 char *newpass, bool allow_password_restriction)
1545 struct samr_ChangePasswordUser2 r;
1547 struct lsa_String server, account;
1548 struct samr_CryptPassword nt_pass, lm_pass;
1549 struct samr_Password nt_verifier, lm_verifier;
1551 uint8_t old_nt_hash[16], new_nt_hash[16];
1552 uint8_t old_lm_hash[16], new_lm_hash[16];
1554 struct samr_GetDomPwInfo dom_pw_info;
1556 struct lsa_String domain_name;
1558 domain_name.string = "";
1559 dom_pw_info.in.domain_name = &domain_name;
1561 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1564 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1567 oldpass = *password;
1570 int policy_min_pw_len = 0;
1571 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1572 if (NT_STATUS_IS_OK(status)) {
1573 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1576 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1579 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1580 init_lsa_String(&account, acct_name);
1582 E_md4hash(oldpass, old_nt_hash);
1583 E_md4hash(newpass, new_nt_hash);
1585 E_deshash(oldpass, old_lm_hash);
1586 E_deshash(newpass, new_lm_hash);
1588 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1589 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1590 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1592 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1593 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1594 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1596 r.in.server = &server;
1597 r.in.account = &account;
1598 r.in.nt_password = &nt_pass;
1599 r.in.nt_verifier = &nt_verifier;
1601 r.in.lm_password = &lm_pass;
1602 r.in.lm_verifier = &lm_verifier;
1604 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1605 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1606 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1607 } else if (!NT_STATUS_IS_OK(status)) {
1608 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1611 *password = newpass;
1618 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1619 const char *account_string,
1620 int policy_min_pw_len,
1622 const char *newpass,
1623 NTTIME last_password_change,
1624 BOOL handle_reject_reason)
1627 struct samr_ChangePasswordUser3 r;
1629 struct lsa_String server, account, account_bad;
1630 struct samr_CryptPassword nt_pass, lm_pass;
1631 struct samr_Password nt_verifier, lm_verifier;
1633 uint8_t old_nt_hash[16], new_nt_hash[16];
1634 uint8_t old_lm_hash[16], new_lm_hash[16];
1637 printf("Testing ChangePasswordUser3\n");
1639 if (newpass == NULL) {
1641 if (policy_min_pw_len == 0) {
1642 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1644 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1646 } while (check_password_quality(newpass) == False);
1648 printf("Using password '%s'\n", newpass);
1652 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1656 oldpass = *password;
1657 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1658 init_lsa_String(&account, account_string);
1660 E_md4hash(oldpass, old_nt_hash);
1661 E_md4hash(newpass, new_nt_hash);
1663 E_deshash(oldpass, old_lm_hash);
1664 E_deshash(newpass, new_lm_hash);
1666 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1667 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1668 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1670 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1671 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1672 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1674 /* Break the verification */
1675 nt_verifier.hash[0]++;
1677 r.in.server = &server;
1678 r.in.account = &account;
1679 r.in.nt_password = &nt_pass;
1680 r.in.nt_verifier = &nt_verifier;
1682 r.in.lm_password = &lm_pass;
1683 r.in.lm_verifier = &lm_verifier;
1684 r.in.password3 = NULL;
1686 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1687 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1688 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1689 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1694 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1695 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1696 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1698 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1699 /* Break the NT hash */
1701 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1702 /* Unbreak it again */
1704 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1706 r.in.server = &server;
1707 r.in.account = &account;
1708 r.in.nt_password = &nt_pass;
1709 r.in.nt_verifier = &nt_verifier;
1711 r.in.lm_password = &lm_pass;
1712 r.in.lm_verifier = &lm_verifier;
1713 r.in.password3 = NULL;
1715 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1716 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1717 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1718 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1723 /* This shouldn't be a valid name */
1724 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1726 r.in.account = &account_bad;
1727 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1728 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1729 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1734 E_md4hash(oldpass, old_nt_hash);
1735 E_md4hash(newpass, new_nt_hash);
1737 E_deshash(oldpass, old_lm_hash);
1738 E_deshash(newpass, new_lm_hash);
1740 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1741 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1742 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1744 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1745 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1746 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1748 r.in.server = &server;
1749 r.in.account = &account;
1750 r.in.nt_password = &nt_pass;
1751 r.in.nt_verifier = &nt_verifier;
1753 r.in.lm_password = &lm_pass;
1754 r.in.lm_verifier = &lm_verifier;
1755 r.in.password3 = NULL;
1757 unix_to_nt_time(&t, time(NULL));
1759 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1761 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1764 && handle_reject_reason
1765 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1766 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1768 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1769 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1770 SAMR_REJECT_OTHER, r.out.reject->reason);
1775 /* We tested the order of precendence which is as follows:
1784 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1785 (last_password_change + r.out.dominfo->min_password_age > t)) {
1787 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1788 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1789 SAMR_REJECT_OTHER, r.out.reject->reason);
1793 } else if ((r.out.dominfo->min_password_length > 0) &&
1794 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1796 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1797 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1798 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1802 } else if ((r.out.dominfo->password_history_length > 0) &&
1803 strequal(oldpass, newpass)) {
1805 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1806 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1807 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1810 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1812 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1813 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1814 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1820 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1821 /* retry with adjusted size */
1822 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1823 r.out.dominfo->min_password_length,
1824 password, NULL, 0, False);
1828 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1829 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1830 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1831 SAMR_REJECT_OTHER, r.out.reject->reason);
1834 /* Perhaps the server has a 'min password age' set? */
1836 } else if (!NT_STATUS_IS_OK(status)) {
1837 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1840 *password = talloc_strdup(mem_ctx, newpass);
1847 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1848 struct policy_handle *alias_handle)
1850 struct samr_GetMembersInAlias r;
1851 struct lsa_SidArray sids;
1855 printf("Testing GetMembersInAlias\n");
1857 r.in.alias_handle = alias_handle;
1860 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1861 if (!NT_STATUS_IS_OK(status)) {
1862 printf("GetMembersInAlias failed - %s\n",
1870 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1871 struct policy_handle *alias_handle,
1872 const struct dom_sid *domain_sid)
1874 struct samr_AddAliasMember r;
1875 struct samr_DeleteAliasMember d;
1878 struct dom_sid *sid;
1880 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1882 printf("testing AddAliasMember\n");
1883 r.in.alias_handle = alias_handle;
1886 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1887 if (!NT_STATUS_IS_OK(status)) {
1888 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1892 d.in.alias_handle = alias_handle;
1895 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1896 if (!NT_STATUS_IS_OK(status)) {
1897 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1904 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1905 struct policy_handle *alias_handle)
1907 struct samr_AddMultipleMembersToAlias a;
1908 struct samr_RemoveMultipleMembersFromAlias r;
1911 struct lsa_SidArray sids;
1913 printf("testing AddMultipleMembersToAlias\n");
1914 a.in.alias_handle = alias_handle;
1918 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1920 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1921 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1922 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1924 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1925 if (!NT_STATUS_IS_OK(status)) {
1926 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1931 printf("testing RemoveMultipleMembersFromAlias\n");
1932 r.in.alias_handle = alias_handle;
1935 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1936 if (!NT_STATUS_IS_OK(status)) {
1937 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1941 /* strange! removing twice doesn't give any error */
1942 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1943 if (!NT_STATUS_IS_OK(status)) {
1944 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1948 /* but removing an alias that isn't there does */
1949 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1951 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1952 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1953 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1960 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1961 struct policy_handle *user_handle)
1963 struct samr_TestPrivateFunctionsUser r;
1967 printf("Testing TestPrivateFunctionsUser\n");
1969 r.in.user_handle = user_handle;
1971 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1972 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1973 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1981 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1982 struct policy_handle *user_handle,
1983 struct policy_handle *domain_handle,
1984 uint32_t base_acct_flags,
1985 const char *base_acct_name, enum torture_samr_choice which_ops)
1987 TALLOC_CTX *user_ctx;
1988 char *password = NULL;
1992 const uint32_t password_fields[] = {
1993 SAMR_FIELD_PASSWORD,
1994 SAMR_FIELD_PASSWORD2,
1995 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1999 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
2000 switch (which_ops) {
2001 case TORTURE_SAMR_USER_ATTRIBUTES:
2002 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
2006 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
2010 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
2014 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
2019 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
2023 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
2027 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
2031 case TORTURE_SAMR_PASSWORDS:
2032 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2033 char simple_pass[9];
2034 char *v = generate_random_str(mem_ctx, 1);
2036 ZERO_STRUCT(simple_pass);
2037 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2039 printf("Testing machine account password policy rules\n");
2041 /* Workstation trust accounts don't seem to need to honour password quality policy */
2042 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2046 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, simple_pass, False)) {
2050 /* reset again, to allow another 'user' password change */
2051 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2055 /* Try a 'short' password */
2056 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, samr_rand_pass(mem_ctx, 4), False)) {
2062 for (i = 0; password_fields[i]; i++) {
2063 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
2067 /* check it was set right */
2068 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2073 for (i = 0; password_fields[i]; i++) {
2074 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
2078 /* check it was set right */
2079 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2084 if (!test_SetUserPassEx(p, user_ctx, user_handle, false, &password)) {
2088 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
2093 case TORTURE_SAMR_OTHER:
2094 /* We just need the account to exist */
2097 talloc_free(user_ctx);
2101 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2102 struct policy_handle *alias_handle,
2103 const struct dom_sid *domain_sid)
2107 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
2111 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
2115 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
2119 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
2123 if (lp_parm_bool(-1, "torture", "samba4", False)) {
2124 printf("skipping MultipleMembers Alias tests against Samba4\n");
2128 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
2136 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2137 struct policy_handle *user_handle)
2139 struct samr_DeleteUser d;
2142 printf("Testing DeleteUser\n");
2144 d.in.user_handle = user_handle;
2145 d.out.user_handle = user_handle;
2147 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2148 if (!NT_STATUS_IS_OK(status)) {
2149 printf("DeleteUser failed - %s\n", nt_errstr(status));
2156 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2157 struct policy_handle *handle, const char *name)
2160 struct samr_DeleteUser d;
2161 struct policy_handle user_handle;
2164 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2165 if (!NT_STATUS_IS_OK(status)) {
2169 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2170 if (!NT_STATUS_IS_OK(status)) {
2174 d.in.user_handle = &user_handle;
2175 d.out.user_handle = &user_handle;
2176 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2177 if (!NT_STATUS_IS_OK(status)) {
2184 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2189 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2190 struct policy_handle *handle, const char *name)
2193 struct samr_OpenGroup r;
2194 struct samr_DeleteDomainGroup d;
2195 struct policy_handle group_handle;
2198 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2199 if (!NT_STATUS_IS_OK(status)) {
2203 r.in.domain_handle = handle;
2204 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2206 r.out.group_handle = &group_handle;
2207 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2208 if (!NT_STATUS_IS_OK(status)) {
2212 d.in.group_handle = &group_handle;
2213 d.out.group_handle = &group_handle;
2214 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2215 if (!NT_STATUS_IS_OK(status)) {
2222 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2227 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2228 struct policy_handle *domain_handle, const char *name)
2231 struct samr_OpenAlias r;
2232 struct samr_DeleteDomAlias d;
2233 struct policy_handle alias_handle;
2236 printf("testing DeleteAlias_byname\n");
2238 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2239 if (!NT_STATUS_IS_OK(status)) {
2243 r.in.domain_handle = domain_handle;
2244 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2246 r.out.alias_handle = &alias_handle;
2247 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2248 if (!NT_STATUS_IS_OK(status)) {
2252 d.in.alias_handle = &alias_handle;
2253 d.out.alias_handle = &alias_handle;
2254 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2255 if (!NT_STATUS_IS_OK(status)) {
2262 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2266 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2267 struct policy_handle *alias_handle)
2269 struct samr_DeleteDomAlias d;
2272 printf("Testing DeleteAlias\n");
2274 d.in.alias_handle = alias_handle;
2275 d.out.alias_handle = alias_handle;
2277 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2278 if (!NT_STATUS_IS_OK(status)) {
2279 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2286 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2287 struct policy_handle *domain_handle,
2288 struct policy_handle *alias_handle,
2289 const struct dom_sid *domain_sid)
2292 struct samr_CreateDomAlias r;
2293 struct lsa_String name;
2297 init_lsa_String(&name, TEST_ALIASNAME);
2298 r.in.domain_handle = domain_handle;
2299 r.in.alias_name = &name;
2300 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2301 r.out.alias_handle = alias_handle;
2304 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2306 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2308 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2309 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2313 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2314 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2317 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2320 if (!NT_STATUS_IS_OK(status)) {
2321 printf("CreateAlias failed - %s\n", nt_errstr(status));
2325 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2332 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2333 const char *acct_name,
2334 struct policy_handle *domain_handle, char **password)
2342 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2346 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, True)) {
2350 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2354 /* test what happens when setting the old password again */
2355 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2360 char simple_pass[9];
2361 char *v = generate_random_str(mem_ctx, 1);
2363 ZERO_STRUCT(simple_pass);
2364 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2366 /* test what happens when picking a simple password */
2367 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2372 /* set samr_SetDomainInfo level 1 with min_length 5 */
2374 struct samr_QueryDomainInfo r;
2375 struct samr_SetDomainInfo s;
2376 uint16_t len_old, len;
2377 uint32_t pwd_prop_old;
2378 int64_t min_pwd_age_old;
2383 r.in.domain_handle = domain_handle;
2386 printf("testing samr_QueryDomainInfo level 1\n");
2387 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2388 if (!NT_STATUS_IS_OK(status)) {
2392 s.in.domain_handle = domain_handle;
2394 s.in.info = r.out.info;
2396 /* remember the old min length, so we can reset it */
2397 len_old = s.in.info->info1.min_password_length;
2398 s.in.info->info1.min_password_length = len;
2399 pwd_prop_old = s.in.info->info1.password_properties;
2400 /* turn off password complexity checks for this test */
2401 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2403 min_pwd_age_old = s.in.info->info1.min_password_age;
2404 s.in.info->info1.min_password_age = 0;
2406 printf("testing samr_SetDomainInfo level 1\n");
2407 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2408 if (!NT_STATUS_IS_OK(status)) {
2412 printf("calling test_ChangePasswordUser3 with too short password\n");
2414 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2418 s.in.info->info1.min_password_length = len_old;
2419 s.in.info->info1.password_properties = pwd_prop_old;
2420 s.in.info->info1.min_password_age = min_pwd_age_old;
2422 printf("testing samr_SetDomainInfo level 1\n");
2423 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2424 if (!NT_STATUS_IS_OK(status)) {
2432 struct samr_OpenUser r;
2433 struct samr_QueryUserInfo q;
2434 struct samr_LookupNames n;
2435 struct policy_handle user_handle;
2437 n.in.domain_handle = domain_handle;
2439 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2440 n.in.names[0].string = acct_name;
2442 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2443 if (!NT_STATUS_IS_OK(status)) {
2444 printf("LookupNames failed - %s\n", nt_errstr(status));
2448 r.in.domain_handle = domain_handle;
2449 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2450 r.in.rid = n.out.rids.ids[0];
2451 r.out.user_handle = &user_handle;
2453 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2454 if (!NT_STATUS_IS_OK(status)) {
2455 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2459 q.in.user_handle = &user_handle;
2462 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2463 if (!NT_STATUS_IS_OK(status)) {
2464 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2468 printf("calling test_ChangePasswordUser3 with too early password change\n");
2470 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2471 q.out.info->info5.last_password_change, True)) {
2476 /* we change passwords twice - this has the effect of verifying
2477 they were changed correctly for the final call */
2478 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2482 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2489 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2490 struct policy_handle *domain_handle,
2491 struct policy_handle *user_handle_out,
2492 enum torture_samr_choice which_ops)
2495 TALLOC_CTX *user_ctx;
2498 struct samr_CreateUser r;
2499 struct samr_QueryUserInfo q;
2500 struct samr_DeleteUser d;
2503 /* This call creates a 'normal' account - check that it really does */
2504 const uint32_t acct_flags = ACB_NORMAL;
2505 struct lsa_String name;
2508 struct policy_handle user_handle;
2509 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2510 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2512 r.in.domain_handle = domain_handle;
2513 r.in.account_name = &name;
2514 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2515 r.out.user_handle = &user_handle;
2518 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2520 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2522 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2523 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2524 talloc_free(user_ctx);
2528 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2529 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2530 talloc_free(user_ctx);
2533 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2535 if (!NT_STATUS_IS_OK(status)) {
2536 talloc_free(user_ctx);
2537 printf("CreateUser failed - %s\n", nt_errstr(status));
2540 q.in.user_handle = &user_handle;
2543 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2544 if (!NT_STATUS_IS_OK(status)) {
2545 printf("QueryUserInfo level %u failed - %s\n",
2546 q.in.level, nt_errstr(status));
2549 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2550 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2551 q.out.info->info16.acct_flags,
2557 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2558 acct_flags, name.string, which_ops)) {
2562 if (user_handle_out) {
2563 *user_handle_out = user_handle;
2565 printf("Testing DeleteUser (createuser test)\n");
2567 d.in.user_handle = &user_handle;
2568 d.out.user_handle = &user_handle;
2570 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2571 if (!NT_STATUS_IS_OK(status)) {
2572 printf("DeleteUser failed - %s\n", nt_errstr(status));
2579 talloc_free(user_ctx);
2585 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2586 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2589 struct samr_CreateUser2 r;
2590 struct samr_QueryUserInfo q;
2591 struct samr_DeleteUser d;
2592 struct policy_handle user_handle;
2594 struct lsa_String name;
2599 uint32_t acct_flags;
2600 const char *account_name;
2602 } account_types[] = {
2603 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2604 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2605 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2606 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2607 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2608 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2609 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2610 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2611 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2612 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2613 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2614 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2615 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2616 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2617 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2620 for (i = 0; account_types[i].account_name; i++) {
2621 TALLOC_CTX *user_ctx;
2622 uint32_t acct_flags = account_types[i].acct_flags;
2623 uint32_t access_granted;
2624 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2625 init_lsa_String(&name, account_types[i].account_name);
2627 r.in.domain_handle = domain_handle;
2628 r.in.account_name = &name;
2629 r.in.acct_flags = acct_flags;
2630 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2631 r.out.user_handle = &user_handle;
2632 r.out.access_granted = &access_granted;
2635 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2637 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2639 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2640 talloc_free(user_ctx);
2641 printf("Server refused create of '%s'\n", r.in.account_name->string);
2644 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2645 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2646 talloc_free(user_ctx);
2650 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2653 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2654 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2655 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2659 if (NT_STATUS_IS_OK(status)) {
2660 q.in.user_handle = &user_handle;
2663 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2664 if (!NT_STATUS_IS_OK(status)) {
2665 printf("QueryUserInfo level %u failed - %s\n",
2666 q.in.level, nt_errstr(status));
2669 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2670 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2671 q.out.info->info5.acct_flags,
2675 switch (acct_flags) {
2677 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2678 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2679 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2684 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2685 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2686 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2691 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2692 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2693 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2700 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2701 acct_flags, name.string, which_ops)) {
2705 printf("Testing DeleteUser (createuser2 test)\n");
2707 d.in.user_handle = &user_handle;
2708 d.out.user_handle = &user_handle;
2710 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2711 if (!NT_STATUS_IS_OK(status)) {
2712 printf("DeleteUser failed - %s\n", nt_errstr(status));
2716 talloc_free(user_ctx);
2722 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2723 struct policy_handle *handle)
2726 struct samr_QueryAliasInfo r;
2727 uint16_t levels[] = {1, 2, 3};
2731 for (i=0;i<ARRAY_SIZE(levels);i++) {
2732 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2734 r.in.alias_handle = handle;
2735 r.in.level = levels[i];
2737 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2738 if (!NT_STATUS_IS_OK(status)) {
2739 printf("QueryAliasInfo level %u failed - %s\n",
2740 levels[i], nt_errstr(status));
2748 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2749 struct policy_handle *handle)
2752 struct samr_QueryGroupInfo r;
2753 uint16_t levels[] = {1, 2, 3, 4, 5};
2757 for (i=0;i<ARRAY_SIZE(levels);i++) {
2758 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2760 r.in.group_handle = handle;
2761 r.in.level = levels[i];
2763 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2764 if (!NT_STATUS_IS_OK(status)) {
2765 printf("QueryGroupInfo level %u failed - %s\n",
2766 levels[i], nt_errstr(status));
2774 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2775 struct policy_handle *handle)
2778 struct samr_QueryGroupMember r;
2781 printf("Testing QueryGroupMember\n");
2783 r.in.group_handle = handle;
2785 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2786 if (!NT_STATUS_IS_OK(status)) {
2787 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2795 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2796 struct policy_handle *handle)
2799 struct samr_QueryGroupInfo r;
2800 struct samr_SetGroupInfo s;
2801 uint16_t levels[] = {1, 2, 3, 4};
2802 uint16_t set_ok[] = {0, 1, 1, 1};
2806 for (i=0;i<ARRAY_SIZE(levels);i++) {
2807 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2809 r.in.group_handle = handle;
2810 r.in.level = levels[i];
2812 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2813 if (!NT_STATUS_IS_OK(status)) {
2814 printf("QueryGroupInfo level %u failed - %s\n",
2815 levels[i], nt_errstr(status));
2819 printf("Testing SetGroupInfo level %u\n", levels[i]);
2821 s.in.group_handle = handle;
2822 s.in.level = levels[i];
2823 s.in.info = r.out.info;
2826 /* disabled this, as it changes the name only from the point of view of samr,
2827 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2828 the name is still reserved, so creating the old name fails, but deleting by the old name
2830 if (s.in.level == 2) {
2831 init_lsa_String(&s.in.info->string, "NewName");
2835 if (s.in.level == 4) {
2836 init_lsa_String(&s.in.info->description, "test description");
2839 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2841 if (!NT_STATUS_IS_OK(status)) {
2842 printf("SetGroupInfo level %u failed - %s\n",
2843 r.in.level, nt_errstr(status));
2848 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2849 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2850 r.in.level, nt_errstr(status));
2860 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2861 struct policy_handle *handle)
2864 struct samr_QueryUserInfo r;
2865 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2866 11, 12, 13, 14, 16, 17, 20, 21};
2870 for (i=0;i<ARRAY_SIZE(levels);i++) {
2871 printf("Testing QueryUserInfo level %u\n", levels[i]);
2873 r.in.user_handle = handle;
2874 r.in.level = levels[i];
2876 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2877 if (!NT_STATUS_IS_OK(status)) {
2878 printf("QueryUserInfo level %u failed - %s\n",
2879 levels[i], nt_errstr(status));
2887 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2888 struct policy_handle *handle)
2891 struct samr_QueryUserInfo2 r;
2892 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2893 11, 12, 13, 14, 16, 17, 20, 21};
2897 for (i=0;i<ARRAY_SIZE(levels);i++) {
2898 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2900 r.in.user_handle = handle;
2901 r.in.level = levels[i];
2903 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2904 if (!NT_STATUS_IS_OK(status)) {
2905 printf("QueryUserInfo2 level %u failed - %s\n",
2906 levels[i], nt_errstr(status));
2914 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2915 struct policy_handle *handle, uint32_t rid)
2918 struct samr_OpenUser r;
2919 struct policy_handle user_handle;
2922 printf("Testing OpenUser(%u)\n", rid);
2924 r.in.domain_handle = handle;
2925 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2927 r.out.user_handle = &user_handle;
2929 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2930 if (!NT_STATUS_IS_OK(status)) {
2931 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2935 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2939 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2943 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2947 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2951 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2955 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2962 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2963 struct policy_handle *handle, uint32_t rid)
2966 struct samr_OpenGroup r;
2967 struct policy_handle group_handle;
2970 printf("Testing OpenGroup(%u)\n", rid);
2972 r.in.domain_handle = handle;
2973 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2975 r.out.group_handle = &group_handle;
2977 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2978 if (!NT_STATUS_IS_OK(status)) {
2979 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2983 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2987 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2991 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2995 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3002 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3003 struct policy_handle *handle, uint32_t rid)
3006 struct samr_OpenAlias r;
3007 struct policy_handle alias_handle;
3010 printf("Testing OpenAlias(%u)\n", rid);
3012 r.in.domain_handle = handle;
3013 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3015 r.out.alias_handle = &alias_handle;
3017 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3018 if (!NT_STATUS_IS_OK(status)) {
3019 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3023 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3027 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3031 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3035 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3042 static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3043 struct policy_handle *handle, uint32_t rid,
3044 uint32_t acct_flag_mask)
3047 struct samr_OpenUser r;
3048 struct samr_QueryUserInfo q;
3049 struct policy_handle user_handle;
3052 printf("Testing OpenUser(%u)\n", rid);
3054 r.in.domain_handle = handle;
3055 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3057 r.out.user_handle = &user_handle;
3059 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3060 if (!NT_STATUS_IS_OK(status)) {
3061 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3065 q.in.user_handle = &user_handle;
3068 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3069 if (!NT_STATUS_IS_OK(status)) {
3070 printf("QueryUserInfo level 16 failed - %s\n",
3074 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3075 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3076 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3081 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3088 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3089 struct policy_handle *handle)
3091 NTSTATUS status = STATUS_MORE_ENTRIES;
3092 struct samr_EnumDomainUsers r;
3093 uint32_t mask, resume_handle=0;
3096 struct samr_LookupNames n;
3097 struct samr_LookupRids lr ;
3098 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3099 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3100 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3103 printf("Testing EnumDomainUsers\n");
3105 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3106 r.in.domain_handle = handle;
3107 r.in.resume_handle = &resume_handle;
3108 r.in.acct_flags = mask = masks[mask_idx];
3109 r.in.max_size = (uint32_t)-1;
3110 r.out.resume_handle = &resume_handle;
3112 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3113 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3114 !NT_STATUS_IS_OK(status)) {
3115 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3120 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3124 if (r.out.sam->count == 0) {
3128 for (i=0;i<r.out.sam->count;i++) {
3130 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3133 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3139 printf("Testing LookupNames\n");
3140 n.in.domain_handle = handle;
3141 n.in.num_names = r.out.sam->count;
3142 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3143 for (i=0;i<r.out.sam->count;i++) {
3144 n.in.names[i].string = r.out.sam->entries[i].name.string;
3146 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3147 if (!NT_STATUS_IS_OK(status)) {
3148 printf("LookupNames failed - %s\n", nt_errstr(status));
3153 printf("Testing LookupRids\n");
3154 lr.in.domain_handle = handle;
3155 lr.in.num_rids = r.out.sam->count;
3156 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3157 for (i=0;i<r.out.sam->count;i++) {
3158 lr.in.rids[i] = r.out.sam->entries[i].idx;
3160 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3161 if (!NT_STATUS_IS_OK(status)) {
3162 printf("LookupRids failed - %s\n", nt_errstr(status));
3170 try blasting the server with a bunch of sync requests
3172 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3173 struct policy_handle *handle)
3176 struct samr_EnumDomainUsers r;
3177 uint32_t resume_handle=0;
3179 #define ASYNC_COUNT 100
3180 struct rpc_request *req[ASYNC_COUNT];
3182 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
3183 printf("samr async test disabled - enable dangerous tests to use\n");
3187 printf("Testing EnumDomainUsers_async\n");
3189 r.in.domain_handle = handle;
3190 r.in.resume_handle = &resume_handle;
3191 r.in.acct_flags = 0;
3192 r.in.max_size = (uint32_t)-1;
3193 r.out.resume_handle = &resume_handle;
3195 for (i=0;i<ASYNC_COUNT;i++) {
3196 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
3199 for (i=0;i<ASYNC_COUNT;i++) {
3200 status = dcerpc_ndr_request_recv(req[i]);
3201 if (!NT_STATUS_IS_OK(status)) {
3202 printf("EnumDomainUsers[%d] failed - %s\n",
3203 i, nt_errstr(status));
3208 printf("%d async requests OK\n", i);
3213 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3214 struct policy_handle *handle)
3217 struct samr_EnumDomainGroups r;
3218 uint32_t resume_handle=0;
3222 printf("Testing EnumDomainGroups\n");
3224 r.in.domain_handle = handle;
3225 r.in.resume_handle = &resume_handle;
3226 r.in.max_size = (uint32_t)-1;
3227 r.out.resume_handle = &resume_handle;
3229 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3230 if (!NT_STATUS_IS_OK(status)) {
3231 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3239 for (i=0;i<r.out.sam->count;i++) {
3240 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3248 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3249 struct policy_handle *handle)
3252 struct samr_EnumDomainAliases r;
3253 uint32_t resume_handle=0;
3257 printf("Testing EnumDomainAliases\n");
3259 r.in.domain_handle = handle;
3260 r.in.resume_handle = &resume_handle;
3261 r.in.acct_flags = (uint32_t)-1;
3262 r.out.resume_handle = &resume_handle;
3264 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3265 if (!NT_STATUS_IS_OK(status)) {
3266 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3274 for (i=0;i<r.out.sam->count;i++) {
3275 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3283 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3284 struct policy_handle *handle)
3287 struct samr_GetDisplayEnumerationIndex r;
3289 uint16_t levels[] = {1, 2, 3, 4, 5};
3290 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3293 for (i=0;i<ARRAY_SIZE(levels);i++) {
3294 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3296 r.in.domain_handle = handle;
3297 r.in.level = levels[i];
3298 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3300 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3303 !NT_STATUS_IS_OK(status) &&
3304 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3305 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3306 levels[i], nt_errstr(status));
3310 init_lsa_String(&r.in.name, "zzzzzzzz");
3312 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3314 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3315 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3316 levels[i], nt_errstr(status));
3324 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3325 struct policy_handle *handle)
3328 struct samr_GetDisplayEnumerationIndex2 r;
3330 uint16_t levels[] = {1, 2, 3, 4, 5};
3331 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3334 for (i=0;i<ARRAY_SIZE(levels);i++) {
3335 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3337 r.in.domain_handle = handle;
3338 r.in.level = levels[i];
3339 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3341 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3343 !NT_STATUS_IS_OK(status) &&
3344 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3345 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3346 levels[i], nt_errstr(status));
3350 init_lsa_String(&r.in.name, "zzzzzzzz");
3352 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3353 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3354 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3355 levels[i], nt_errstr(status));
3363 #define STRING_EQUAL_QUERY(s1, s2, user) \
3364 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3365 /* odd, but valid */ \
3366 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3367 printf("%s mismatch for %s: %s != %s (%s)\n", \
3368 #s1, user.string, s1.string, s2.string, __location__); \
3371 #define INT_EQUAL_QUERY(s1, s2, user) \
3373 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3374 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3378 static BOOL test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3379 struct samr_QueryDisplayInfo *querydisplayinfo,
3380 bool *seen_testuser)
3382 struct samr_OpenUser r;
3383 struct samr_QueryUserInfo q;
3384 struct policy_handle user_handle;
3387 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3388 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3389 for (i = 0; ; i++) {
3390 switch (querydisplayinfo->in.level) {
3392 if (i >= querydisplayinfo->out.info.info1.count) {
3395 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3398 if (i >= querydisplayinfo->out.info.info2.count) {
3401 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3407 /* Not interested in validating just the account name */
3411 r.out.user_handle = &user_handle;
3413 switch (querydisplayinfo->in.level) {
3416 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3417 if (!NT_STATUS_IS_OK(status)) {
3418 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3423 q.in.user_handle = &user_handle;
3425 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3426 if (!NT_STATUS_IS_OK(status)) {
3427 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3431 switch (querydisplayinfo->in.level) {
3433 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3434 *seen_testuser = true;
3436 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3437 q.out.info->info21.full_name, q.out.info->info21.account_name);
3438 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3439 q.out.info->info21.account_name, q.out.info->info21.account_name);
3440 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3441 q.out.info->info21.description, q.out.info->info21.account_name);
3442 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3443 q.out.info->info21.rid, q.out.info->info21.account_name);
3444 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3445 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3449 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3450 q.out.info->info21.account_name, q.out.info->info21.account_name);
3451 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3452 q.out.info->info21.description, q.out.info->info21.account_name);
3453 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3454 q.out.info->info21.rid, q.out.info->info21.account_name);
3455 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3456 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3458 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3459 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3460 q.out.info->info21.account_name.string);
3463 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3464 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3465 q.out.info->info21.account_name.string,
3466 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3467 q.out.info->info21.acct_flags);
3474 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3481 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3482 struct policy_handle *handle)
3485 struct samr_QueryDisplayInfo r;
3486 struct samr_QueryDomainInfo dom_info;
3488 uint16_t levels[] = {1, 2, 3, 4, 5};
3490 bool seen_testuser = false;
3492 for (i=0;i<ARRAY_SIZE(levels);i++) {
3493 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3496 status = STATUS_MORE_ENTRIES;
3497 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3498 r.in.domain_handle = handle;
3499 r.in.level = levels[i];
3500 r.in.max_entries = 2;
3501 r.in.buf_size = (uint32_t)-1;
3503 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3504 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3505 printf("QueryDisplayInfo level %u failed - %s\n",
3506 levels[i], nt_errstr(status));
3509 switch (r.in.level) {
3511 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3514 r.in.start_idx += r.out.info.info1.count;
3517 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3520 r.in.start_idx += r.out.info.info2.count;
3523 r.in.start_idx += r.out.info.info3.count;
3526 r.in.start_idx += r.out.info.info4.count;
3529 r.in.start_idx += r.out.info.info5.count;
3533 dom_info.in.domain_handle = handle;
3534 dom_info.in.level = 2;
3535 /* Check number of users returned is correct */
3536 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3537 if (!NT_STATUS_IS_OK(status)) {
3538 printf("QueryDomainInfo level %u failed - %s\n",
3539 r.in.level, nt_errstr(status));
3543 switch (r.in.level) {
3546 if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3547 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3548 r.in.start_idx, dom_info.out.info->info2.num_groups,
3549 dom_info.out.info->info2.domain_name.string);
3552 if (!seen_testuser) {
3553 struct policy_handle user_handle;
3554 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3555 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3556 dom_info.out.info->info2.domain_name.string);
3558 test_samr_handle_Close(p, mem_ctx, &user_handle);
3564 if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3565 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3566 r.in.start_idx, dom_info.out.info->info2.num_groups,
3567 dom_info.out.info->info2.domain_name.string);
3579 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3580 struct policy_handle *handle)
3583 struct samr_QueryDisplayInfo2 r;
3585 uint16_t levels[] = {1, 2, 3, 4, 5};
3588 for (i=0;i<ARRAY_SIZE(levels);i++) {
3589 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3591 r.in.domain_handle = handle;
3592 r.in.level = levels[i];
3594 r.in.max_entries = 1000;
3595 r.in.buf_size = (uint32_t)-1;
3597 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3598 if (!NT_STATUS_IS_OK(status)) {
3599 printf("QueryDisplayInfo2 level %u failed - %s\n",
3600 levels[i], nt_errstr(status));
3608 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3609 struct policy_handle *handle)
3612 struct samr_QueryDisplayInfo3 r;
3614 uint16_t levels[] = {1, 2, 3, 4, 5};
3617 for (i=0;i<ARRAY_SIZE(levels);i++) {
3618 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3620 r.in.domain_handle = handle;
3621 r.in.level = levels[i];
3623 r.in.max_entries = 1000;
3624 r.in.buf_size = (uint32_t)-1;
3626 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3627 if (!NT_STATUS_IS_OK(status)) {
3628 printf("QueryDisplayInfo3 level %u failed - %s\n",
3629 levels[i], nt_errstr(status));
3638 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3639 struct policy_handle *handle)
3642 struct samr_QueryDisplayInfo r;
3645 printf("Testing QueryDisplayInfo continuation\n");
3647 r.in.domain_handle = handle;
3650 r.in.max_entries = 1;
3651 r.in.buf_size = (uint32_t)-1;
3654 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3655 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3656 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3657 printf("expected idx %d but got %d\n",
3659 r.out.info.info1.entries[0].idx);
3663 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3664 !NT_STATUS_IS_OK(status)) {
3665 printf("QueryDisplayInfo level %u failed - %s\n",
3666 r.in.level, nt_errstr(status));
3671 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3672 NT_STATUS_IS_OK(status)) &&
3673 r.out.returned_size != 0);
3678 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3679 struct policy_handle *handle)
3682 struct samr_QueryDomainInfo r;
3683 struct samr_SetDomainInfo s;
3684 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3685 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3688 const char *domain_comment = talloc_asprintf(mem_ctx,
3689 "Tortured by Samba4 RPC-SAMR: %s",
3690 timestring(mem_ctx, time(NULL)));
3692 s.in.domain_handle = handle;
3694 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3696 s.in.info->info4.comment.string = domain_comment;
3697 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3698 if (!NT_STATUS_IS_OK(status)) {
3699 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3700 r.in.level, nt_errstr(status));
3704 for (i=0;i<ARRAY_SIZE(levels);i++) {
3705 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3707 r.in.domain_handle = handle;
3708 r.in.level = levels[i];
3710 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3711 if (!NT_STATUS_IS_OK(status)) {
3712 printf("QueryDomainInfo level %u failed - %s\n",
3713 r.in.level, nt_errstr(status));
3718 switch (levels[i]) {
3720 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3721 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3722 levels[i], r.out.info->info2.comment.string, domain_comment);
3725 if (!r.out.info->info2.primary.string) {
3726 printf("QueryDomainInfo level %u returned no PDC name\n",
3729 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3730 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3731 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3732 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3737 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3738 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3739 levels[i], r.out.info->info4.comment.string, domain_comment);
3744 if (!r.out.info->info6.primary.string) {
3745 printf("QueryDomainInfo level %u returned no PDC name\n",
3751 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3752 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3753 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3759 printf("Testing SetDomainInfo level %u\n", levels[i]);
3761 s.in.domain_handle = handle;
3762 s.in.level = levels[i];
3763 s.in.info = r.out.info;
3765 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3767 if (!NT_STATUS_IS_OK(status)) {
3768 printf("SetDomainInfo level %u failed - %s\n",
3769 r.in.level, nt_errstr(status));
3774 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3775 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3776 r.in.level, nt_errstr(status));
3782 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3783 if (!NT_STATUS_IS_OK(status)) {
3784 printf("QueryDomainInfo level %u failed - %s\n",
3785 r.in.level, nt_errstr(status));
3795 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3796 struct policy_handle *handle)
3799 struct samr_QueryDomainInfo2 r;
3800 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3804 for (i=0;i<ARRAY_SIZE(levels);i++) {
3805 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3807 r.in.domain_handle = handle;
3808 r.in.level = levels[i];
3810 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3811 if (!NT_STATUS_IS_OK(status)) {
3812 printf("QueryDomainInfo2 level %u failed - %s\n",
3813 r.in.level, nt_errstr(status));
3822 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3823 set of group names. */
3824 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3825 struct policy_handle *handle)
3827 struct samr_EnumDomainGroups q1;
3828 struct samr_QueryDisplayInfo q2;
3830 uint32_t resume_handle=0;
3835 const char **names = NULL;
3837 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3839 q1.in.domain_handle = handle;
3840 q1.in.resume_handle = &resume_handle;
3842 q1.out.resume_handle = &resume_handle;
3844 status = STATUS_MORE_ENTRIES;
3845 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3846 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3848 if (!NT_STATUS_IS_OK(status) &&
3849 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3852 for (i=0; i<q1.out.num_entries; i++) {
3853 add_string_to_array(mem_ctx,
3854 q1.out.sam->entries[i].name.string,
3855 &names, &num_names);
3859 if (!NT_STATUS_IS_OK(status)) {
3860 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3868 q2.in.domain_handle = handle;
3870 q2.in.start_idx = 0;
3871 q2.in.max_entries = 5;
3872 q2.in.buf_size = (uint32_t)-1;
3874 status = STATUS_MORE_ENTRIES;
3875 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3876 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3878 if (!NT_STATUS_IS_OK(status) &&
3879 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3882 for (i=0; i<q2.out.info.info5.count; i++) {
3884 const char *name = q2.out.info.info5.entries[i].account_name.string;
3886 for (j=0; j<num_names; j++) {
3887 if (names[j] == NULL)
3889 /* Hmm. No strequal in samba4 */
3890 if (strequal(names[j], name)) {
3898 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3903 q2.in.start_idx += q2.out.info.info5.count;
3906 if (!NT_STATUS_IS_OK(status)) {
3907 printf("QueryDisplayInfo level 5 failed - %s\n",
3912 for (i=0; i<num_names; i++) {
3913 if (names[i] != NULL) {
3914 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3923 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3924 struct policy_handle *group_handle)
3926 struct samr_DeleteDomainGroup d;
3930 printf("Testing DeleteDomainGroup\n");
3932 d.in.group_handle = group_handle;
3933 d.out.group_handle = group_handle;
3935 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3944 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3945 struct policy_handle *domain_handle)
3947 struct samr_TestPrivateFunctionsDomain r;
3951 printf("Testing TestPrivateFunctionsDomain\n");
3953 r.in.domain_handle = domain_handle;
3955 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3956 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3957 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3964 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3965 struct dom_sid *domain_sid,
3966 struct policy_handle *domain_handle)
3968 struct samr_RidToSid r;
3971 struct dom_sid *calc_sid;
3972 int rids[] = { 0, 42, 512, 10200 };
3975 for (i=0;i<ARRAY_SIZE(rids);i++) {
3977 printf("Testing RidToSid\n");
3979 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3980 r.in.domain_handle = domain_handle;
3983 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3984 if (!NT_STATUS_IS_OK(status)) {
3985 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3988 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3990 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3991 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3992 dom_sid_string(mem_ctx, r.out.sid),
3993 dom_sid_string(mem_ctx, calc_sid));
4002 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4003 struct policy_handle *domain_handle)
4005 struct samr_GetBootKeyInformation r;
4009 printf("Testing GetBootKeyInformation\n");
4011 r.in.domain_handle = domain_handle;
4013 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4014 if (!NT_STATUS_IS_OK(status)) {
4015 /* w2k3 seems to fail this sometimes and pass it sometimes */
4016 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4022 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4023 struct policy_handle *domain_handle,
4024 struct policy_handle *group_handle)
4027 struct samr_AddGroupMember r;
4028 struct samr_DeleteGroupMember d;
4029 struct samr_QueryGroupMember q;
4030 struct samr_SetMemberAttributesOfGroup s;
4034 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4035 if (!NT_STATUS_IS_OK(status)) {
4036 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4040 r.in.group_handle = group_handle;
4042 r.in.flags = 0; /* ??? */
4044 printf("Testing AddGroupMember and DeleteGroupMember\n");
4046 d.in.group_handle = group_handle;
4049 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
4050 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4051 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4056 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4062 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4063 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4064 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4069 if (lp_parm_bool(-1, "torture", "samba4", False)) {
4070 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4072 /* this one is quite strange. I am using random inputs in the
4073 hope of triggering an error that might give us a clue */
4075 s.in.group_handle = group_handle;
4076 s.in.unknown1 = random();
4077 s.in.unknown2 = random();
4079 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4086 q.in.group_handle = group_handle;
4088 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
4089 if (!NT_STATUS_IS_OK(status)) {
4090 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4094 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
4095 if (!NT_STATUS_IS_OK(status)) {
4096 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4100 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4101 if (!NT_STATUS_IS_OK(status)) {
4102 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4110 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4111 struct policy_handle *domain_handle, struct policy_handle *group_handle)
4114 struct samr_CreateDomainGroup r;
4116 struct lsa_String name;
4119 init_lsa_String(&name, TEST_GROUPNAME);
4121 r.in.domain_handle = domain_handle;
4123 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4124 r.out.group_handle = group_handle;
4127 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4129 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4131 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4132 printf("Server refused create of '%s'\n", r.in.name->string);
4133 ZERO_STRUCTP(group_handle);
4137 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4138 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4140 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4144 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4146 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4147 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4149 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4153 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4155 if (!NT_STATUS_IS_OK(status)) {
4156 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4160 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4161 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4165 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4174 its not totally clear what this does. It seems to accept any sid you like.
4176 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4177 TALLOC_CTX *mem_ctx,
4178 struct policy_handle *domain_handle)
4181 struct samr_RemoveMemberFromForeignDomain r;
4183 r.in.domain_handle = domain_handle;
4184 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4186 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4187 if (!NT_STATUS_IS_OK(status)) {
4188 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4197 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4198 struct policy_handle *handle);
4200 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4201 struct policy_handle *handle, struct dom_sid *sid,
4202 enum torture_samr_choice which_ops)
4205 struct samr_OpenDomain r;
4206 struct policy_handle domain_handle;
4207 struct policy_handle alias_handle;
4208 struct policy_handle user_handle;
4209 struct policy_handle group_handle;
4212 ZERO_STRUCT(alias_handle);
4213 ZERO_STRUCT(user_handle);
4214 ZERO_STRUCT(group_handle);
4215 ZERO_STRUCT(domain_handle);
4217 printf("Testing OpenDomain\n");
4219 r.in.connect_handle = handle;
4220 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4222 r.out.domain_handle = &domain_handle;
4224 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
4225 if (!NT_STATUS_IS_OK(status)) {
4226 printf("OpenDomain failed - %s\n", nt_errstr(status));
4230 /* run the domain tests with the main handle closed - this tests
4231 the servers reference counting */
4232 ret &= test_samr_handle_Close(p, mem_ctx, handle);
4234 switch (which_ops) {
4235 case TORTURE_SAMR_USER_ATTRIBUTES:
4236 case TORTURE_SAMR_PASSWORDS:
4237 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
4238 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4239 /* This test needs 'complex' users to validate */
4240 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
4242 case TORTURE_SAMR_OTHER:
4243 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4244 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
4245 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
4246 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
4247 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
4248 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
4249 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
4250 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
4251 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
4252 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
4253 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
4254 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
4255 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
4256 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
4258 if (lp_parm_bool(-1, "torture", "samba4", False)) {
4259 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4261 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
4262 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
4264 ret &= test_GroupList(p, mem_ctx, &domain_handle);
4265 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
4266 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
4267 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
4271 if (!policy_handle_empty(&user_handle) &&
4272 !test_DeleteUser(p, mem_ctx, &user_handle)) {
4276 if (!policy_handle_empty(&alias_handle) &&
4277 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
4281 if (!policy_handle_empty(&group_handle) &&
4282 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
4286 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
4288 /* reconnect the main handle */
4289 ret &= test_Connect(p, mem_ctx, handle);
4292 printf("Testing domain %s failed!\n", dom_sid_string(mem_ctx, sid));
4298 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4299 struct policy_handle *handle, const char *domain,
4300 enum torture_samr_choice which_ops)
4303 struct samr_LookupDomain r;
4304 struct lsa_String n1;
4305 struct lsa_String n2;
4308 printf("Testing LookupDomain(%s)\n", domain);
4310 /* check for correct error codes */
4311 r.in.connect_handle = handle;
4312 r.in.domain_name = &n2;
4315 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4316 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4317 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4321 init_lsa_String(&n2, "xxNODOMAINxx");
4323 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4324 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4325 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4329 r.in.connect_handle = handle;
4331 init_lsa_String(&n1, domain);
4332 r.in.domain_name = &n1;
4334 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4335 if (!NT_STATUS_IS_OK(status)) {
4336 printf("LookupDomain failed - %s\n", nt_errstr(status));
4340 if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
4344 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
4352 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4353 struct policy_handle *handle, enum torture_samr_choice which_ops)
4356 struct samr_EnumDomains r;
4357 uint32_t resume_handle = 0;
4361 r.in.connect_handle = handle;
4362 r.in.resume_handle = &resume_handle;
4363 r.in.buf_size = (uint32_t)-1;
4364 r.out.resume_handle = &resume_handle;
4366 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4367 if (!NT_STATUS_IS_OK(status)) {
4368 printf("EnumDomains failed - %s\n", nt_errstr(status));
4376 for (i=0;i<r.out.sam->count;i++) {
4377 if (!test_LookupDomain(p, mem_ctx, handle,
4378 r.out.sam->entries[i].name.string, which_ops)) {
4383 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4384 if (!NT_STATUS_IS_OK(status)) {
4385 printf("EnumDomains failed - %s\n", nt_errstr(status));
4393 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4394 struct policy_handle *handle)
4397 struct samr_Connect r;
4398 struct samr_Connect2 r2;
4399 struct samr_Connect3 r3;
4400 struct samr_Connect4 r4;
4401 struct samr_Connect5 r5;
4402 union samr_ConnectInfo info;
4403 struct policy_handle h;
4404 BOOL ret = True, got_handle = False;
4406 printf("testing samr_Connect\n");
4408 r.in.system_name = 0;
4409 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4410 r.out.connect_handle = &h;
4412 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4413 if (!NT_STATUS_IS_OK(status)) {
4414 printf("Connect failed - %s\n", nt_errstr(status));
4421 printf("testing samr_Connect2\n");
4423 r2.in.system_name = NULL;
4424 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4425 r2.out.connect_handle = &h;
4427 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4428 if (!NT_STATUS_IS_OK(status)) {
4429 printf("Connect2 failed - %s\n", nt_errstr(status));
4433 test_samr_handle_Close(p, mem_ctx, handle);
4439 printf("testing samr_Connect3\n");
4441 r3.in.system_name = NULL;
4443 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4444 r3.out.connect_handle = &h;
4446 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4447 if (!NT_STATUS_IS_OK(status)) {
4448 printf("Connect3 failed - %s\n", nt_errstr(status));
4452 test_samr_handle_Close(p, mem_ctx, handle);
4458 printf("testing samr_Connect4\n");
4460 r4.in.system_name = "";
4462 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4463 r4.out.connect_handle = &h;
4465 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4466 if (!NT_STATUS_IS_OK(status)) {
4467 printf("Connect4 failed - %s\n", nt_errstr(status));
4471 test_samr_handle_Close(p, mem_ctx, handle);
4477 printf("testing samr_Connect5\n");
4479 info.info1.unknown1 = 0;
4480 info.info1.unknown2 = 0;
4482 r5.in.system_name = "";
4483 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4486 r5.out.info = &info;
4487 r5.out.connect_handle = &h;
4489 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4490 if (!NT_STATUS_IS_OK(status)) {
4491 printf("Connect5 failed - %s\n", nt_errstr(status));
4495 test_samr_handle_Close(p, mem_ctx, handle);
4505 BOOL torture_rpc_samr(struct torture_context *torture)
4508 struct dcerpc_pipe *p;
4510 struct policy_handle handle;
4512 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4513 if (!NT_STATUS_IS_OK(status)) {
4517 ret &= test_Connect(p, torture, &handle);
4519 ret &= test_QuerySecurity(p, torture, &handle);
4521 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4523 ret &= test_SetDsrmPassword(p, torture, &handle);
4525 ret &= test_Shutdown(p, torture, &handle);
4527 ret &= test_samr_handle_Close(p, torture, &handle);
4533 BOOL torture_rpc_samr_users(struct torture_context *torture)
4536 struct dcerpc_pipe *p;
4538 struct policy_handle handle;
4540 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4541 if (!NT_STATUS_IS_OK(status)) {
4545 ret &= test_Connect(p, torture, &handle);
4547 ret &= test_QuerySecurity(p, torture, &handle);
4549 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4551 ret &= test_SetDsrmPassword(p, torture, &handle);
4553 ret &= test_Shutdown(p, torture, &handle);
4555 ret &= test_samr_handle_Close(p, torture, &handle);
4561 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
4564 struct dcerpc_pipe *p;
4566 struct policy_handle handle;
4568 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4569 if (!NT_STATUS_IS_OK(status)) {
4573 ret &= test_Connect(p, torture, &handle);
4575 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4577 ret &= test_samr_handle_Close(p, torture, &handle);