2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
63 struct policy_handle *handle)
69 r.out.handle = handle;
71 status = dcerpc_samr_Close(p, mem_ctx, &r);
72 if (!NT_STATUS_IS_OK(status)) {
73 printf("Close handle failed - %s\n", nt_errstr(status));
80 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
81 struct policy_handle *handle)
84 struct samr_Shutdown r;
86 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
87 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
91 r.in.connect_handle = handle;
93 printf("testing samr_Shutdown\n");
95 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
96 if (!NT_STATUS_IS_OK(status)) {
97 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
104 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
105 struct policy_handle *handle)
108 struct samr_SetDsrmPassword r;
109 struct lsa_String string;
110 struct samr_Password hash;
112 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
113 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 printf("testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
128 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
129 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
137 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
138 struct policy_handle *handle)
141 struct samr_QuerySecurity r;
142 struct samr_SetSecurity s;
144 r.in.handle = handle;
147 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
148 if (!NT_STATUS_IS_OK(status)) {
149 printf("QuerySecurity failed - %s\n", nt_errstr(status));
153 if (r.out.sdbuf == NULL) {
157 s.in.handle = handle;
159 s.in.sdbuf = r.out.sdbuf;
161 if (lp_parm_bool(-1, "torture", "samba4", False)) {
162 printf("skipping SetSecurity test against Samba4\n");
166 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
167 if (!NT_STATUS_IS_OK(status)) {
168 printf("SetSecurity failed - %s\n", nt_errstr(status));
172 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
173 if (!NT_STATUS_IS_OK(status)) {
174 printf("QuerySecurity failed - %s\n", nt_errstr(status));
182 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
183 struct policy_handle *handle, uint32_t base_acct_flags,
184 const char *base_account_name)
187 struct samr_SetUserInfo s;
188 struct samr_SetUserInfo2 s2;
189 struct samr_QueryUserInfo q;
190 struct samr_QueryUserInfo q0;
191 union samr_UserInfo u;
193 const char *test_account_name;
195 uint32_t user_extra_flags = 0;
196 if (base_acct_flags == ACB_NORMAL) {
197 /* When created, accounts are expired by default */
198 user_extra_flags = ACB_PW_EXPIRED;
201 s.in.user_handle = handle;
204 s2.in.user_handle = handle;
207 q.in.user_handle = handle;
211 #define TESTCALL(call, r) \
212 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
213 if (!NT_STATUS_IS_OK(status)) { \
214 printf(#call " level %u failed - %s (%s)\n", \
215 r.in.level, nt_errstr(status), __location__); \
220 #define STRING_EQUAL(s1, s2, field) \
221 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
222 printf("Failed to set %s to '%s' (%s)\n", \
223 #field, s2, __location__); \
228 #define INT_EQUAL(i1, i2, field) \
230 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
231 #field, i2, i1, __location__); \
236 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
237 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
239 TESTCALL(QueryUserInfo, q) \
241 s2.in.level = lvl1; \
244 ZERO_STRUCT(u.info21); \
245 u.info21.fields_present = fpval; \
247 init_lsa_String(&u.info ## lvl1.field1, value); \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 init_lsa_String(&u.info ## lvl1.field1, ""); \
251 TESTCALL(QueryUserInfo, q); \
253 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
255 TESTCALL(QueryUserInfo, q) \
257 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
261 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
263 TESTCALL(QueryUserInfo, q) \
265 s2.in.level = lvl1; \
268 uint8_t *bits = u.info21.logon_hours.bits; \
269 ZERO_STRUCT(u.info21); \
270 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
271 u.info21.logon_hours.units_per_week = 168; \
272 u.info21.logon_hours.bits = bits; \
274 u.info21.fields_present = fpval; \
276 u.info ## lvl1.field1 = value; \
277 TESTCALL(SetUserInfo, s) \
278 TESTCALL(SetUserInfo2, s2) \
279 u.info ## lvl1.field1 = 0; \
280 TESTCALL(QueryUserInfo, q); \
282 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
284 TESTCALL(QueryUserInfo, q) \
286 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
289 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
290 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
294 do { TESTCALL(QueryUserInfo, q0) } while (0);
296 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
297 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
298 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
301 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
302 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
303 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
304 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
305 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
306 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
307 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
308 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
309 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
310 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
311 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
312 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
313 test_account_name = base_account_name;
314 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
315 SAMR_FIELD_ACCOUNT_NAME);
317 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
318 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
319 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
323 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
324 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
325 SAMR_FIELD_FULL_NAME);
327 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
328 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
329 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
333 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
334 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
335 SAMR_FIELD_FULL_NAME);
337 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
338 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
339 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
340 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
341 SAMR_FIELD_LOGON_SCRIPT);
343 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
344 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
345 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
346 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
347 SAMR_FIELD_PROFILE_PATH);
349 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
350 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
351 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
352 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
353 SAMR_FIELD_HOME_DIRECTORY);
354 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
355 SAMR_FIELD_HOME_DIRECTORY);
357 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
358 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
359 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
360 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
361 SAMR_FIELD_HOME_DRIVE);
362 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
363 SAMR_FIELD_HOME_DRIVE);
365 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
366 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
367 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
368 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
369 SAMR_FIELD_DESCRIPTION);
371 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
372 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
373 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
374 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
375 SAMR_FIELD_WORKSTATIONS);
377 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
378 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
379 SAMR_FIELD_PARAMETERS);
381 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
382 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
383 SAMR_FIELD_COUNTRY_CODE);
385 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
386 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
387 SAMR_FIELD_CODE_PAGE);
389 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
390 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
391 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
392 SAMR_FIELD_ACCT_EXPIRY);
393 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
394 SAMR_FIELD_ACCT_EXPIRY);
395 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
396 SAMR_FIELD_ACCT_EXPIRY);
398 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
399 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
400 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
401 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
402 SAMR_FIELD_LOGON_HOURS);
404 if (lp_parm_bool(-1, "torture", "samba4", False)) {
405 printf("skipping Set Account Flag tests against Samba4\n");
409 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
410 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
411 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
413 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
414 (base_acct_flags | ACB_DISABLED),
415 (base_acct_flags | ACB_DISABLED | user_extra_flags),
418 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
419 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
420 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
421 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
423 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
424 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
425 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
429 /* The 'autolock' flag doesn't stick - check this */
430 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
431 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
432 (base_acct_flags | ACB_DISABLED | user_extra_flags),
435 /* Removing the 'disabled' flag doesn't stick - check this */
436 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
438 (base_acct_flags | ACB_DISABLED | user_extra_flags),
441 /* The 'store plaintext' flag does stick */
442 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
443 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
444 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
446 /* The 'use DES' flag does stick */
447 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
448 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
449 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
451 /* The 'don't require kerberos pre-authentication flag does stick */
452 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
453 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
454 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
456 /* The 'no kerberos PAC required' flag sticks */
457 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
458 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
459 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
462 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
463 (base_acct_flags | ACB_DISABLED),
464 (base_acct_flags | ACB_DISABLED | user_extra_flags),
465 SAMR_FIELD_ACCT_FLAGS);
468 /* these fail with win2003 - it appears you can't set the primary gid?
469 the set succeeds, but the gid isn't changed. Very weird! */
470 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
471 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
472 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
473 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
480 generate a random password for password change tests
482 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
484 size_t len = MAX(8, min_len) + (random() % 6);
485 char *s = generate_random_str(mem_ctx, len);
486 printf("Generated password '%s'\n", s);
491 generate a random password for password change tests (fixed length)
493 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
495 char *s = generate_random_str(mem_ctx, len);
496 printf("Generated password '%s'\n", s);
500 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
501 struct policy_handle *handle, char **password)
504 struct samr_SetUserInfo s;
505 union samr_UserInfo u;
507 DATA_BLOB session_key;
509 struct samr_GetUserPwInfo pwp;
510 int policy_min_pw_len = 0;
511 pwp.in.user_handle = handle;
513 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
514 if (NT_STATUS_IS_OK(status)) {
515 policy_min_pw_len = pwp.out.info.min_password_length;
517 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
519 s.in.user_handle = handle;
523 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
524 /* w2k3 ignores this length */
525 u.info24.pw_len = strlen_m(newpass) * 2;
527 status = dcerpc_fetch_session_key(p, &session_key);
528 if (!NT_STATUS_IS_OK(status)) {
529 printf("SetUserInfo level %u - no session key - %s\n",
530 s.in.level, nt_errstr(status));
534 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
536 printf("Testing SetUserInfo level 24 (set password)\n");
538 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
539 if (!NT_STATUS_IS_OK(status)) {
540 printf("SetUserInfo level %u failed - %s\n",
541 s.in.level, nt_errstr(status));
551 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
552 struct policy_handle *handle, uint32_t fields_present,
556 struct samr_SetUserInfo s;
557 union samr_UserInfo u;
559 DATA_BLOB session_key;
561 struct samr_GetUserPwInfo pwp;
562 int policy_min_pw_len = 0;
563 pwp.in.user_handle = handle;
565 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
566 if (NT_STATUS_IS_OK(status)) {
567 policy_min_pw_len = pwp.out.info.min_password_length;
569 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
571 s.in.user_handle = handle;
577 u.info23.info.fields_present = fields_present;
579 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
581 status = dcerpc_fetch_session_key(p, &session_key);
582 if (!NT_STATUS_IS_OK(status)) {
583 printf("SetUserInfo level %u - no session key - %s\n",
584 s.in.level, nt_errstr(status));
588 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
590 printf("Testing SetUserInfo level 23 (set password)\n");
592 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
593 if (!NT_STATUS_IS_OK(status)) {
594 printf("SetUserInfo level %u failed - %s\n",
595 s.in.level, nt_errstr(status));
601 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
603 status = dcerpc_fetch_session_key(p, &session_key);
604 if (!NT_STATUS_IS_OK(status)) {
605 printf("SetUserInfo level %u - no session key - %s\n",
606 s.in.level, nt_errstr(status));
610 /* This should break the key nicely */
611 session_key.length--;
612 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
614 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
616 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
617 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
618 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
619 s.in.level, nt_errstr(status));
627 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
628 struct policy_handle *handle, bool makeshort,
632 struct samr_SetUserInfo s;
633 union samr_UserInfo u;
635 DATA_BLOB session_key;
636 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
637 uint8_t confounder[16];
639 struct MD5Context ctx;
640 struct samr_GetUserPwInfo pwp;
641 int policy_min_pw_len = 0;
642 pwp.in.user_handle = handle;
644 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
645 if (NT_STATUS_IS_OK(status)) {
646 policy_min_pw_len = pwp.out.info.min_password_length;
648 if (makeshort && policy_min_pw_len) {
649 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
651 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
654 s.in.user_handle = handle;
658 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
659 u.info26.pw_len = strlen(newpass);
661 status = dcerpc_fetch_session_key(p, &session_key);
662 if (!NT_STATUS_IS_OK(status)) {
663 printf("SetUserInfo level %u - no session key - %s\n",
664 s.in.level, nt_errstr(status));
668 generate_random_buffer((uint8_t *)confounder, 16);
671 MD5Update(&ctx, confounder, 16);
672 MD5Update(&ctx, session_key.data, session_key.length);
673 MD5Final(confounded_session_key.data, &ctx);
675 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
676 memcpy(&u.info26.password.data[516], confounder, 16);
678 printf("Testing SetUserInfo level 26 (set password ex)\n");
680 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
681 if (!NT_STATUS_IS_OK(status)) {
682 printf("SetUserInfo level %u failed - %s\n",
683 s.in.level, nt_errstr(status));
689 /* This should break the key nicely */
690 confounded_session_key.data[0]++;
692 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
693 memcpy(&u.info26.password.data[516], confounder, 16);
695 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
697 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
698 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
699 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
700 s.in.level, nt_errstr(status));
709 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
710 struct policy_handle *handle, uint32_t fields_present,
714 struct samr_SetUserInfo s;
715 union samr_UserInfo u;
717 DATA_BLOB session_key;
718 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
719 struct MD5Context ctx;
720 uint8_t confounder[16];
722 struct samr_GetUserPwInfo pwp;
723 int policy_min_pw_len = 0;
724 pwp.in.user_handle = handle;
726 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
727 if (NT_STATUS_IS_OK(status)) {
728 policy_min_pw_len = pwp.out.info.min_password_length;
730 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
732 s.in.user_handle = handle;
738 u.info25.info.fields_present = fields_present;
740 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
742 status = dcerpc_fetch_session_key(p, &session_key);
743 if (!NT_STATUS_IS_OK(status)) {
744 printf("SetUserInfo level %u - no session key - %s\n",
745 s.in.level, nt_errstr(status));
749 generate_random_buffer((uint8_t *)confounder, 16);
752 MD5Update(&ctx, confounder, 16);
753 MD5Update(&ctx, session_key.data, session_key.length);
754 MD5Final(confounded_session_key.data, &ctx);
756 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
757 memcpy(&u.info25.password.data[516], confounder, 16);
759 printf("Testing SetUserInfo level 25 (set password ex)\n");
761 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
762 if (!NT_STATUS_IS_OK(status)) {
763 printf("SetUserInfo level %u failed - %s\n",
764 s.in.level, nt_errstr(status));
770 /* This should break the key nicely */
771 confounded_session_key.data[0]++;
773 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
774 memcpy(&u.info25.password.data[516], confounder, 16);
776 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
778 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
779 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
780 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
781 s.in.level, nt_errstr(status));
788 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
789 struct policy_handle *handle)
792 struct samr_SetAliasInfo r;
793 struct samr_QueryAliasInfo q;
794 uint16_t levels[] = {2, 3};
798 /* Ignoring switch level 1, as that includes the number of members for the alias
799 * and setting this to a wrong value might have negative consequences
802 for (i=0;i<ARRAY_SIZE(levels);i++) {
803 printf("Testing SetAliasInfo level %u\n", levels[i]);
805 r.in.alias_handle = handle;
806 r.in.level = levels[i];
807 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
808 switch (r.in.level) {
809 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
810 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
811 "Test Description, should test I18N as well"); break;
814 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
815 if (!NT_STATUS_IS_OK(status)) {
816 printf("SetAliasInfo level %u failed - %s\n",
817 levels[i], nt_errstr(status));
821 q.in.alias_handle = handle;
822 q.in.level = levels[i];
824 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
825 if (!NT_STATUS_IS_OK(status)) {
826 printf("QueryAliasInfo level %u failed - %s\n",
827 levels[i], nt_errstr(status));
835 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
836 struct policy_handle *user_handle)
838 struct samr_GetGroupsForUser r;
842 printf("testing GetGroupsForUser\n");
844 r.in.user_handle = user_handle;
846 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
847 if (!NT_STATUS_IS_OK(status)) {
848 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
856 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
857 struct lsa_String *domain_name)
860 struct samr_GetDomPwInfo r;
863 r.in.domain_name = domain_name;
864 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
866 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
867 if (!NT_STATUS_IS_OK(status)) {
868 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
872 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
873 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
875 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
876 if (!NT_STATUS_IS_OK(status)) {
877 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
881 r.in.domain_name->string = "\\\\__NONAME__";
882 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
884 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
885 if (!NT_STATUS_IS_OK(status)) {
886 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
890 r.in.domain_name->string = "\\\\Builtin";
891 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
893 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
894 if (!NT_STATUS_IS_OK(status)) {
895 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
903 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
904 struct policy_handle *handle)
907 struct samr_GetUserPwInfo r;
910 printf("Testing GetUserPwInfo\n");
912 r.in.user_handle = handle;
914 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
915 if (!NT_STATUS_IS_OK(status)) {
916 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
923 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
924 struct policy_handle *domain_handle, const char *name,
928 struct samr_LookupNames n;
929 struct lsa_String sname[2];
931 init_lsa_String(&sname[0], name);
933 n.in.domain_handle = domain_handle;
936 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
937 if (NT_STATUS_IS_OK(status)) {
938 *rid = n.out.rids.ids[0];
943 init_lsa_String(&sname[1], "xxNONAMExx");
945 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
946 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
947 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
948 if (NT_STATUS_IS_OK(status)) {
949 return NT_STATUS_UNSUCCESSFUL;
955 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
956 if (!NT_STATUS_IS_OK(status)) {
957 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
961 init_lsa_String(&sname[0], "xxNONAMExx");
963 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
964 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
965 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
966 if (NT_STATUS_IS_OK(status)) {
967 return NT_STATUS_UNSUCCESSFUL;
972 init_lsa_String(&sname[0], "xxNONAMExx");
973 init_lsa_String(&sname[1], "xxNONAME2xx");
975 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
976 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
977 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
978 if (NT_STATUS_IS_OK(status)) {
979 return NT_STATUS_UNSUCCESSFUL;
987 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
988 struct policy_handle *domain_handle,
989 const char *name, struct policy_handle *user_handle)
992 struct samr_OpenUser r;
995 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
996 if (!NT_STATUS_IS_OK(status)) {
1000 r.in.domain_handle = domain_handle;
1001 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1003 r.out.user_handle = user_handle;
1004 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1005 if (!NT_STATUS_IS_OK(status)) {
1006 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1013 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1014 struct policy_handle *handle)
1017 struct samr_ChangePasswordUser r;
1019 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1020 struct policy_handle user_handle;
1021 char *oldpass = "test";
1022 char *newpass = "test2";
1023 uint8_t old_nt_hash[16], new_nt_hash[16];
1024 uint8_t old_lm_hash[16], new_lm_hash[16];
1026 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1027 if (!NT_STATUS_IS_OK(status)) {
1031 printf("Testing ChangePasswordUser for user 'testuser'\n");
1033 printf("old password: %s\n", oldpass);
1034 printf("new password: %s\n", newpass);
1036 E_md4hash(oldpass, old_nt_hash);
1037 E_md4hash(newpass, new_nt_hash);
1038 E_deshash(oldpass, old_lm_hash);
1039 E_deshash(newpass, new_lm_hash);
1041 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1042 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1043 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1044 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1045 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1046 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1048 r.in.handle = &user_handle;
1049 r.in.lm_present = 1;
1050 r.in.old_lm_crypted = &hash1;
1051 r.in.new_lm_crypted = &hash2;
1052 r.in.nt_present = 1;
1053 r.in.old_nt_crypted = &hash3;
1054 r.in.new_nt_crypted = &hash4;
1055 r.in.cross1_present = 1;
1056 r.in.nt_cross = &hash5;
1057 r.in.cross2_present = 1;
1058 r.in.lm_cross = &hash6;
1060 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1066 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1074 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1075 const char *acct_name,
1076 struct policy_handle *handle, char **password)
1079 struct samr_ChangePasswordUser r;
1081 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1082 struct policy_handle user_handle;
1084 uint8_t old_nt_hash[16], new_nt_hash[16];
1085 uint8_t old_lm_hash[16], new_lm_hash[16];
1086 BOOL changed = True;
1089 struct samr_GetUserPwInfo pwp;
1090 int policy_min_pw_len = 0;
1092 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1093 if (!NT_STATUS_IS_OK(status)) {
1096 pwp.in.user_handle = &user_handle;
1098 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1099 if (NT_STATUS_IS_OK(status)) {
1100 policy_min_pw_len = pwp.out.info.min_password_length;
1102 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1104 printf("Testing ChangePasswordUser\n");
1107 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1111 oldpass = *password;
1113 E_md4hash(oldpass, old_nt_hash);
1114 E_md4hash(newpass, new_nt_hash);
1115 E_deshash(oldpass, old_lm_hash);
1116 E_deshash(newpass, new_lm_hash);
1118 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1119 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1120 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1121 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1122 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1123 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1125 r.in.user_handle = &user_handle;
1126 r.in.lm_present = 1;
1127 /* Break the LM hash */
1129 r.in.old_lm_crypted = &hash1;
1130 r.in.new_lm_crypted = &hash2;
1131 r.in.nt_present = 1;
1132 r.in.old_nt_crypted = &hash3;
1133 r.in.new_nt_crypted = &hash4;
1134 r.in.cross1_present = 1;
1135 r.in.nt_cross = &hash5;
1136 r.in.cross2_present = 1;
1137 r.in.lm_cross = &hash6;
1139 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1140 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1141 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1145 /* Unbreak the LM hash */
1148 r.in.user_handle = &user_handle;
1149 r.in.lm_present = 1;
1150 r.in.old_lm_crypted = &hash1;
1151 r.in.new_lm_crypted = &hash2;
1152 /* Break the NT hash */
1154 r.in.nt_present = 1;
1155 r.in.old_nt_crypted = &hash3;
1156 r.in.new_nt_crypted = &hash4;
1157 r.in.cross1_present = 1;
1158 r.in.nt_cross = &hash5;
1159 r.in.cross2_present = 1;
1160 r.in.lm_cross = &hash6;
1162 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1163 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1164 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1168 /* Unbreak the NT hash */
1171 r.in.user_handle = &user_handle;
1172 r.in.lm_present = 1;
1173 r.in.old_lm_crypted = &hash1;
1174 r.in.new_lm_crypted = &hash2;
1175 r.in.nt_present = 1;
1176 r.in.old_nt_crypted = &hash3;
1177 r.in.new_nt_crypted = &hash4;
1178 r.in.cross1_present = 1;
1179 r.in.nt_cross = &hash5;
1180 r.in.cross2_present = 1;
1181 /* Break the LM cross */
1183 r.in.lm_cross = &hash6;
1185 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1186 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1187 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1191 /* Unbreak the LM cross */
1194 r.in.user_handle = &user_handle;
1195 r.in.lm_present = 1;
1196 r.in.old_lm_crypted = &hash1;
1197 r.in.new_lm_crypted = &hash2;
1198 r.in.nt_present = 1;
1199 r.in.old_nt_crypted = &hash3;
1200 r.in.new_nt_crypted = &hash4;
1201 r.in.cross1_present = 1;
1202 /* Break the NT cross */
1204 r.in.nt_cross = &hash5;
1205 r.in.cross2_present = 1;
1206 r.in.lm_cross = &hash6;
1208 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1209 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1210 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1214 /* Unbreak the NT cross */
1218 /* Reset the hashes to not broken values */
1219 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1220 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1221 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1222 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1223 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1224 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1226 r.in.user_handle = &user_handle;
1227 r.in.lm_present = 1;
1228 r.in.old_lm_crypted = &hash1;
1229 r.in.new_lm_crypted = &hash2;
1230 r.in.nt_present = 1;
1231 r.in.old_nt_crypted = &hash3;
1232 r.in.new_nt_crypted = &hash4;
1233 r.in.cross1_present = 1;
1234 r.in.nt_cross = &hash5;
1235 r.in.cross2_present = 0;
1236 r.in.lm_cross = NULL;
1238 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1239 if (NT_STATUS_IS_OK(status)) {
1241 *password = newpass;
1242 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1243 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1248 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1250 E_md4hash(oldpass, old_nt_hash);
1251 E_md4hash(newpass, new_nt_hash);
1252 E_deshash(oldpass, old_lm_hash);
1253 E_deshash(newpass, new_lm_hash);
1256 /* Reset the hashes to not broken values */
1257 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1258 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1259 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1260 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1261 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1262 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1264 r.in.user_handle = &user_handle;
1265 r.in.lm_present = 1;
1266 r.in.old_lm_crypted = &hash1;
1267 r.in.new_lm_crypted = &hash2;
1268 r.in.nt_present = 1;
1269 r.in.old_nt_crypted = &hash3;
1270 r.in.new_nt_crypted = &hash4;
1271 r.in.cross1_present = 0;
1272 r.in.nt_cross = NULL;
1273 r.in.cross2_present = 1;
1274 r.in.lm_cross = &hash6;
1276 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1277 if (NT_STATUS_IS_OK(status)) {
1279 *password = newpass;
1280 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1281 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1286 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1288 E_md4hash(oldpass, old_nt_hash);
1289 E_md4hash(newpass, new_nt_hash);
1290 E_deshash(oldpass, old_lm_hash);
1291 E_deshash(newpass, new_lm_hash);
1294 /* Reset the hashes to not broken values */
1295 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1296 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1297 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1298 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1299 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1300 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1302 r.in.user_handle = &user_handle;
1303 r.in.lm_present = 1;
1304 r.in.old_lm_crypted = &hash1;
1305 r.in.new_lm_crypted = &hash2;
1306 r.in.nt_present = 1;
1307 r.in.old_nt_crypted = &hash3;
1308 r.in.new_nt_crypted = &hash4;
1309 r.in.cross1_present = 1;
1310 r.in.nt_cross = &hash5;
1311 r.in.cross2_present = 1;
1312 r.in.lm_cross = &hash6;
1314 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1315 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1316 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1317 } else if (!NT_STATUS_IS_OK(status)) {
1318 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1322 *password = newpass;
1325 r.in.user_handle = &user_handle;
1326 r.in.lm_present = 1;
1327 r.in.old_lm_crypted = &hash1;
1328 r.in.new_lm_crypted = &hash2;
1329 r.in.nt_present = 1;
1330 r.in.old_nt_crypted = &hash3;
1331 r.in.new_nt_crypted = &hash4;
1332 r.in.cross1_present = 1;
1333 r.in.nt_cross = &hash5;
1334 r.in.cross2_present = 1;
1335 r.in.lm_cross = &hash6;
1338 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1339 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1340 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1341 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1342 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1348 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1356 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1357 const char *acct_name,
1358 struct policy_handle *handle, char **password)
1361 struct samr_OemChangePasswordUser2 r;
1363 struct samr_Password lm_verifier;
1364 struct samr_CryptPassword lm_pass;
1365 struct lsa_AsciiString server, account, account_bad;
1368 uint8_t old_lm_hash[16], new_lm_hash[16];
1370 struct samr_GetDomPwInfo dom_pw_info;
1371 int policy_min_pw_len = 0;
1373 struct lsa_String domain_name;
1375 domain_name.string = "";
1376 dom_pw_info.in.domain_name = &domain_name;
1378 printf("Testing OemChangePasswordUser2\n");
1381 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1385 oldpass = *password;
1387 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1388 if (NT_STATUS_IS_OK(status)) {
1389 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1392 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1394 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1395 account.string = acct_name;
1397 E_deshash(oldpass, old_lm_hash);
1398 E_deshash(newpass, new_lm_hash);
1400 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1401 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1402 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1404 r.in.server = &server;
1405 r.in.account = &account;
1406 r.in.password = &lm_pass;
1407 r.in.hash = &lm_verifier;
1409 /* Break the verification */
1410 lm_verifier.hash[0]++;
1412 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1414 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1415 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1416 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1421 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1422 /* Break the old password */
1424 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1425 /* unbreak it for the next operation */
1427 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1429 r.in.server = &server;
1430 r.in.account = &account;
1431 r.in.password = &lm_pass;
1432 r.in.hash = &lm_verifier;
1434 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1436 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1437 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1438 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1443 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1444 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1446 r.in.server = &server;
1447 r.in.account = &account;
1448 r.in.password = &lm_pass;
1451 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1453 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1454 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1455 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1460 /* This shouldn't be a valid name */
1461 account_bad.string = TEST_ACCOUNT_NAME "XX";
1462 r.in.account = &account_bad;
1464 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1466 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1467 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1472 /* This shouldn't be a valid name */
1473 account_bad.string = TEST_ACCOUNT_NAME "XX";
1474 r.in.account = &account_bad;
1475 r.in.password = &lm_pass;
1476 r.in.hash = &lm_verifier;
1478 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1480 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1481 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1486 /* This shouldn't be a valid name */
1487 account_bad.string = TEST_ACCOUNT_NAME "XX";
1488 r.in.account = &account_bad;
1489 r.in.password = NULL;
1490 r.in.hash = &lm_verifier;
1492 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1494 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1495 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1500 E_deshash(oldpass, old_lm_hash);
1501 E_deshash(newpass, new_lm_hash);
1503 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1504 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1505 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1507 r.in.server = &server;
1508 r.in.account = &account;
1509 r.in.password = &lm_pass;
1510 r.in.hash = &lm_verifier;
1512 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1513 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1514 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1515 } else if (!NT_STATUS_IS_OK(status)) {
1516 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1519 *password = newpass;
1526 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1527 const char *acct_name,
1529 char *newpass, bool allow_password_restriction)
1532 struct samr_ChangePasswordUser2 r;
1534 struct lsa_String server, account;
1535 struct samr_CryptPassword nt_pass, lm_pass;
1536 struct samr_Password nt_verifier, lm_verifier;
1538 uint8_t old_nt_hash[16], new_nt_hash[16];
1539 uint8_t old_lm_hash[16], new_lm_hash[16];
1541 struct samr_GetDomPwInfo dom_pw_info;
1543 struct lsa_String domain_name;
1545 domain_name.string = "";
1546 dom_pw_info.in.domain_name = &domain_name;
1548 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1551 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1554 oldpass = *password;
1557 int policy_min_pw_len = 0;
1558 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1559 if (NT_STATUS_IS_OK(status)) {
1560 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1563 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1566 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1567 init_lsa_String(&account, acct_name);
1569 E_md4hash(oldpass, old_nt_hash);
1570 E_md4hash(newpass, new_nt_hash);
1572 E_deshash(oldpass, old_lm_hash);
1573 E_deshash(newpass, new_lm_hash);
1575 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1576 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1577 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1579 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1580 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1581 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1583 r.in.server = &server;
1584 r.in.account = &account;
1585 r.in.nt_password = &nt_pass;
1586 r.in.nt_verifier = &nt_verifier;
1588 r.in.lm_password = &lm_pass;
1589 r.in.lm_verifier = &lm_verifier;
1591 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1592 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1593 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1594 } else if (!NT_STATUS_IS_OK(status)) {
1595 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1598 *password = newpass;
1605 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1606 const char *account_string,
1607 int policy_min_pw_len,
1609 const char *newpass,
1610 NTTIME last_password_change,
1611 BOOL handle_reject_reason)
1614 struct samr_ChangePasswordUser3 r;
1616 struct lsa_String server, account, account_bad;
1617 struct samr_CryptPassword nt_pass, lm_pass;
1618 struct samr_Password nt_verifier, lm_verifier;
1620 uint8_t old_nt_hash[16], new_nt_hash[16];
1621 uint8_t old_lm_hash[16], new_lm_hash[16];
1624 printf("Testing ChangePasswordUser3\n");
1626 if (newpass == NULL) {
1628 if (policy_min_pw_len == 0) {
1629 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1631 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1633 } while (check_password_quality(newpass) == False);
1635 printf("Using password '%s'\n", newpass);
1639 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1643 oldpass = *password;
1644 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1645 init_lsa_String(&account, account_string);
1647 E_md4hash(oldpass, old_nt_hash);
1648 E_md4hash(newpass, new_nt_hash);
1650 E_deshash(oldpass, old_lm_hash);
1651 E_deshash(newpass, new_lm_hash);
1653 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1654 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1655 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1657 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1658 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1659 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1661 /* Break the verification */
1662 nt_verifier.hash[0]++;
1664 r.in.server = &server;
1665 r.in.account = &account;
1666 r.in.nt_password = &nt_pass;
1667 r.in.nt_verifier = &nt_verifier;
1669 r.in.lm_password = &lm_pass;
1670 r.in.lm_verifier = &lm_verifier;
1671 r.in.password3 = NULL;
1673 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1674 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1675 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1676 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1681 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1682 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1683 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1685 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1686 /* Break the NT hash */
1688 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1689 /* Unbreak it again */
1691 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1693 r.in.server = &server;
1694 r.in.account = &account;
1695 r.in.nt_password = &nt_pass;
1696 r.in.nt_verifier = &nt_verifier;
1698 r.in.lm_password = &lm_pass;
1699 r.in.lm_verifier = &lm_verifier;
1700 r.in.password3 = NULL;
1702 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1703 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1704 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1705 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1710 /* This shouldn't be a valid name */
1711 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1713 r.in.account = &account_bad;
1714 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1715 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1716 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1721 E_md4hash(oldpass, old_nt_hash);
1722 E_md4hash(newpass, new_nt_hash);
1724 E_deshash(oldpass, old_lm_hash);
1725 E_deshash(newpass, new_lm_hash);
1727 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1728 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1729 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1731 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1732 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1733 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1735 r.in.server = &server;
1736 r.in.account = &account;
1737 r.in.nt_password = &nt_pass;
1738 r.in.nt_verifier = &nt_verifier;
1740 r.in.lm_password = &lm_pass;
1741 r.in.lm_verifier = &lm_verifier;
1742 r.in.password3 = NULL;
1744 unix_to_nt_time(&t, time(NULL));
1746 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1748 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1751 && handle_reject_reason
1752 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1753 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1755 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1756 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1757 SAMR_REJECT_OTHER, r.out.reject->reason);
1762 /* We tested the order of precendence which is as follows:
1771 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1772 (last_password_change + r.out.dominfo->min_password_age > t)) {
1774 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1775 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1776 SAMR_REJECT_OTHER, r.out.reject->reason);
1780 } else if ((r.out.dominfo->min_password_length > 0) &&
1781 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1783 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1784 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1785 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1789 } else if ((r.out.dominfo->password_history_length > 0) &&
1790 strequal(oldpass, newpass)) {
1792 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1793 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1794 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1797 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1799 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1800 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1801 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1807 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1808 /* retry with adjusted size */
1809 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1810 r.out.dominfo->min_password_length,
1811 password, NULL, 0, False);
1815 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1816 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1817 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1818 SAMR_REJECT_OTHER, r.out.reject->reason);
1821 /* Perhaps the server has a 'min password age' set? */
1823 } else if (!NT_STATUS_IS_OK(status)) {
1824 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1827 *password = talloc_strdup(mem_ctx, newpass);
1834 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1835 struct policy_handle *alias_handle)
1837 struct samr_GetMembersInAlias r;
1838 struct lsa_SidArray sids;
1842 printf("Testing GetMembersInAlias\n");
1844 r.in.alias_handle = alias_handle;
1847 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1848 if (!NT_STATUS_IS_OK(status)) {
1849 printf("GetMembersInAlias failed - %s\n",
1857 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1858 struct policy_handle *alias_handle,
1859 const struct dom_sid *domain_sid)
1861 struct samr_AddAliasMember r;
1862 struct samr_DeleteAliasMember d;
1865 struct dom_sid *sid;
1867 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1869 printf("testing AddAliasMember\n");
1870 r.in.alias_handle = alias_handle;
1873 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1874 if (!NT_STATUS_IS_OK(status)) {
1875 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1879 d.in.alias_handle = alias_handle;
1882 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1883 if (!NT_STATUS_IS_OK(status)) {
1884 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1891 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1892 struct policy_handle *alias_handle)
1894 struct samr_AddMultipleMembersToAlias a;
1895 struct samr_RemoveMultipleMembersFromAlias r;
1898 struct lsa_SidArray sids;
1900 printf("testing AddMultipleMembersToAlias\n");
1901 a.in.alias_handle = alias_handle;
1905 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1907 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1908 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1909 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1911 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1912 if (!NT_STATUS_IS_OK(status)) {
1913 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1918 printf("testing RemoveMultipleMembersFromAlias\n");
1919 r.in.alias_handle = alias_handle;
1922 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1923 if (!NT_STATUS_IS_OK(status)) {
1924 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1928 /* strange! removing twice doesn't give any error */
1929 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1930 if (!NT_STATUS_IS_OK(status)) {
1931 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1935 /* but removing an alias that isn't there does */
1936 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1938 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1939 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1940 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1947 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1948 struct policy_handle *user_handle)
1950 struct samr_TestPrivateFunctionsUser r;
1954 printf("Testing TestPrivateFunctionsUser\n");
1956 r.in.user_handle = user_handle;
1958 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1959 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1960 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1968 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1969 struct policy_handle *user_handle,
1970 struct policy_handle *domain_handle,
1971 uint32_t base_acct_flags,
1972 const char *base_acct_name, enum torture_samr_choice which_ops)
1974 TALLOC_CTX *user_ctx;
1975 char *password = NULL;
1979 const uint32_t password_fields[] = {
1980 SAMR_FIELD_PASSWORD,
1981 SAMR_FIELD_PASSWORD2,
1982 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1986 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1987 switch (which_ops) {
1988 case TORTURE_SAMR_USER_ATTRIBUTES:
1989 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1993 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1997 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
2001 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
2006 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
2010 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
2014 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
2018 case TORTURE_SAMR_PASSWORDS:
2019 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2020 char simple_pass[9];
2021 char *v = generate_random_str(mem_ctx, 1);
2023 ZERO_STRUCT(simple_pass);
2024 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2026 printf("Testing machine account password policy rules\n");
2028 /* Workstation trust accounts don't seem to need to honour password quality policy */
2029 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2033 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, simple_pass, False)) {
2037 /* reset again, to allow another 'user' password change */
2038 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2042 /* Try a 'short' password */
2043 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, samr_rand_pass(mem_ctx, 4), False)) {
2049 for (i = 0; password_fields[i]; i++) {
2050 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
2054 /* check it was set right */
2055 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2060 for (i = 0; password_fields[i]; i++) {
2061 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
2065 /* check it was set right */
2066 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2071 if (!test_SetUserPassEx(p, user_ctx, user_handle, false, &password)) {
2075 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
2080 case TORTURE_SAMR_OTHER:
2081 /* We just need the account to exist */
2084 talloc_free(user_ctx);
2088 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2089 struct policy_handle *alias_handle,
2090 const struct dom_sid *domain_sid)
2094 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
2098 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
2102 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
2106 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
2110 if (lp_parm_bool(-1, "torture", "samba4", False)) {
2111 printf("skipping MultipleMembers Alias tests against Samba4\n");
2115 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
2123 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2124 struct policy_handle *user_handle)
2126 struct samr_DeleteUser d;
2129 printf("Testing DeleteUser\n");
2131 d.in.user_handle = user_handle;
2132 d.out.user_handle = user_handle;
2134 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2135 if (!NT_STATUS_IS_OK(status)) {
2136 printf("DeleteUser failed - %s\n", nt_errstr(status));
2143 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2144 struct policy_handle *handle, const char *name)
2147 struct samr_DeleteUser d;
2148 struct policy_handle user_handle;
2151 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2152 if (!NT_STATUS_IS_OK(status)) {
2156 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2157 if (!NT_STATUS_IS_OK(status)) {
2161 d.in.user_handle = &user_handle;
2162 d.out.user_handle = &user_handle;
2163 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2164 if (!NT_STATUS_IS_OK(status)) {
2171 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2176 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2177 struct policy_handle *handle, const char *name)
2180 struct samr_OpenGroup r;
2181 struct samr_DeleteDomainGroup d;
2182 struct policy_handle group_handle;
2185 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2186 if (!NT_STATUS_IS_OK(status)) {
2190 r.in.domain_handle = handle;
2191 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2193 r.out.group_handle = &group_handle;
2194 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2195 if (!NT_STATUS_IS_OK(status)) {
2199 d.in.group_handle = &group_handle;
2200 d.out.group_handle = &group_handle;
2201 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2202 if (!NT_STATUS_IS_OK(status)) {
2209 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2214 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2215 struct policy_handle *domain_handle, const char *name)
2218 struct samr_OpenAlias r;
2219 struct samr_DeleteDomAlias d;
2220 struct policy_handle alias_handle;
2223 printf("testing DeleteAlias_byname\n");
2225 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2226 if (!NT_STATUS_IS_OK(status)) {
2230 r.in.domain_handle = domain_handle;
2231 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2233 r.out.alias_handle = &alias_handle;
2234 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2235 if (!NT_STATUS_IS_OK(status)) {
2239 d.in.alias_handle = &alias_handle;
2240 d.out.alias_handle = &alias_handle;
2241 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2242 if (!NT_STATUS_IS_OK(status)) {
2249 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2253 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2254 struct policy_handle *alias_handle)
2256 struct samr_DeleteDomAlias d;
2259 printf("Testing DeleteAlias\n");
2261 d.in.alias_handle = alias_handle;
2262 d.out.alias_handle = alias_handle;
2264 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2265 if (!NT_STATUS_IS_OK(status)) {
2266 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2273 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2274 struct policy_handle *domain_handle,
2275 struct policy_handle *alias_handle,
2276 const struct dom_sid *domain_sid)
2279 struct samr_CreateDomAlias r;
2280 struct lsa_String name;
2284 init_lsa_String(&name, TEST_ALIASNAME);
2285 r.in.domain_handle = domain_handle;
2286 r.in.alias_name = &name;
2287 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2288 r.out.alias_handle = alias_handle;
2291 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2293 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2295 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2296 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2300 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2301 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2304 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2307 if (!NT_STATUS_IS_OK(status)) {
2308 printf("CreateAlias failed - %s\n", nt_errstr(status));
2312 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2319 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2320 const char *acct_name,
2321 struct policy_handle *domain_handle, char **password)
2329 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2333 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, True)) {
2337 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2341 /* test what happens when setting the old password again */
2342 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2347 char simple_pass[9];
2348 char *v = generate_random_str(mem_ctx, 1);
2350 ZERO_STRUCT(simple_pass);
2351 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2353 /* test what happens when picking a simple password */
2354 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2359 /* set samr_SetDomainInfo level 1 with min_length 5 */
2361 struct samr_QueryDomainInfo r;
2362 struct samr_SetDomainInfo s;
2363 uint16_t len_old, len;
2364 uint32_t pwd_prop_old;
2365 int64_t min_pwd_age_old;
2370 r.in.domain_handle = domain_handle;
2373 printf("testing samr_QueryDomainInfo level 1\n");
2374 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2375 if (!NT_STATUS_IS_OK(status)) {
2379 s.in.domain_handle = domain_handle;
2381 s.in.info = r.out.info;
2383 /* remember the old min length, so we can reset it */
2384 len_old = s.in.info->info1.min_password_length;
2385 s.in.info->info1.min_password_length = len;
2386 pwd_prop_old = s.in.info->info1.password_properties;
2387 /* turn off password complexity checks for this test */
2388 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2390 min_pwd_age_old = s.in.info->info1.min_password_age;
2391 s.in.info->info1.min_password_age = 0;
2393 printf("testing samr_SetDomainInfo level 1\n");
2394 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2395 if (!NT_STATUS_IS_OK(status)) {
2399 printf("calling test_ChangePasswordUser3 with too short password\n");
2401 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2405 s.in.info->info1.min_password_length = len_old;
2406 s.in.info->info1.password_properties = pwd_prop_old;
2407 s.in.info->info1.min_password_age = min_pwd_age_old;
2409 printf("testing samr_SetDomainInfo level 1\n");
2410 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2411 if (!NT_STATUS_IS_OK(status)) {
2419 struct samr_OpenUser r;
2420 struct samr_QueryUserInfo q;
2421 struct samr_LookupNames n;
2422 struct policy_handle user_handle;
2424 n.in.domain_handle = domain_handle;
2426 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2427 n.in.names[0].string = acct_name;
2429 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2430 if (!NT_STATUS_IS_OK(status)) {
2431 printf("LookupNames failed - %s\n", nt_errstr(status));
2435 r.in.domain_handle = domain_handle;
2436 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2437 r.in.rid = n.out.rids.ids[0];
2438 r.out.user_handle = &user_handle;
2440 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2441 if (!NT_STATUS_IS_OK(status)) {
2442 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2446 q.in.user_handle = &user_handle;
2449 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2450 if (!NT_STATUS_IS_OK(status)) {
2451 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2455 printf("calling test_ChangePasswordUser3 with too early password change\n");
2457 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2458 q.out.info->info5.last_password_change, True)) {
2463 /* we change passwords twice - this has the effect of verifying
2464 they were changed correctly for the final call */
2465 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2469 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2476 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2477 struct policy_handle *domain_handle,
2478 struct policy_handle *user_handle_out,
2479 enum torture_samr_choice which_ops)
2482 TALLOC_CTX *user_ctx;
2485 struct samr_CreateUser r;
2486 struct samr_QueryUserInfo q;
2487 struct samr_DeleteUser d;
2490 /* This call creates a 'normal' account - check that it really does */
2491 const uint32_t acct_flags = ACB_NORMAL;
2492 struct lsa_String name;
2495 struct policy_handle user_handle;
2496 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2497 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2499 r.in.domain_handle = domain_handle;
2500 r.in.account_name = &name;
2501 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2502 r.out.user_handle = &user_handle;
2505 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2507 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2509 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2510 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2511 talloc_free(user_ctx);
2515 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2516 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2517 talloc_free(user_ctx);
2520 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2522 if (!NT_STATUS_IS_OK(status)) {
2523 talloc_free(user_ctx);
2524 printf("CreateUser failed - %s\n", nt_errstr(status));
2527 q.in.user_handle = &user_handle;
2530 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2531 if (!NT_STATUS_IS_OK(status)) {
2532 printf("QueryUserInfo level %u failed - %s\n",
2533 q.in.level, nt_errstr(status));
2536 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2537 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2538 q.out.info->info16.acct_flags,
2544 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2545 acct_flags, name.string, which_ops)) {
2549 if (user_handle_out) {
2550 *user_handle_out = user_handle;
2552 printf("Testing DeleteUser (createuser test)\n");
2554 d.in.user_handle = &user_handle;
2555 d.out.user_handle = &user_handle;
2557 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2558 if (!NT_STATUS_IS_OK(status)) {
2559 printf("DeleteUser failed - %s\n", nt_errstr(status));
2566 talloc_free(user_ctx);
2572 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2573 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2576 struct samr_CreateUser2 r;
2577 struct samr_QueryUserInfo q;
2578 struct samr_DeleteUser d;
2579 struct policy_handle user_handle;
2581 struct lsa_String name;
2586 uint32_t acct_flags;
2587 const char *account_name;
2589 } account_types[] = {
2590 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2591 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2592 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2593 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2594 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2595 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2596 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2597 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2598 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2599 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2600 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2601 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2602 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2603 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2604 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2607 for (i = 0; account_types[i].account_name; i++) {
2608 TALLOC_CTX *user_ctx;
2609 uint32_t acct_flags = account_types[i].acct_flags;
2610 uint32_t access_granted;
2611 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2612 init_lsa_String(&name, account_types[i].account_name);
2614 r.in.domain_handle = domain_handle;
2615 r.in.account_name = &name;
2616 r.in.acct_flags = acct_flags;
2617 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2618 r.out.user_handle = &user_handle;
2619 r.out.access_granted = &access_granted;
2622 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2624 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2626 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2627 talloc_free(user_ctx);
2628 printf("Server refused create of '%s'\n", r.in.account_name->string);
2631 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2632 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2633 talloc_free(user_ctx);
2637 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2640 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2641 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2642 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2646 if (NT_STATUS_IS_OK(status)) {
2647 q.in.user_handle = &user_handle;
2650 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2651 if (!NT_STATUS_IS_OK(status)) {
2652 printf("QueryUserInfo level %u failed - %s\n",
2653 q.in.level, nt_errstr(status));
2656 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2657 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2658 q.out.info->info5.acct_flags,
2662 switch (acct_flags) {
2664 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2665 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2666 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2671 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2672 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2673 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2678 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2679 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2680 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2687 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2688 acct_flags, name.string, which_ops)) {
2692 printf("Testing DeleteUser (createuser2 test)\n");
2694 d.in.user_handle = &user_handle;
2695 d.out.user_handle = &user_handle;
2697 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2698 if (!NT_STATUS_IS_OK(status)) {
2699 printf("DeleteUser failed - %s\n", nt_errstr(status));
2703 talloc_free(user_ctx);
2709 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2710 struct policy_handle *handle)
2713 struct samr_QueryAliasInfo r;
2714 uint16_t levels[] = {1, 2, 3};
2718 for (i=0;i<ARRAY_SIZE(levels);i++) {
2719 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2721 r.in.alias_handle = handle;
2722 r.in.level = levels[i];
2724 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2725 if (!NT_STATUS_IS_OK(status)) {
2726 printf("QueryAliasInfo level %u failed - %s\n",
2727 levels[i], nt_errstr(status));
2735 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2736 struct policy_handle *handle)
2739 struct samr_QueryGroupInfo r;
2740 uint16_t levels[] = {1, 2, 3, 4, 5};
2744 for (i=0;i<ARRAY_SIZE(levels);i++) {
2745 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2747 r.in.group_handle = handle;
2748 r.in.level = levels[i];
2750 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2751 if (!NT_STATUS_IS_OK(status)) {
2752 printf("QueryGroupInfo level %u failed - %s\n",
2753 levels[i], nt_errstr(status));
2761 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2762 struct policy_handle *handle)
2765 struct samr_QueryGroupMember r;
2768 printf("Testing QueryGroupMember\n");
2770 r.in.group_handle = handle;
2772 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2773 if (!NT_STATUS_IS_OK(status)) {
2774 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2782 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2783 struct policy_handle *handle)
2786 struct samr_QueryGroupInfo r;
2787 struct samr_SetGroupInfo s;
2788 uint16_t levels[] = {1, 2, 3, 4};
2789 uint16_t set_ok[] = {0, 1, 1, 1};
2793 for (i=0;i<ARRAY_SIZE(levels);i++) {
2794 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2796 r.in.group_handle = handle;
2797 r.in.level = levels[i];
2799 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 printf("QueryGroupInfo level %u failed - %s\n",
2802 levels[i], nt_errstr(status));
2806 printf("Testing SetGroupInfo level %u\n", levels[i]);
2808 s.in.group_handle = handle;
2809 s.in.level = levels[i];
2810 s.in.info = r.out.info;
2813 /* disabled this, as it changes the name only from the point of view of samr,
2814 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2815 the name is still reserved, so creating the old name fails, but deleting by the old name
2817 if (s.in.level == 2) {
2818 init_lsa_String(&s.in.info->string, "NewName");
2822 if (s.in.level == 4) {
2823 init_lsa_String(&s.in.info->description, "test description");
2826 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2828 if (!NT_STATUS_IS_OK(status)) {
2829 printf("SetGroupInfo level %u failed - %s\n",
2830 r.in.level, nt_errstr(status));
2835 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2836 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2837 r.in.level, nt_errstr(status));
2847 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2848 struct policy_handle *handle)
2851 struct samr_QueryUserInfo r;
2852 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2853 11, 12, 13, 14, 16, 17, 20, 21};
2857 for (i=0;i<ARRAY_SIZE(levels);i++) {
2858 printf("Testing QueryUserInfo level %u\n", levels[i]);
2860 r.in.user_handle = handle;
2861 r.in.level = levels[i];
2863 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2864 if (!NT_STATUS_IS_OK(status)) {
2865 printf("QueryUserInfo level %u failed - %s\n",
2866 levels[i], nt_errstr(status));
2874 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2875 struct policy_handle *handle)
2878 struct samr_QueryUserInfo2 r;
2879 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2880 11, 12, 13, 14, 16, 17, 20, 21};
2884 for (i=0;i<ARRAY_SIZE(levels);i++) {
2885 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2887 r.in.user_handle = handle;
2888 r.in.level = levels[i];
2890 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2891 if (!NT_STATUS_IS_OK(status)) {
2892 printf("QueryUserInfo2 level %u failed - %s\n",
2893 levels[i], nt_errstr(status));
2901 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2902 struct policy_handle *handle, uint32_t rid)
2905 struct samr_OpenUser r;
2906 struct policy_handle user_handle;
2909 printf("Testing OpenUser(%u)\n", rid);
2911 r.in.domain_handle = handle;
2912 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2914 r.out.user_handle = &user_handle;
2916 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2917 if (!NT_STATUS_IS_OK(status)) {
2918 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2922 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2926 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2930 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2934 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2938 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2942 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2949 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2950 struct policy_handle *handle, uint32_t rid)
2953 struct samr_OpenGroup r;
2954 struct policy_handle group_handle;
2957 printf("Testing OpenGroup(%u)\n", rid);
2959 r.in.domain_handle = handle;
2960 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2962 r.out.group_handle = &group_handle;
2964 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2965 if (!NT_STATUS_IS_OK(status)) {
2966 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2970 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2974 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2978 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2982 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2989 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2990 struct policy_handle *handle, uint32_t rid)
2993 struct samr_OpenAlias r;
2994 struct policy_handle alias_handle;
2997 printf("Testing OpenAlias(%u)\n", rid);
2999 r.in.domain_handle = handle;
3000 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3002 r.out.alias_handle = &alias_handle;
3004 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3005 if (!NT_STATUS_IS_OK(status)) {
3006 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3010 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3014 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3018 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3022 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3029 static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3030 struct policy_handle *handle, uint32_t rid,
3031 uint32_t acct_flag_mask)
3034 struct samr_OpenUser r;
3035 struct samr_QueryUserInfo q;
3036 struct policy_handle user_handle;
3039 printf("Testing OpenUser(%u)\n", rid);
3041 r.in.domain_handle = handle;
3042 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3044 r.out.user_handle = &user_handle;
3046 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3047 if (!NT_STATUS_IS_OK(status)) {
3048 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3052 q.in.user_handle = &user_handle;
3055 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3056 if (!NT_STATUS_IS_OK(status)) {
3057 printf("QueryUserInfo level 16 failed - %s\n",
3061 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3062 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3063 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3068 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3075 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3076 struct policy_handle *handle)
3078 NTSTATUS status = STATUS_MORE_ENTRIES;
3079 struct samr_EnumDomainUsers r;
3080 uint32_t mask, resume_handle=0;
3083 struct samr_LookupNames n;
3084 struct samr_LookupRids lr ;
3085 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3086 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3087 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3090 printf("Testing EnumDomainUsers\n");
3092 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3093 r.in.domain_handle = handle;
3094 r.in.resume_handle = &resume_handle;
3095 r.in.acct_flags = mask = masks[mask_idx];
3096 r.in.max_size = (uint32_t)-1;
3097 r.out.resume_handle = &resume_handle;
3099 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3100 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3101 !NT_STATUS_IS_OK(status)) {
3102 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3107 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3111 if (r.out.sam->count == 0) {
3115 for (i=0;i<r.out.sam->count;i++) {
3117 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3120 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3126 printf("Testing LookupNames\n");
3127 n.in.domain_handle = handle;
3128 n.in.num_names = r.out.sam->count;
3129 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3130 for (i=0;i<r.out.sam->count;i++) {
3131 n.in.names[i].string = r.out.sam->entries[i].name.string;
3133 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3134 if (!NT_STATUS_IS_OK(status)) {
3135 printf("LookupNames failed - %s\n", nt_errstr(status));
3140 printf("Testing LookupRids\n");
3141 lr.in.domain_handle = handle;
3142 lr.in.num_rids = r.out.sam->count;
3143 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3144 for (i=0;i<r.out.sam->count;i++) {
3145 lr.in.rids[i] = r.out.sam->entries[i].idx;
3147 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3148 if (!NT_STATUS_IS_OK(status)) {
3149 printf("LookupRids failed - %s\n", nt_errstr(status));
3157 try blasting the server with a bunch of sync requests
3159 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3160 struct policy_handle *handle)
3163 struct samr_EnumDomainUsers r;
3164 uint32_t resume_handle=0;
3166 #define ASYNC_COUNT 100
3167 struct rpc_request *req[ASYNC_COUNT];
3169 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
3170 printf("samr async test disabled - enable dangerous tests to use\n");
3174 printf("Testing EnumDomainUsers_async\n");
3176 r.in.domain_handle = handle;
3177 r.in.resume_handle = &resume_handle;
3178 r.in.acct_flags = 0;
3179 r.in.max_size = (uint32_t)-1;
3180 r.out.resume_handle = &resume_handle;
3182 for (i=0;i<ASYNC_COUNT;i++) {
3183 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
3186 for (i=0;i<ASYNC_COUNT;i++) {
3187 status = dcerpc_ndr_request_recv(req[i]);
3188 if (!NT_STATUS_IS_OK(status)) {
3189 printf("EnumDomainUsers[%d] failed - %s\n",
3190 i, nt_errstr(status));
3195 printf("%d async requests OK\n", i);
3200 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3201 struct policy_handle *handle)
3204 struct samr_EnumDomainGroups r;
3205 uint32_t resume_handle=0;
3209 printf("Testing EnumDomainGroups\n");
3211 r.in.domain_handle = handle;
3212 r.in.resume_handle = &resume_handle;
3213 r.in.max_size = (uint32_t)-1;
3214 r.out.resume_handle = &resume_handle;
3216 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3217 if (!NT_STATUS_IS_OK(status)) {
3218 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3226 for (i=0;i<r.out.sam->count;i++) {
3227 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3235 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3236 struct policy_handle *handle)
3239 struct samr_EnumDomainAliases r;
3240 uint32_t resume_handle=0;
3244 printf("Testing EnumDomainAliases\n");
3246 r.in.domain_handle = handle;
3247 r.in.resume_handle = &resume_handle;
3248 r.in.acct_flags = (uint32_t)-1;
3249 r.out.resume_handle = &resume_handle;
3251 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3252 if (!NT_STATUS_IS_OK(status)) {
3253 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3261 for (i=0;i<r.out.sam->count;i++) {
3262 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3270 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3271 struct policy_handle *handle)
3274 struct samr_GetDisplayEnumerationIndex r;
3276 uint16_t levels[] = {1, 2, 3, 4, 5};
3277 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3280 for (i=0;i<ARRAY_SIZE(levels);i++) {
3281 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3283 r.in.domain_handle = handle;
3284 r.in.level = levels[i];
3285 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3287 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3290 !NT_STATUS_IS_OK(status) &&
3291 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3292 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3293 levels[i], nt_errstr(status));
3297 init_lsa_String(&r.in.name, "zzzzzzzz");
3299 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3301 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3302 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3303 levels[i], nt_errstr(status));
3311 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3312 struct policy_handle *handle)
3315 struct samr_GetDisplayEnumerationIndex2 r;
3317 uint16_t levels[] = {1, 2, 3, 4, 5};
3318 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3321 for (i=0;i<ARRAY_SIZE(levels);i++) {
3322 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3324 r.in.domain_handle = handle;
3325 r.in.level = levels[i];
3326 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3328 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3330 !NT_STATUS_IS_OK(status) &&
3331 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3332 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3333 levels[i], nt_errstr(status));
3337 init_lsa_String(&r.in.name, "zzzzzzzz");
3339 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3340 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3341 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3342 levels[i], nt_errstr(status));
3350 #define STRING_EQUAL_QUERY(s1, s2, user) \
3351 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3352 /* odd, but valid */ \
3353 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3354 printf("%s mismatch for %s: %s != %s (%s)\n", \
3355 #s1, user.string, s1.string, s2.string, __location__); \
3358 #define INT_EQUAL_QUERY(s1, s2, user) \
3360 printf("%s mismatch for %s: 0x%x != 0x%x (%s)\n", \
3361 #s1, user.string, (unsigned int)s1, (unsigned int)s2, __location__); \
3365 static BOOL test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3366 struct samr_QueryDisplayInfo *querydisplayinfo,
3367 bool *seen_testuser)
3369 struct samr_OpenUser r;
3370 struct samr_QueryUserInfo q;
3371 struct policy_handle user_handle;
3374 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3375 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3376 for (i = 0; ; i++) {
3377 switch (querydisplayinfo->in.level) {
3379 if (i >= querydisplayinfo->out.info.info1.count) {
3382 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3385 if (i >= querydisplayinfo->out.info.info2.count) {
3388 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3394 /* Not interested in validating just the account name */
3398 r.out.user_handle = &user_handle;
3400 switch (querydisplayinfo->in.level) {
3403 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3404 if (!NT_STATUS_IS_OK(status)) {
3405 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3410 q.in.user_handle = &user_handle;
3412 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3413 if (!NT_STATUS_IS_OK(status)) {
3414 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3418 switch (querydisplayinfo->in.level) {
3420 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3421 *seen_testuser = true;
3423 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3424 q.out.info->info21.full_name, q.out.info->info21.account_name);
3425 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3426 q.out.info->info21.account_name, q.out.info->info21.account_name);
3427 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3428 q.out.info->info21.description, q.out.info->info21.account_name);
3429 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3430 q.out.info->info21.rid, q.out.info->info21.account_name);
3431 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3432 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3436 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3437 q.out.info->info21.account_name, q.out.info->info21.account_name);
3438 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3439 q.out.info->info21.description, q.out.info->info21.account_name);
3440 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3441 q.out.info->info21.rid, q.out.info->info21.account_name);
3442 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3443 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3445 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3446 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3447 q.out.info->info21.account_name.string);
3450 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3451 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3452 q.out.info->info21.account_name.string,
3453 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3454 q.out.info->info21.acct_flags);
3461 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3468 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3469 struct policy_handle *handle)
3472 struct samr_QueryDisplayInfo r;
3473 struct samr_QueryDomainInfo dom_info;
3475 uint16_t levels[] = {1, 2, 3, 4, 5};
3477 bool seen_testuser = false;
3479 for (i=0;i<ARRAY_SIZE(levels);i++) {
3480 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3483 status = STATUS_MORE_ENTRIES;
3484 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3485 r.in.domain_handle = handle;
3486 r.in.level = levels[i];
3487 r.in.max_entries = 2;
3488 r.in.buf_size = (uint32_t)-1;
3490 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3491 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3492 printf("QueryDisplayInfo level %u failed - %s\n",
3493 levels[i], nt_errstr(status));
3496 switch (r.in.level) {
3498 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3501 r.in.start_idx += r.out.info.info1.count;
3504 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3507 r.in.start_idx += r.out.info.info2.count;
3510 r.in.start_idx += r.out.info.info3.count;
3513 r.in.start_idx += r.out.info.info4.count;
3516 r.in.start_idx += r.out.info.info5.count;
3520 dom_info.in.domain_handle = handle;
3521 dom_info.in.level = 2;
3522 /* Check number of users returned is correct */
3523 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3524 if (!NT_STATUS_IS_OK(status)) {
3525 printf("QueryDomainInfo level %u failed - %s\n",
3526 r.in.level, nt_errstr(status));
3530 switch (r.in.level) {
3533 if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3534 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3535 r.in.start_idx, dom_info.out.info->info2.num_groups,
3536 dom_info.out.info->info2.domain_name.string);
3539 if (!seen_testuser) {
3540 struct policy_handle user_handle;
3541 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3542 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3543 dom_info.out.info->info2.domain_name.string);
3545 test_samr_handle_Close(p, mem_ctx, &user_handle);
3551 if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3552 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3553 r.in.start_idx, dom_info.out.info->info2.num_groups,
3554 dom_info.out.info->info2.domain_name.string);
3566 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3567 struct policy_handle *handle)
3570 struct samr_QueryDisplayInfo2 r;
3572 uint16_t levels[] = {1, 2, 3, 4, 5};
3575 for (i=0;i<ARRAY_SIZE(levels);i++) {
3576 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3578 r.in.domain_handle = handle;
3579 r.in.level = levels[i];
3581 r.in.max_entries = 1000;
3582 r.in.buf_size = (uint32_t)-1;
3584 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3585 if (!NT_STATUS_IS_OK(status)) {
3586 printf("QueryDisplayInfo2 level %u failed - %s\n",
3587 levels[i], nt_errstr(status));
3595 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3596 struct policy_handle *handle)
3599 struct samr_QueryDisplayInfo3 r;
3601 uint16_t levels[] = {1, 2, 3, 4, 5};
3604 for (i=0;i<ARRAY_SIZE(levels);i++) {
3605 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3607 r.in.domain_handle = handle;
3608 r.in.level = levels[i];
3610 r.in.max_entries = 1000;
3611 r.in.buf_size = (uint32_t)-1;
3613 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3614 if (!NT_STATUS_IS_OK(status)) {
3615 printf("QueryDisplayInfo3 level %u failed - %s\n",
3616 levels[i], nt_errstr(status));
3625 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3626 struct policy_handle *handle)
3629 struct samr_QueryDisplayInfo r;
3632 printf("Testing QueryDisplayInfo continuation\n");
3634 r.in.domain_handle = handle;
3637 r.in.max_entries = 1;
3638 r.in.buf_size = (uint32_t)-1;
3641 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3642 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3643 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3644 printf("expected idx %d but got %d\n",
3646 r.out.info.info1.entries[0].idx);
3650 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3651 !NT_STATUS_IS_OK(status)) {
3652 printf("QueryDisplayInfo level %u failed - %s\n",
3653 r.in.level, nt_errstr(status));
3658 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3659 NT_STATUS_IS_OK(status)) &&
3660 r.out.returned_size != 0);
3665 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3666 struct policy_handle *handle)
3669 struct samr_QueryDomainInfo r;
3670 struct samr_SetDomainInfo s;
3671 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3672 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3675 const char *domain_comment = talloc_asprintf(mem_ctx,
3676 "Tortured by Samba4 RPC-SAMR: %s",
3677 timestring(mem_ctx, time(NULL)));
3679 s.in.domain_handle = handle;
3681 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3683 s.in.info->info4.comment.string = domain_comment;
3684 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3685 if (!NT_STATUS_IS_OK(status)) {
3686 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3687 r.in.level, nt_errstr(status));
3691 for (i=0;i<ARRAY_SIZE(levels);i++) {
3692 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3694 r.in.domain_handle = handle;
3695 r.in.level = levels[i];
3697 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3698 if (!NT_STATUS_IS_OK(status)) {
3699 printf("QueryDomainInfo level %u failed - %s\n",
3700 r.in.level, nt_errstr(status));
3705 switch (levels[i]) {
3707 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3708 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3709 levels[i], r.out.info->info2.comment.string, domain_comment);
3712 if (!r.out.info->info2.primary.string) {
3713 printf("QueryDomainInfo level %u returned no PDC name\n",
3716 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3717 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3718 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3719 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3724 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3725 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3726 levels[i], r.out.info->info4.comment.string, domain_comment);
3731 if (!r.out.info->info6.primary.string) {
3732 printf("QueryDomainInfo level %u returned no PDC name\n",
3738 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3739 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3740 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3746 printf("Testing SetDomainInfo level %u\n", levels[i]);
3748 s.in.domain_handle = handle;
3749 s.in.level = levels[i];
3750 s.in.info = r.out.info;
3752 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3754 if (!NT_STATUS_IS_OK(status)) {
3755 printf("SetDomainInfo level %u failed - %s\n",
3756 r.in.level, nt_errstr(status));
3761 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3762 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3763 r.in.level, nt_errstr(status));
3769 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3770 if (!NT_STATUS_IS_OK(status)) {
3771 printf("QueryDomainInfo level %u failed - %s\n",
3772 r.in.level, nt_errstr(status));
3782 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3783 struct policy_handle *handle)
3786 struct samr_QueryDomainInfo2 r;
3787 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3791 for (i=0;i<ARRAY_SIZE(levels);i++) {
3792 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3794 r.in.domain_handle = handle;
3795 r.in.level = levels[i];
3797 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3798 if (!NT_STATUS_IS_OK(status)) {
3799 printf("QueryDomainInfo2 level %u failed - %s\n",
3800 r.in.level, nt_errstr(status));
3809 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3810 set of group names. */
3811 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3812 struct policy_handle *handle)
3814 struct samr_EnumDomainGroups q1;
3815 struct samr_QueryDisplayInfo q2;
3817 uint32_t resume_handle=0;
3822 const char **names = NULL;
3824 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3826 q1.in.domain_handle = handle;
3827 q1.in.resume_handle = &resume_handle;
3829 q1.out.resume_handle = &resume_handle;
3831 status = STATUS_MORE_ENTRIES;
3832 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3833 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3835 if (!NT_STATUS_IS_OK(status) &&
3836 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3839 for (i=0; i<q1.out.num_entries; i++) {
3840 add_string_to_array(mem_ctx,
3841 q1.out.sam->entries[i].name.string,
3842 &names, &num_names);
3846 if (!NT_STATUS_IS_OK(status)) {
3847 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3855 q2.in.domain_handle = handle;
3857 q2.in.start_idx = 0;
3858 q2.in.max_entries = 5;
3859 q2.in.buf_size = (uint32_t)-1;
3861 status = STATUS_MORE_ENTRIES;
3862 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3863 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3865 if (!NT_STATUS_IS_OK(status) &&
3866 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3869 for (i=0; i<q2.out.info.info5.count; i++) {
3871 const char *name = q2.out.info.info5.entries[i].account_name.string;
3873 for (j=0; j<num_names; j++) {
3874 if (names[j] == NULL)
3876 /* Hmm. No strequal in samba4 */
3877 if (strequal(names[j], name)) {
3885 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3890 q2.in.start_idx += q2.out.info.info5.count;
3893 if (!NT_STATUS_IS_OK(status)) {
3894 printf("QueryDisplayInfo level 5 failed - %s\n",
3899 for (i=0; i<num_names; i++) {
3900 if (names[i] != NULL) {
3901 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3910 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3911 struct policy_handle *group_handle)
3913 struct samr_DeleteDomainGroup d;
3917 printf("Testing DeleteDomainGroup\n");
3919 d.in.group_handle = group_handle;
3920 d.out.group_handle = group_handle;
3922 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3923 if (!NT_STATUS_IS_OK(status)) {
3924 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3931 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3932 struct policy_handle *domain_handle)
3934 struct samr_TestPrivateFunctionsDomain r;
3938 printf("Testing TestPrivateFunctionsDomain\n");
3940 r.in.domain_handle = domain_handle;
3942 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3943 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3944 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3951 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3952 struct dom_sid *domain_sid,
3953 struct policy_handle *domain_handle)
3955 struct samr_RidToSid r;
3958 struct dom_sid *calc_sid;
3959 int rids[] = { 0, 42, 512, 10200 };
3962 for (i=0;i<ARRAY_SIZE(rids);i++) {
3964 printf("Testing RidToSid\n");
3966 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3967 r.in.domain_handle = domain_handle;
3970 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3971 if (!NT_STATUS_IS_OK(status)) {
3972 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3975 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3977 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3978 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3979 dom_sid_string(mem_ctx, r.out.sid),
3980 dom_sid_string(mem_ctx, calc_sid));
3989 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3990 struct policy_handle *domain_handle)
3992 struct samr_GetBootKeyInformation r;
3996 printf("Testing GetBootKeyInformation\n");
3998 r.in.domain_handle = domain_handle;
4000 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4001 if (!NT_STATUS_IS_OK(status)) {
4002 /* w2k3 seems to fail this sometimes and pass it sometimes */
4003 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4009 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4010 struct policy_handle *domain_handle,
4011 struct policy_handle *group_handle)
4014 struct samr_AddGroupMember r;
4015 struct samr_DeleteGroupMember d;
4016 struct samr_QueryGroupMember q;
4017 struct samr_SetMemberAttributesOfGroup s;
4021 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4022 if (!NT_STATUS_IS_OK(status)) {
4023 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4027 r.in.group_handle = group_handle;
4029 r.in.flags = 0; /* ??? */
4031 printf("Testing AddGroupMember and DeleteGroupMember\n");
4033 d.in.group_handle = group_handle;
4036 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
4037 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4038 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4043 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4044 if (!NT_STATUS_IS_OK(status)) {
4045 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4049 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4050 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4051 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4056 if (lp_parm_bool(-1, "torture", "samba4", False)) {
4057 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4059 /* this one is quite strange. I am using random inputs in the
4060 hope of triggering an error that might give us a clue */
4062 s.in.group_handle = group_handle;
4063 s.in.unknown1 = random();
4064 s.in.unknown2 = random();
4066 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
4067 if (!NT_STATUS_IS_OK(status)) {
4068 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4073 q.in.group_handle = group_handle;
4075 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
4076 if (!NT_STATUS_IS_OK(status)) {
4077 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4081 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
4082 if (!NT_STATUS_IS_OK(status)) {
4083 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4087 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4088 if (!NT_STATUS_IS_OK(status)) {
4089 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4097 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4098 struct policy_handle *domain_handle, struct policy_handle *group_handle)
4101 struct samr_CreateDomainGroup r;
4103 struct lsa_String name;
4106 init_lsa_String(&name, TEST_GROUPNAME);
4108 r.in.domain_handle = domain_handle;
4110 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4111 r.out.group_handle = group_handle;
4114 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4116 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4118 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4119 printf("Server refused create of '%s'\n", r.in.name->string);
4120 ZERO_STRUCTP(group_handle);
4124 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4125 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4127 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4131 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4133 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4134 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4136 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4140 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4142 if (!NT_STATUS_IS_OK(status)) {
4143 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4147 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4148 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4152 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4161 its not totally clear what this does. It seems to accept any sid you like.
4163 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4164 TALLOC_CTX *mem_ctx,
4165 struct policy_handle *domain_handle)
4168 struct samr_RemoveMemberFromForeignDomain r;
4170 r.in.domain_handle = domain_handle;
4171 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4173 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4174 if (!NT_STATUS_IS_OK(status)) {
4175 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4184 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4185 struct policy_handle *handle);
4187 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4188 struct policy_handle *handle, struct dom_sid *sid,
4189 enum torture_samr_choice which_ops)
4192 struct samr_OpenDomain r;
4193 struct policy_handle domain_handle;
4194 struct policy_handle alias_handle;
4195 struct policy_handle user_handle;
4196 struct policy_handle group_handle;
4199 ZERO_STRUCT(alias_handle);
4200 ZERO_STRUCT(user_handle);
4201 ZERO_STRUCT(group_handle);
4202 ZERO_STRUCT(domain_handle);
4204 printf("Testing OpenDomain\n");
4206 r.in.connect_handle = handle;
4207 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4209 r.out.domain_handle = &domain_handle;
4211 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
4212 if (!NT_STATUS_IS_OK(status)) {
4213 printf("OpenDomain failed - %s\n", nt_errstr(status));
4217 /* run the domain tests with the main handle closed - this tests
4218 the servers reference counting */
4219 ret &= test_samr_handle_Close(p, mem_ctx, handle);
4221 switch (which_ops) {
4222 case TORTURE_SAMR_USER_ATTRIBUTES:
4223 case TORTURE_SAMR_PASSWORDS:
4224 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
4225 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4226 /* This test needs 'complex' users to validate */
4227 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
4229 case TORTURE_SAMR_OTHER:
4230 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4231 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
4232 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
4233 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
4234 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
4235 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
4236 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
4237 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
4238 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
4239 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
4240 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
4241 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
4242 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
4243 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
4245 if (lp_parm_bool(-1, "torture", "samba4", False)) {
4246 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4248 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
4249 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
4251 ret &= test_GroupList(p, mem_ctx, &domain_handle);
4252 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
4253 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
4254 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
4258 if (!policy_handle_empty(&user_handle) &&
4259 !test_DeleteUser(p, mem_ctx, &user_handle)) {
4263 if (!policy_handle_empty(&alias_handle) &&
4264 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
4268 if (!policy_handle_empty(&group_handle) &&
4269 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
4273 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
4275 /* reconnect the main handle */
4276 ret &= test_Connect(p, mem_ctx, handle);
4279 printf("Testing domain %s failed!\n", dom_sid_string(mem_ctx, sid));
4285 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4286 struct policy_handle *handle, const char *domain,
4287 enum torture_samr_choice which_ops)
4290 struct samr_LookupDomain r;
4291 struct lsa_String n1;
4292 struct lsa_String n2;
4295 printf("Testing LookupDomain(%s)\n", domain);
4297 /* check for correct error codes */
4298 r.in.connect_handle = handle;
4299 r.in.domain_name = &n2;
4302 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4303 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4304 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4308 init_lsa_String(&n2, "xxNODOMAINxx");
4310 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4311 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4312 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4316 r.in.connect_handle = handle;
4318 init_lsa_String(&n1, domain);
4319 r.in.domain_name = &n1;
4321 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4322 if (!NT_STATUS_IS_OK(status)) {
4323 printf("LookupDomain failed - %s\n", nt_errstr(status));
4327 if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
4331 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
4339 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4340 struct policy_handle *handle, enum torture_samr_choice which_ops)
4343 struct samr_EnumDomains r;
4344 uint32_t resume_handle = 0;
4348 r.in.connect_handle = handle;
4349 r.in.resume_handle = &resume_handle;
4350 r.in.buf_size = (uint32_t)-1;
4351 r.out.resume_handle = &resume_handle;
4353 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4354 if (!NT_STATUS_IS_OK(status)) {
4355 printf("EnumDomains failed - %s\n", nt_errstr(status));
4363 for (i=0;i<r.out.sam->count;i++) {
4364 if (!test_LookupDomain(p, mem_ctx, handle,
4365 r.out.sam->entries[i].name.string, which_ops)) {
4370 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4371 if (!NT_STATUS_IS_OK(status)) {
4372 printf("EnumDomains failed - %s\n", nt_errstr(status));
4380 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4381 struct policy_handle *handle)
4384 struct samr_Connect r;
4385 struct samr_Connect2 r2;
4386 struct samr_Connect3 r3;
4387 struct samr_Connect4 r4;
4388 struct samr_Connect5 r5;
4389 union samr_ConnectInfo info;
4390 struct policy_handle h;
4391 BOOL ret = True, got_handle = False;
4393 printf("testing samr_Connect\n");
4395 r.in.system_name = 0;
4396 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4397 r.out.connect_handle = &h;
4399 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4400 if (!NT_STATUS_IS_OK(status)) {
4401 printf("Connect failed - %s\n", nt_errstr(status));
4408 printf("testing samr_Connect2\n");
4410 r2.in.system_name = NULL;
4411 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4412 r2.out.connect_handle = &h;
4414 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4415 if (!NT_STATUS_IS_OK(status)) {
4416 printf("Connect2 failed - %s\n", nt_errstr(status));
4420 test_samr_handle_Close(p, mem_ctx, handle);
4426 printf("testing samr_Connect3\n");
4428 r3.in.system_name = NULL;
4430 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4431 r3.out.connect_handle = &h;
4433 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4434 if (!NT_STATUS_IS_OK(status)) {
4435 printf("Connect3 failed - %s\n", nt_errstr(status));
4439 test_samr_handle_Close(p, mem_ctx, handle);
4445 printf("testing samr_Connect4\n");
4447 r4.in.system_name = "";
4449 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4450 r4.out.connect_handle = &h;
4452 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4453 if (!NT_STATUS_IS_OK(status)) {
4454 printf("Connect4 failed - %s\n", nt_errstr(status));
4458 test_samr_handle_Close(p, mem_ctx, handle);
4464 printf("testing samr_Connect5\n");
4466 info.info1.unknown1 = 0;
4467 info.info1.unknown2 = 0;
4469 r5.in.system_name = "";
4470 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4473 r5.out.info = &info;
4474 r5.out.connect_handle = &h;
4476 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4477 if (!NT_STATUS_IS_OK(status)) {
4478 printf("Connect5 failed - %s\n", nt_errstr(status));
4482 test_samr_handle_Close(p, mem_ctx, handle);
4492 BOOL torture_rpc_samr(struct torture_context *torture)
4495 struct dcerpc_pipe *p;
4497 struct policy_handle handle;
4499 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4500 if (!NT_STATUS_IS_OK(status)) {
4504 ret &= test_Connect(p, torture, &handle);
4506 ret &= test_QuerySecurity(p, torture, &handle);
4508 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4510 ret &= test_SetDsrmPassword(p, torture, &handle);
4512 ret &= test_Shutdown(p, torture, &handle);
4514 ret &= test_samr_handle_Close(p, torture, &handle);
4520 BOOL torture_rpc_samr_users(struct torture_context *torture)
4523 struct dcerpc_pipe *p;
4525 struct policy_handle handle;
4527 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4528 if (!NT_STATUS_IS_OK(status)) {
4532 ret &= test_Connect(p, torture, &handle);
4534 ret &= test_QuerySecurity(p, torture, &handle);
4536 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4538 ret &= test_SetDsrmPassword(p, torture, &handle);
4540 ret &= test_Shutdown(p, torture, &handle);
4542 ret &= test_samr_handle_Close(p, torture, &handle);
4548 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
4551 struct dcerpc_pipe *p;
4553 struct policy_handle handle;
4555 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4556 if (!NT_STATUS_IS_OK(status)) {
4560 ret &= test_Connect(p, torture, &handle);
4562 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4564 ret &= test_samr_handle_Close(p, torture, &handle);