2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
38 enum torture_samr_choice {
39 TORTURE_SAMR_PASSWORDS,
40 TORTURE_SAMR_USER_ATTRIBUTES,
44 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 const char *acct_name,
55 struct policy_handle *domain_handle, char **password);
57 static void init_lsa_String(struct lsa_String *string, const char *s)
62 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
63 struct policy_handle *handle)
69 r.out.handle = handle;
71 status = dcerpc_samr_Close(p, mem_ctx, &r);
72 if (!NT_STATUS_IS_OK(status)) {
73 printf("Close handle failed - %s\n", nt_errstr(status));
80 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
81 struct policy_handle *handle)
84 struct samr_Shutdown r;
86 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
87 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
91 r.in.connect_handle = handle;
93 printf("testing samr_Shutdown\n");
95 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
96 if (!NT_STATUS_IS_OK(status)) {
97 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
104 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
105 struct policy_handle *handle)
108 struct samr_SetDsrmPassword r;
109 struct lsa_String string;
110 struct samr_Password hash;
112 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
113 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
117 E_md4hash("TeSTDSRM123", hash.hash);
119 init_lsa_String(&string, "Administrator");
125 printf("testing samr_SetDsrmPassword\n");
127 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
128 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
129 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
137 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
138 struct policy_handle *handle)
141 struct samr_QuerySecurity r;
142 struct samr_SetSecurity s;
144 r.in.handle = handle;
147 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
148 if (!NT_STATUS_IS_OK(status)) {
149 printf("QuerySecurity failed - %s\n", nt_errstr(status));
153 if (r.out.sdbuf == NULL) {
157 s.in.handle = handle;
159 s.in.sdbuf = r.out.sdbuf;
161 if (lp_parm_bool(-1, "torture", "samba4", False)) {
162 printf("skipping SetSecurity test against Samba4\n");
166 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
167 if (!NT_STATUS_IS_OK(status)) {
168 printf("SetSecurity failed - %s\n", nt_errstr(status));
172 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
173 if (!NT_STATUS_IS_OK(status)) {
174 printf("QuerySecurity failed - %s\n", nt_errstr(status));
182 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
183 struct policy_handle *handle, uint32_t base_acct_flags,
184 const char *base_account_name)
187 struct samr_SetUserInfo s;
188 struct samr_SetUserInfo2 s2;
189 struct samr_QueryUserInfo q;
190 struct samr_QueryUserInfo q0;
191 union samr_UserInfo u;
193 const char *test_account_name;
195 uint32_t user_extra_flags = 0;
196 if (base_acct_flags == ACB_NORMAL) {
197 /* When created, accounts are expired by default */
198 user_extra_flags = ACB_PW_EXPIRED;
201 s.in.user_handle = handle;
204 s2.in.user_handle = handle;
207 q.in.user_handle = handle;
211 #define TESTCALL(call, r) \
212 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
213 if (!NT_STATUS_IS_OK(status)) { \
214 printf(#call " level %u failed - %s (%s)\n", \
215 r.in.level, nt_errstr(status), __location__); \
220 #define STRING_EQUAL(s1, s2, field) \
221 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
222 printf("Failed to set %s to '%s' (%s)\n", \
223 #field, s2, __location__); \
228 #define INT_EQUAL(i1, i2, field) \
230 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
231 #field, i2, i1, __location__); \
236 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
237 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
239 TESTCALL(QueryUserInfo, q) \
241 s2.in.level = lvl1; \
244 ZERO_STRUCT(u.info21); \
245 u.info21.fields_present = fpval; \
247 init_lsa_String(&u.info ## lvl1.field1, value); \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 init_lsa_String(&u.info ## lvl1.field1, ""); \
251 TESTCALL(QueryUserInfo, q); \
253 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
255 TESTCALL(QueryUserInfo, q) \
257 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
261 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
263 TESTCALL(QueryUserInfo, q) \
265 s2.in.level = lvl1; \
268 uint8_t *bits = u.info21.logon_hours.bits; \
269 ZERO_STRUCT(u.info21); \
270 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
271 u.info21.logon_hours.units_per_week = 168; \
272 u.info21.logon_hours.bits = bits; \
274 u.info21.fields_present = fpval; \
276 u.info ## lvl1.field1 = value; \
277 TESTCALL(SetUserInfo, s) \
278 TESTCALL(SetUserInfo2, s2) \
279 u.info ## lvl1.field1 = 0; \
280 TESTCALL(QueryUserInfo, q); \
282 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
284 TESTCALL(QueryUserInfo, q) \
286 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
289 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
290 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
294 do { TESTCALL(QueryUserInfo, q0) } while (0);
296 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
297 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
298 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
301 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
302 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
303 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
304 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
305 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
306 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
307 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
308 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
309 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
310 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
311 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
312 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
313 test_account_name = base_account_name;
314 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
315 SAMR_FIELD_ACCOUNT_NAME);
317 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
318 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
319 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
323 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
324 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
325 SAMR_FIELD_FULL_NAME);
327 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
328 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
329 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
333 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
334 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
335 SAMR_FIELD_FULL_NAME);
337 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
338 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
339 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
340 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
341 SAMR_FIELD_LOGON_SCRIPT);
343 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
344 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
345 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
346 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
347 SAMR_FIELD_PROFILE_PATH);
349 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
350 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
351 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
352 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
353 SAMR_FIELD_HOME_DIRECTORY);
354 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
355 SAMR_FIELD_HOME_DIRECTORY);
357 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
358 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
359 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
360 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
361 SAMR_FIELD_HOME_DRIVE);
362 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
363 SAMR_FIELD_HOME_DRIVE);
365 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
366 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
367 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
368 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
369 SAMR_FIELD_DESCRIPTION);
371 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
372 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
373 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
374 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
375 SAMR_FIELD_WORKSTATIONS);
377 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
378 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
379 SAMR_FIELD_PARAMETERS);
381 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
382 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
383 SAMR_FIELD_COUNTRY_CODE);
385 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
386 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
387 SAMR_FIELD_CODE_PAGE);
389 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
390 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
391 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
392 SAMR_FIELD_ACCT_EXPIRY);
394 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
395 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
396 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
397 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
398 SAMR_FIELD_LOGON_HOURS);
400 if (lp_parm_bool(-1, "torture", "samba4", False)) {
401 printf("skipping Set Account Flag tests against Samba4\n");
405 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
406 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
407 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
409 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
410 (base_acct_flags | ACB_DISABLED),
411 (base_acct_flags | ACB_DISABLED | user_extra_flags),
414 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
415 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
416 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
417 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
419 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
420 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
421 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
425 /* The 'autolock' flag doesn't stick - check this */
426 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
427 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
428 (base_acct_flags | ACB_DISABLED | user_extra_flags),
431 /* Removing the 'disabled' flag doesn't stick - check this */
432 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
434 (base_acct_flags | ACB_DISABLED | user_extra_flags),
437 /* The 'store plaintext' flag does stick */
438 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
439 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
440 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
442 /* The 'use DES' flag does stick */
443 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
444 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
445 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
447 /* The 'don't require kerberos pre-authentication flag does stick */
448 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
449 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
450 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
452 /* The 'no kerberos PAC required' flag sticks */
453 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
454 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
455 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
458 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
459 (base_acct_flags | ACB_DISABLED),
460 (base_acct_flags | ACB_DISABLED | user_extra_flags),
461 SAMR_FIELD_ACCT_FLAGS);
464 /* these fail with win2003 - it appears you can't set the primary gid?
465 the set succeeds, but the gid isn't changed. Very weird! */
466 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
467 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
468 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
469 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
476 generate a random password for password change tests
478 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
480 size_t len = MAX(8, min_len) + (random() % 6);
481 char *s = generate_random_str(mem_ctx, len);
482 printf("Generated password '%s'\n", s);
487 generate a random password for password change tests (fixed length)
489 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
491 char *s = generate_random_str(mem_ctx, len);
492 printf("Generated password '%s'\n", s);
496 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
497 struct policy_handle *handle, char **password)
500 struct samr_SetUserInfo s;
501 union samr_UserInfo u;
503 DATA_BLOB session_key;
505 struct samr_GetUserPwInfo pwp;
506 int policy_min_pw_len = 0;
507 pwp.in.user_handle = handle;
509 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
510 if (NT_STATUS_IS_OK(status)) {
511 policy_min_pw_len = pwp.out.info.min_password_length;
513 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
515 s.in.user_handle = handle;
519 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
520 /* w2k3 ignores this length */
521 u.info24.pw_len = strlen_m(newpass) * 2;
523 status = dcerpc_fetch_session_key(p, &session_key);
524 if (!NT_STATUS_IS_OK(status)) {
525 printf("SetUserInfo level %u - no session key - %s\n",
526 s.in.level, nt_errstr(status));
530 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
532 printf("Testing SetUserInfo level 24 (set password)\n");
534 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
535 if (!NT_STATUS_IS_OK(status)) {
536 printf("SetUserInfo level %u failed - %s\n",
537 s.in.level, nt_errstr(status));
547 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
548 struct policy_handle *handle, uint32_t fields_present,
552 struct samr_SetUserInfo s;
553 union samr_UserInfo u;
555 DATA_BLOB session_key;
557 struct samr_GetUserPwInfo pwp;
558 int policy_min_pw_len = 0;
559 pwp.in.user_handle = handle;
561 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
562 if (NT_STATUS_IS_OK(status)) {
563 policy_min_pw_len = pwp.out.info.min_password_length;
565 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
567 s.in.user_handle = handle;
573 u.info23.info.fields_present = fields_present;
575 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
577 status = dcerpc_fetch_session_key(p, &session_key);
578 if (!NT_STATUS_IS_OK(status)) {
579 printf("SetUserInfo level %u - no session key - %s\n",
580 s.in.level, nt_errstr(status));
584 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
586 printf("Testing SetUserInfo level 23 (set password)\n");
588 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
589 if (!NT_STATUS_IS_OK(status)) {
590 printf("SetUserInfo level %u failed - %s\n",
591 s.in.level, nt_errstr(status));
597 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
599 status = dcerpc_fetch_session_key(p, &session_key);
600 if (!NT_STATUS_IS_OK(status)) {
601 printf("SetUserInfo level %u - no session key - %s\n",
602 s.in.level, nt_errstr(status));
606 /* This should break the key nicely */
607 session_key.length--;
608 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
610 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
612 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
613 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
614 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
615 s.in.level, nt_errstr(status));
623 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
624 struct policy_handle *handle, bool makeshort,
628 struct samr_SetUserInfo s;
629 union samr_UserInfo u;
631 DATA_BLOB session_key;
632 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
633 uint8_t confounder[16];
635 struct MD5Context ctx;
636 struct samr_GetUserPwInfo pwp;
637 int policy_min_pw_len = 0;
638 pwp.in.user_handle = handle;
640 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
641 if (NT_STATUS_IS_OK(status)) {
642 policy_min_pw_len = pwp.out.info.min_password_length;
644 if (makeshort && policy_min_pw_len) {
645 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
647 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
650 s.in.user_handle = handle;
654 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
655 u.info26.pw_len = strlen(newpass);
657 status = dcerpc_fetch_session_key(p, &session_key);
658 if (!NT_STATUS_IS_OK(status)) {
659 printf("SetUserInfo level %u - no session key - %s\n",
660 s.in.level, nt_errstr(status));
664 generate_random_buffer((uint8_t *)confounder, 16);
667 MD5Update(&ctx, confounder, 16);
668 MD5Update(&ctx, session_key.data, session_key.length);
669 MD5Final(confounded_session_key.data, &ctx);
671 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
672 memcpy(&u.info26.password.data[516], confounder, 16);
674 printf("Testing SetUserInfo level 26 (set password ex)\n");
676 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
677 if (!NT_STATUS_IS_OK(status)) {
678 printf("SetUserInfo level %u failed - %s\n",
679 s.in.level, nt_errstr(status));
685 /* This should break the key nicely */
686 confounded_session_key.data[0]++;
688 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
689 memcpy(&u.info26.password.data[516], confounder, 16);
691 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
693 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
694 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
695 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
696 s.in.level, nt_errstr(status));
705 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
706 struct policy_handle *handle, uint32_t fields_present,
710 struct samr_SetUserInfo s;
711 union samr_UserInfo u;
713 DATA_BLOB session_key;
714 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
715 struct MD5Context ctx;
716 uint8_t confounder[16];
718 struct samr_GetUserPwInfo pwp;
719 int policy_min_pw_len = 0;
720 pwp.in.user_handle = handle;
722 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
723 if (NT_STATUS_IS_OK(status)) {
724 policy_min_pw_len = pwp.out.info.min_password_length;
726 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
728 s.in.user_handle = handle;
734 u.info25.info.fields_present = fields_present;
736 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
738 status = dcerpc_fetch_session_key(p, &session_key);
739 if (!NT_STATUS_IS_OK(status)) {
740 printf("SetUserInfo level %u - no session key - %s\n",
741 s.in.level, nt_errstr(status));
745 generate_random_buffer((uint8_t *)confounder, 16);
748 MD5Update(&ctx, confounder, 16);
749 MD5Update(&ctx, session_key.data, session_key.length);
750 MD5Final(confounded_session_key.data, &ctx);
752 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
753 memcpy(&u.info25.password.data[516], confounder, 16);
755 printf("Testing SetUserInfo level 25 (set password ex)\n");
757 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
758 if (!NT_STATUS_IS_OK(status)) {
759 printf("SetUserInfo level %u failed - %s\n",
760 s.in.level, nt_errstr(status));
766 /* This should break the key nicely */
767 confounded_session_key.data[0]++;
769 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
770 memcpy(&u.info25.password.data[516], confounder, 16);
772 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
774 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
775 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
776 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
777 s.in.level, nt_errstr(status));
784 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
785 struct policy_handle *handle)
788 struct samr_SetAliasInfo r;
789 struct samr_QueryAliasInfo q;
790 uint16_t levels[] = {2, 3};
794 /* Ignoring switch level 1, as that includes the number of members for the alias
795 * and setting this to a wrong value might have negative consequences
798 for (i=0;i<ARRAY_SIZE(levels);i++) {
799 printf("Testing SetAliasInfo level %u\n", levels[i]);
801 r.in.alias_handle = handle;
802 r.in.level = levels[i];
803 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
804 switch (r.in.level) {
805 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
806 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
807 "Test Description, should test I18N as well"); break;
810 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
811 if (!NT_STATUS_IS_OK(status)) {
812 printf("SetAliasInfo level %u failed - %s\n",
813 levels[i], nt_errstr(status));
817 q.in.alias_handle = handle;
818 q.in.level = levels[i];
820 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
821 if (!NT_STATUS_IS_OK(status)) {
822 printf("QueryAliasInfo level %u failed - %s\n",
823 levels[i], nt_errstr(status));
831 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
832 struct policy_handle *user_handle)
834 struct samr_GetGroupsForUser r;
838 printf("testing GetGroupsForUser\n");
840 r.in.user_handle = user_handle;
842 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
843 if (!NT_STATUS_IS_OK(status)) {
844 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
852 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
853 struct lsa_String *domain_name)
856 struct samr_GetDomPwInfo r;
859 r.in.domain_name = domain_name;
860 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
862 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
863 if (!NT_STATUS_IS_OK(status)) {
864 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
868 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
869 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
871 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
872 if (!NT_STATUS_IS_OK(status)) {
873 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
877 r.in.domain_name->string = "\\\\__NONAME__";
878 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
880 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
881 if (!NT_STATUS_IS_OK(status)) {
882 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
886 r.in.domain_name->string = "\\\\Builtin";
887 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
889 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
890 if (!NT_STATUS_IS_OK(status)) {
891 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
899 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
900 struct policy_handle *handle)
903 struct samr_GetUserPwInfo r;
906 printf("Testing GetUserPwInfo\n");
908 r.in.user_handle = handle;
910 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
911 if (!NT_STATUS_IS_OK(status)) {
912 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
919 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
920 struct policy_handle *domain_handle, const char *name,
924 struct samr_LookupNames n;
925 struct lsa_String sname[2];
927 init_lsa_String(&sname[0], name);
929 n.in.domain_handle = domain_handle;
932 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
933 if (NT_STATUS_IS_OK(status)) {
934 *rid = n.out.rids.ids[0];
939 init_lsa_String(&sname[1], "xxNONAMExx");
941 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
942 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
943 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
944 if (NT_STATUS_IS_OK(status)) {
945 return NT_STATUS_UNSUCCESSFUL;
951 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
952 if (!NT_STATUS_IS_OK(status)) {
953 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
957 init_lsa_String(&sname[0], "xxNONAMExx");
959 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
960 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
961 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
962 if (NT_STATUS_IS_OK(status)) {
963 return NT_STATUS_UNSUCCESSFUL;
968 init_lsa_String(&sname[0], "xxNONAMExx");
969 init_lsa_String(&sname[1], "xxNONAME2xx");
971 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
972 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
973 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
974 if (NT_STATUS_IS_OK(status)) {
975 return NT_STATUS_UNSUCCESSFUL;
983 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
984 struct policy_handle *domain_handle,
985 const char *name, struct policy_handle *user_handle)
988 struct samr_OpenUser r;
991 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
992 if (!NT_STATUS_IS_OK(status)) {
996 r.in.domain_handle = domain_handle;
997 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
999 r.out.user_handle = user_handle;
1000 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1001 if (!NT_STATUS_IS_OK(status)) {
1002 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1009 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1010 struct policy_handle *handle)
1013 struct samr_ChangePasswordUser r;
1015 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1016 struct policy_handle user_handle;
1017 char *oldpass = "test";
1018 char *newpass = "test2";
1019 uint8_t old_nt_hash[16], new_nt_hash[16];
1020 uint8_t old_lm_hash[16], new_lm_hash[16];
1022 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1023 if (!NT_STATUS_IS_OK(status)) {
1027 printf("Testing ChangePasswordUser for user 'testuser'\n");
1029 printf("old password: %s\n", oldpass);
1030 printf("new password: %s\n", newpass);
1032 E_md4hash(oldpass, old_nt_hash);
1033 E_md4hash(newpass, new_nt_hash);
1034 E_deshash(oldpass, old_lm_hash);
1035 E_deshash(newpass, new_lm_hash);
1037 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1038 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1039 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1040 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1041 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1042 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1044 r.in.handle = &user_handle;
1045 r.in.lm_present = 1;
1046 r.in.old_lm_crypted = &hash1;
1047 r.in.new_lm_crypted = &hash2;
1048 r.in.nt_present = 1;
1049 r.in.old_nt_crypted = &hash3;
1050 r.in.new_nt_crypted = &hash4;
1051 r.in.cross1_present = 1;
1052 r.in.nt_cross = &hash5;
1053 r.in.cross2_present = 1;
1054 r.in.lm_cross = &hash6;
1056 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1062 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1070 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1071 const char *acct_name,
1072 struct policy_handle *handle, char **password)
1075 struct samr_ChangePasswordUser r;
1077 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1078 struct policy_handle user_handle;
1080 uint8_t old_nt_hash[16], new_nt_hash[16];
1081 uint8_t old_lm_hash[16], new_lm_hash[16];
1082 BOOL changed = True;
1085 struct samr_GetUserPwInfo pwp;
1086 int policy_min_pw_len = 0;
1088 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1089 if (!NT_STATUS_IS_OK(status)) {
1092 pwp.in.user_handle = &user_handle;
1094 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1095 if (NT_STATUS_IS_OK(status)) {
1096 policy_min_pw_len = pwp.out.info.min_password_length;
1098 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1100 printf("Testing ChangePasswordUser\n");
1103 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1107 oldpass = *password;
1109 E_md4hash(oldpass, old_nt_hash);
1110 E_md4hash(newpass, new_nt_hash);
1111 E_deshash(oldpass, old_lm_hash);
1112 E_deshash(newpass, new_lm_hash);
1114 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1115 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1116 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1117 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1118 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1119 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1121 r.in.user_handle = &user_handle;
1122 r.in.lm_present = 1;
1123 /* Break the LM hash */
1125 r.in.old_lm_crypted = &hash1;
1126 r.in.new_lm_crypted = &hash2;
1127 r.in.nt_present = 1;
1128 r.in.old_nt_crypted = &hash3;
1129 r.in.new_nt_crypted = &hash4;
1130 r.in.cross1_present = 1;
1131 r.in.nt_cross = &hash5;
1132 r.in.cross2_present = 1;
1133 r.in.lm_cross = &hash6;
1135 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1136 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1137 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1141 /* Unbreak the LM hash */
1144 r.in.user_handle = &user_handle;
1145 r.in.lm_present = 1;
1146 r.in.old_lm_crypted = &hash1;
1147 r.in.new_lm_crypted = &hash2;
1148 /* Break the NT hash */
1150 r.in.nt_present = 1;
1151 r.in.old_nt_crypted = &hash3;
1152 r.in.new_nt_crypted = &hash4;
1153 r.in.cross1_present = 1;
1154 r.in.nt_cross = &hash5;
1155 r.in.cross2_present = 1;
1156 r.in.lm_cross = &hash6;
1158 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1159 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1160 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1164 /* Unbreak the NT hash */
1167 r.in.user_handle = &user_handle;
1168 r.in.lm_present = 1;
1169 r.in.old_lm_crypted = &hash1;
1170 r.in.new_lm_crypted = &hash2;
1171 r.in.nt_present = 1;
1172 r.in.old_nt_crypted = &hash3;
1173 r.in.new_nt_crypted = &hash4;
1174 r.in.cross1_present = 1;
1175 r.in.nt_cross = &hash5;
1176 r.in.cross2_present = 1;
1177 /* Break the LM cross */
1179 r.in.lm_cross = &hash6;
1181 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1182 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1183 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1187 /* Unbreak the LM cross */
1190 r.in.user_handle = &user_handle;
1191 r.in.lm_present = 1;
1192 r.in.old_lm_crypted = &hash1;
1193 r.in.new_lm_crypted = &hash2;
1194 r.in.nt_present = 1;
1195 r.in.old_nt_crypted = &hash3;
1196 r.in.new_nt_crypted = &hash4;
1197 r.in.cross1_present = 1;
1198 /* Break the NT cross */
1200 r.in.nt_cross = &hash5;
1201 r.in.cross2_present = 1;
1202 r.in.lm_cross = &hash6;
1204 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1205 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1206 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1210 /* Unbreak the NT cross */
1214 /* Reset the hashes to not broken values */
1215 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1216 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1217 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1218 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1219 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1220 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1222 r.in.user_handle = &user_handle;
1223 r.in.lm_present = 1;
1224 r.in.old_lm_crypted = &hash1;
1225 r.in.new_lm_crypted = &hash2;
1226 r.in.nt_present = 1;
1227 r.in.old_nt_crypted = &hash3;
1228 r.in.new_nt_crypted = &hash4;
1229 r.in.cross1_present = 1;
1230 r.in.nt_cross = &hash5;
1231 r.in.cross2_present = 0;
1232 r.in.lm_cross = NULL;
1234 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1235 if (NT_STATUS_IS_OK(status)) {
1237 *password = newpass;
1238 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1239 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1244 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1246 E_md4hash(oldpass, old_nt_hash);
1247 E_md4hash(newpass, new_nt_hash);
1248 E_deshash(oldpass, old_lm_hash);
1249 E_deshash(newpass, new_lm_hash);
1252 /* Reset the hashes to not broken values */
1253 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1254 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1255 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1256 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1257 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1258 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1260 r.in.user_handle = &user_handle;
1261 r.in.lm_present = 1;
1262 r.in.old_lm_crypted = &hash1;
1263 r.in.new_lm_crypted = &hash2;
1264 r.in.nt_present = 1;
1265 r.in.old_nt_crypted = &hash3;
1266 r.in.new_nt_crypted = &hash4;
1267 r.in.cross1_present = 0;
1268 r.in.nt_cross = NULL;
1269 r.in.cross2_present = 1;
1270 r.in.lm_cross = &hash6;
1272 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1273 if (NT_STATUS_IS_OK(status)) {
1275 *password = newpass;
1276 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1277 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1282 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1284 E_md4hash(oldpass, old_nt_hash);
1285 E_md4hash(newpass, new_nt_hash);
1286 E_deshash(oldpass, old_lm_hash);
1287 E_deshash(newpass, new_lm_hash);
1290 /* Reset the hashes to not broken values */
1291 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1292 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1293 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1294 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1295 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1296 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1298 r.in.user_handle = &user_handle;
1299 r.in.lm_present = 1;
1300 r.in.old_lm_crypted = &hash1;
1301 r.in.new_lm_crypted = &hash2;
1302 r.in.nt_present = 1;
1303 r.in.old_nt_crypted = &hash3;
1304 r.in.new_nt_crypted = &hash4;
1305 r.in.cross1_present = 1;
1306 r.in.nt_cross = &hash5;
1307 r.in.cross2_present = 1;
1308 r.in.lm_cross = &hash6;
1310 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1311 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1312 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1313 } else if (!NT_STATUS_IS_OK(status)) {
1314 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1318 *password = newpass;
1321 r.in.user_handle = &user_handle;
1322 r.in.lm_present = 1;
1323 r.in.old_lm_crypted = &hash1;
1324 r.in.new_lm_crypted = &hash2;
1325 r.in.nt_present = 1;
1326 r.in.old_nt_crypted = &hash3;
1327 r.in.new_nt_crypted = &hash4;
1328 r.in.cross1_present = 1;
1329 r.in.nt_cross = &hash5;
1330 r.in.cross2_present = 1;
1331 r.in.lm_cross = &hash6;
1334 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1335 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1336 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1337 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1338 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1344 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1352 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1353 const char *acct_name,
1354 struct policy_handle *handle, char **password)
1357 struct samr_OemChangePasswordUser2 r;
1359 struct samr_Password lm_verifier;
1360 struct samr_CryptPassword lm_pass;
1361 struct lsa_AsciiString server, account, account_bad;
1364 uint8_t old_lm_hash[16], new_lm_hash[16];
1366 struct samr_GetDomPwInfo dom_pw_info;
1367 int policy_min_pw_len = 0;
1369 struct lsa_String domain_name;
1371 domain_name.string = "";
1372 dom_pw_info.in.domain_name = &domain_name;
1374 printf("Testing OemChangePasswordUser2\n");
1377 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1381 oldpass = *password;
1383 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1384 if (NT_STATUS_IS_OK(status)) {
1385 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1388 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1390 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1391 account.string = acct_name;
1393 E_deshash(oldpass, old_lm_hash);
1394 E_deshash(newpass, new_lm_hash);
1396 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1397 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1398 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1400 r.in.server = &server;
1401 r.in.account = &account;
1402 r.in.password = &lm_pass;
1403 r.in.hash = &lm_verifier;
1405 /* Break the verification */
1406 lm_verifier.hash[0]++;
1408 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1410 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1411 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1412 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1417 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1418 /* Break the old password */
1420 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1421 /* unbreak it for the next operation */
1423 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1425 r.in.server = &server;
1426 r.in.account = &account;
1427 r.in.password = &lm_pass;
1428 r.in.hash = &lm_verifier;
1430 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1432 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1433 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1434 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1439 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1440 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1442 r.in.server = &server;
1443 r.in.account = &account;
1444 r.in.password = &lm_pass;
1447 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1449 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1450 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1451 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1456 /* This shouldn't be a valid name */
1457 account_bad.string = TEST_ACCOUNT_NAME "XX";
1458 r.in.account = &account_bad;
1460 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1462 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1463 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1468 /* This shouldn't be a valid name */
1469 account_bad.string = TEST_ACCOUNT_NAME "XX";
1470 r.in.account = &account_bad;
1471 r.in.password = &lm_pass;
1472 r.in.hash = &lm_verifier;
1474 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1476 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1477 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1482 /* This shouldn't be a valid name */
1483 account_bad.string = TEST_ACCOUNT_NAME "XX";
1484 r.in.account = &account_bad;
1485 r.in.password = NULL;
1486 r.in.hash = &lm_verifier;
1488 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1490 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1491 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1496 E_deshash(oldpass, old_lm_hash);
1497 E_deshash(newpass, new_lm_hash);
1499 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1500 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1501 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1503 r.in.server = &server;
1504 r.in.account = &account;
1505 r.in.password = &lm_pass;
1506 r.in.hash = &lm_verifier;
1508 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1509 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1510 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1511 } else if (!NT_STATUS_IS_OK(status)) {
1512 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1515 *password = newpass;
1522 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1523 const char *acct_name,
1525 char *newpass, bool allow_password_restriction)
1528 struct samr_ChangePasswordUser2 r;
1530 struct lsa_String server, account;
1531 struct samr_CryptPassword nt_pass, lm_pass;
1532 struct samr_Password nt_verifier, lm_verifier;
1534 uint8_t old_nt_hash[16], new_nt_hash[16];
1535 uint8_t old_lm_hash[16], new_lm_hash[16];
1537 struct samr_GetDomPwInfo dom_pw_info;
1539 struct lsa_String domain_name;
1541 domain_name.string = "";
1542 dom_pw_info.in.domain_name = &domain_name;
1544 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1547 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1550 oldpass = *password;
1553 int policy_min_pw_len = 0;
1554 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1555 if (NT_STATUS_IS_OK(status)) {
1556 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1559 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1562 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1563 init_lsa_String(&account, acct_name);
1565 E_md4hash(oldpass, old_nt_hash);
1566 E_md4hash(newpass, new_nt_hash);
1568 E_deshash(oldpass, old_lm_hash);
1569 E_deshash(newpass, new_lm_hash);
1571 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1572 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1573 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1575 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1576 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1577 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1579 r.in.server = &server;
1580 r.in.account = &account;
1581 r.in.nt_password = &nt_pass;
1582 r.in.nt_verifier = &nt_verifier;
1584 r.in.lm_password = &lm_pass;
1585 r.in.lm_verifier = &lm_verifier;
1587 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1588 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1589 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1590 } else if (!NT_STATUS_IS_OK(status)) {
1591 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1594 *password = newpass;
1601 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1602 const char *account_string,
1603 int policy_min_pw_len,
1605 const char *newpass,
1606 NTTIME last_password_change,
1607 BOOL handle_reject_reason)
1610 struct samr_ChangePasswordUser3 r;
1612 struct lsa_String server, account, account_bad;
1613 struct samr_CryptPassword nt_pass, lm_pass;
1614 struct samr_Password nt_verifier, lm_verifier;
1616 uint8_t old_nt_hash[16], new_nt_hash[16];
1617 uint8_t old_lm_hash[16], new_lm_hash[16];
1620 printf("Testing ChangePasswordUser3\n");
1622 if (newpass == NULL) {
1624 if (policy_min_pw_len == 0) {
1625 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1627 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1629 } while (check_password_quality(newpass) == False);
1631 printf("Using password '%s'\n", newpass);
1635 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1639 oldpass = *password;
1640 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1641 init_lsa_String(&account, account_string);
1643 E_md4hash(oldpass, old_nt_hash);
1644 E_md4hash(newpass, new_nt_hash);
1646 E_deshash(oldpass, old_lm_hash);
1647 E_deshash(newpass, new_lm_hash);
1649 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1650 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1651 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1653 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1654 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1655 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1657 /* Break the verification */
1658 nt_verifier.hash[0]++;
1660 r.in.server = &server;
1661 r.in.account = &account;
1662 r.in.nt_password = &nt_pass;
1663 r.in.nt_verifier = &nt_verifier;
1665 r.in.lm_password = &lm_pass;
1666 r.in.lm_verifier = &lm_verifier;
1667 r.in.password3 = NULL;
1669 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1670 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1671 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1672 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1677 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1678 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1679 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1681 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1682 /* Break the NT hash */
1684 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1685 /* Unbreak it again */
1687 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1689 r.in.server = &server;
1690 r.in.account = &account;
1691 r.in.nt_password = &nt_pass;
1692 r.in.nt_verifier = &nt_verifier;
1694 r.in.lm_password = &lm_pass;
1695 r.in.lm_verifier = &lm_verifier;
1696 r.in.password3 = NULL;
1698 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1699 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1700 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1701 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1706 /* This shouldn't be a valid name */
1707 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1709 r.in.account = &account_bad;
1710 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1711 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1712 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1717 E_md4hash(oldpass, old_nt_hash);
1718 E_md4hash(newpass, new_nt_hash);
1720 E_deshash(oldpass, old_lm_hash);
1721 E_deshash(newpass, new_lm_hash);
1723 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1724 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1725 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1727 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1728 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1729 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1731 r.in.server = &server;
1732 r.in.account = &account;
1733 r.in.nt_password = &nt_pass;
1734 r.in.nt_verifier = &nt_verifier;
1736 r.in.lm_password = &lm_pass;
1737 r.in.lm_verifier = &lm_verifier;
1738 r.in.password3 = NULL;
1740 unix_to_nt_time(&t, time(NULL));
1742 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1744 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1747 && handle_reject_reason
1748 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1749 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1751 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1752 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1753 SAMR_REJECT_OTHER, r.out.reject->reason);
1758 /* We tested the order of precendence which is as follows:
1767 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1768 (last_password_change + r.out.dominfo->min_password_age > t)) {
1770 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1771 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1772 SAMR_REJECT_OTHER, r.out.reject->reason);
1776 } else if ((r.out.dominfo->min_password_length > 0) &&
1777 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1779 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1780 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1781 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1785 } else if ((r.out.dominfo->password_history_length > 0) &&
1786 strequal(oldpass, newpass)) {
1788 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1789 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1790 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1793 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1795 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1796 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1797 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1803 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1804 /* retry with adjusted size */
1805 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1806 r.out.dominfo->min_password_length,
1807 password, NULL, 0, False);
1811 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1812 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1813 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1814 SAMR_REJECT_OTHER, r.out.reject->reason);
1817 /* Perhaps the server has a 'min password age' set? */
1819 } else if (!NT_STATUS_IS_OK(status)) {
1820 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1823 *password = talloc_strdup(mem_ctx, newpass);
1830 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1831 struct policy_handle *alias_handle)
1833 struct samr_GetMembersInAlias r;
1834 struct lsa_SidArray sids;
1838 printf("Testing GetMembersInAlias\n");
1840 r.in.alias_handle = alias_handle;
1843 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1844 if (!NT_STATUS_IS_OK(status)) {
1845 printf("GetMembersInAlias failed - %s\n",
1853 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1854 struct policy_handle *alias_handle,
1855 const struct dom_sid *domain_sid)
1857 struct samr_AddAliasMember r;
1858 struct samr_DeleteAliasMember d;
1861 struct dom_sid *sid;
1863 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1865 printf("testing AddAliasMember\n");
1866 r.in.alias_handle = alias_handle;
1869 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1870 if (!NT_STATUS_IS_OK(status)) {
1871 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1875 d.in.alias_handle = alias_handle;
1878 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1887 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1888 struct policy_handle *alias_handle)
1890 struct samr_AddMultipleMembersToAlias a;
1891 struct samr_RemoveMultipleMembersFromAlias r;
1894 struct lsa_SidArray sids;
1896 printf("testing AddMultipleMembersToAlias\n");
1897 a.in.alias_handle = alias_handle;
1901 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1903 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1904 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1905 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1907 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1908 if (!NT_STATUS_IS_OK(status)) {
1909 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1914 printf("testing RemoveMultipleMembersFromAlias\n");
1915 r.in.alias_handle = alias_handle;
1918 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1919 if (!NT_STATUS_IS_OK(status)) {
1920 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1924 /* strange! removing twice doesn't give any error */
1925 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1926 if (!NT_STATUS_IS_OK(status)) {
1927 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1931 /* but removing an alias that isn't there does */
1932 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1934 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1935 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1936 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1943 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1944 struct policy_handle *user_handle)
1946 struct samr_TestPrivateFunctionsUser r;
1950 printf("Testing TestPrivateFunctionsUser\n");
1952 r.in.user_handle = user_handle;
1954 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1955 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1956 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1964 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1965 struct policy_handle *user_handle,
1966 struct policy_handle *domain_handle,
1967 uint32_t base_acct_flags,
1968 const char *base_acct_name, enum torture_samr_choice which_ops)
1970 TALLOC_CTX *user_ctx;
1971 char *password = NULL;
1975 const uint32_t password_fields[] = {
1976 SAMR_FIELD_PASSWORD,
1977 SAMR_FIELD_PASSWORD2,
1978 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1982 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1983 switch (which_ops) {
1984 case TORTURE_SAMR_USER_ATTRIBUTES:
1985 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1989 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1993 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1997 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
2002 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
2006 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
2010 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
2014 case TORTURE_SAMR_PASSWORDS:
2015 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2016 char simple_pass[9];
2017 char *v = generate_random_str(mem_ctx, 1);
2019 ZERO_STRUCT(simple_pass);
2020 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2022 printf("Testing machine account password policy rules\n");
2024 /* Workstation trust accounts don't seem to need to honour password quality policy */
2025 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2029 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, simple_pass, False)) {
2033 /* reset again, to allow another 'user' password change */
2034 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2038 /* Try a 'short' password */
2039 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, samr_rand_pass(mem_ctx, 4), False)) {
2045 for (i = 0; password_fields[i]; i++) {
2046 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
2050 /* check it was set right */
2051 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2056 for (i = 0; password_fields[i]; i++) {
2057 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
2061 /* check it was set right */
2062 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2067 if (!test_SetUserPassEx(p, user_ctx, user_handle, false, &password)) {
2071 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
2076 case TORTURE_SAMR_OTHER:
2077 /* We just need the account to exist */
2080 talloc_free(user_ctx);
2084 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2085 struct policy_handle *alias_handle,
2086 const struct dom_sid *domain_sid)
2090 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
2094 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
2098 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
2102 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
2106 if (lp_parm_bool(-1, "torture", "samba4", False)) {
2107 printf("skipping MultipleMembers Alias tests against Samba4\n");
2111 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
2119 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2120 struct policy_handle *user_handle)
2122 struct samr_DeleteUser d;
2125 printf("Testing DeleteUser\n");
2127 d.in.user_handle = user_handle;
2128 d.out.user_handle = user_handle;
2130 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2131 if (!NT_STATUS_IS_OK(status)) {
2132 printf("DeleteUser failed - %s\n", nt_errstr(status));
2139 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2140 struct policy_handle *handle, const char *name)
2143 struct samr_DeleteUser d;
2144 struct policy_handle user_handle;
2147 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2148 if (!NT_STATUS_IS_OK(status)) {
2152 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2153 if (!NT_STATUS_IS_OK(status)) {
2157 d.in.user_handle = &user_handle;
2158 d.out.user_handle = &user_handle;
2159 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2160 if (!NT_STATUS_IS_OK(status)) {
2167 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2172 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2173 struct policy_handle *handle, const char *name)
2176 struct samr_OpenGroup r;
2177 struct samr_DeleteDomainGroup d;
2178 struct policy_handle group_handle;
2181 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2182 if (!NT_STATUS_IS_OK(status)) {
2186 r.in.domain_handle = handle;
2187 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2189 r.out.group_handle = &group_handle;
2190 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2191 if (!NT_STATUS_IS_OK(status)) {
2195 d.in.group_handle = &group_handle;
2196 d.out.group_handle = &group_handle;
2197 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2198 if (!NT_STATUS_IS_OK(status)) {
2205 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2210 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2211 struct policy_handle *domain_handle, const char *name)
2214 struct samr_OpenAlias r;
2215 struct samr_DeleteDomAlias d;
2216 struct policy_handle alias_handle;
2219 printf("testing DeleteAlias_byname\n");
2221 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2222 if (!NT_STATUS_IS_OK(status)) {
2226 r.in.domain_handle = domain_handle;
2227 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2229 r.out.alias_handle = &alias_handle;
2230 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2231 if (!NT_STATUS_IS_OK(status)) {
2235 d.in.alias_handle = &alias_handle;
2236 d.out.alias_handle = &alias_handle;
2237 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2238 if (!NT_STATUS_IS_OK(status)) {
2245 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2249 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2250 struct policy_handle *alias_handle)
2252 struct samr_DeleteDomAlias d;
2255 printf("Testing DeleteAlias\n");
2257 d.in.alias_handle = alias_handle;
2258 d.out.alias_handle = alias_handle;
2260 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2261 if (!NT_STATUS_IS_OK(status)) {
2262 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2269 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2270 struct policy_handle *domain_handle,
2271 struct policy_handle *alias_handle,
2272 const struct dom_sid *domain_sid)
2275 struct samr_CreateDomAlias r;
2276 struct lsa_String name;
2280 init_lsa_String(&name, TEST_ALIASNAME);
2281 r.in.domain_handle = domain_handle;
2282 r.in.alias_name = &name;
2283 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2284 r.out.alias_handle = alias_handle;
2287 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2289 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2291 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2292 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2296 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2297 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2300 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2303 if (!NT_STATUS_IS_OK(status)) {
2304 printf("CreateAlias failed - %s\n", nt_errstr(status));
2308 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2315 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2316 const char *acct_name,
2317 struct policy_handle *domain_handle, char **password)
2325 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2329 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, True)) {
2333 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2337 /* test what happens when setting the old password again */
2338 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2343 char simple_pass[9];
2344 char *v = generate_random_str(mem_ctx, 1);
2346 ZERO_STRUCT(simple_pass);
2347 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2349 /* test what happens when picking a simple password */
2350 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2355 /* set samr_SetDomainInfo level 1 with min_length 5 */
2357 struct samr_QueryDomainInfo r;
2358 struct samr_SetDomainInfo s;
2359 uint16_t len_old, len;
2360 uint32_t pwd_prop_old;
2361 int64_t min_pwd_age_old;
2366 r.in.domain_handle = domain_handle;
2369 printf("testing samr_QueryDomainInfo level 1\n");
2370 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2371 if (!NT_STATUS_IS_OK(status)) {
2375 s.in.domain_handle = domain_handle;
2377 s.in.info = r.out.info;
2379 /* remember the old min length, so we can reset it */
2380 len_old = s.in.info->info1.min_password_length;
2381 s.in.info->info1.min_password_length = len;
2382 pwd_prop_old = s.in.info->info1.password_properties;
2383 /* turn off password complexity checks for this test */
2384 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2386 min_pwd_age_old = s.in.info->info1.min_password_age;
2387 s.in.info->info1.min_password_age = 0;
2389 printf("testing samr_SetDomainInfo level 1\n");
2390 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2391 if (!NT_STATUS_IS_OK(status)) {
2395 printf("calling test_ChangePasswordUser3 with too short password\n");
2397 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2401 s.in.info->info1.min_password_length = len_old;
2402 s.in.info->info1.password_properties = pwd_prop_old;
2403 s.in.info->info1.min_password_age = min_pwd_age_old;
2405 printf("testing samr_SetDomainInfo level 1\n");
2406 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2407 if (!NT_STATUS_IS_OK(status)) {
2415 struct samr_OpenUser r;
2416 struct samr_QueryUserInfo q;
2417 struct samr_LookupNames n;
2418 struct policy_handle user_handle;
2420 n.in.domain_handle = domain_handle;
2422 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2423 n.in.names[0].string = acct_name;
2425 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2426 if (!NT_STATUS_IS_OK(status)) {
2427 printf("LookupNames failed - %s\n", nt_errstr(status));
2431 r.in.domain_handle = domain_handle;
2432 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2433 r.in.rid = n.out.rids.ids[0];
2434 r.out.user_handle = &user_handle;
2436 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2437 if (!NT_STATUS_IS_OK(status)) {
2438 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2442 q.in.user_handle = &user_handle;
2445 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2446 if (!NT_STATUS_IS_OK(status)) {
2447 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2451 printf("calling test_ChangePasswordUser3 with too early password change\n");
2453 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2454 q.out.info->info5.last_password_change, True)) {
2459 /* we change passwords twice - this has the effect of verifying
2460 they were changed correctly for the final call */
2461 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2465 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2472 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2473 struct policy_handle *domain_handle,
2474 struct policy_handle *user_handle_out,
2475 enum torture_samr_choice which_ops)
2478 TALLOC_CTX *user_ctx;
2481 struct samr_CreateUser r;
2482 struct samr_QueryUserInfo q;
2483 struct samr_DeleteUser d;
2486 /* This call creates a 'normal' account - check that it really does */
2487 const uint32_t acct_flags = ACB_NORMAL;
2488 struct lsa_String name;
2491 struct policy_handle user_handle;
2492 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2493 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2495 r.in.domain_handle = domain_handle;
2496 r.in.account_name = &name;
2497 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2498 r.out.user_handle = &user_handle;
2501 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2503 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2505 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2506 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2507 talloc_free(user_ctx);
2511 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2512 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2513 talloc_free(user_ctx);
2516 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2518 if (!NT_STATUS_IS_OK(status)) {
2519 talloc_free(user_ctx);
2520 printf("CreateUser failed - %s\n", nt_errstr(status));
2523 q.in.user_handle = &user_handle;
2526 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2527 if (!NT_STATUS_IS_OK(status)) {
2528 printf("QueryUserInfo level %u failed - %s\n",
2529 q.in.level, nt_errstr(status));
2532 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2533 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2534 q.out.info->info16.acct_flags,
2540 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2541 acct_flags, name.string, which_ops)) {
2545 if (user_handle_out) {
2546 *user_handle_out = user_handle;
2548 printf("Testing DeleteUser (createuser test)\n");
2550 d.in.user_handle = &user_handle;
2551 d.out.user_handle = &user_handle;
2553 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2554 if (!NT_STATUS_IS_OK(status)) {
2555 printf("DeleteUser failed - %s\n", nt_errstr(status));
2562 talloc_free(user_ctx);
2568 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2569 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2572 struct samr_CreateUser2 r;
2573 struct samr_QueryUserInfo q;
2574 struct samr_DeleteUser d;
2575 struct policy_handle user_handle;
2577 struct lsa_String name;
2582 uint32_t acct_flags;
2583 const char *account_name;
2585 } account_types[] = {
2586 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2587 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2588 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2589 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2590 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2591 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2592 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2593 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2594 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2595 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2596 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2597 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2598 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2599 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2600 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2603 for (i = 0; account_types[i].account_name; i++) {
2604 TALLOC_CTX *user_ctx;
2605 uint32_t acct_flags = account_types[i].acct_flags;
2606 uint32_t access_granted;
2607 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2608 init_lsa_String(&name, account_types[i].account_name);
2610 r.in.domain_handle = domain_handle;
2611 r.in.account_name = &name;
2612 r.in.acct_flags = acct_flags;
2613 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2614 r.out.user_handle = &user_handle;
2615 r.out.access_granted = &access_granted;
2618 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2620 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2622 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2623 talloc_free(user_ctx);
2624 printf("Server refused create of '%s'\n", r.in.account_name->string);
2627 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2628 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2629 talloc_free(user_ctx);
2633 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2636 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2637 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2638 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2642 if (NT_STATUS_IS_OK(status)) {
2643 q.in.user_handle = &user_handle;
2646 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2647 if (!NT_STATUS_IS_OK(status)) {
2648 printf("QueryUserInfo level %u failed - %s\n",
2649 q.in.level, nt_errstr(status));
2652 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2653 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2654 q.out.info->info5.acct_flags,
2658 switch (acct_flags) {
2660 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2661 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2662 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2667 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2668 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2669 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2674 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2675 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2676 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2683 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2684 acct_flags, name.string, which_ops)) {
2688 printf("Testing DeleteUser (createuser2 test)\n");
2690 d.in.user_handle = &user_handle;
2691 d.out.user_handle = &user_handle;
2693 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2694 if (!NT_STATUS_IS_OK(status)) {
2695 printf("DeleteUser failed - %s\n", nt_errstr(status));
2699 talloc_free(user_ctx);
2705 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2706 struct policy_handle *handle)
2709 struct samr_QueryAliasInfo r;
2710 uint16_t levels[] = {1, 2, 3};
2714 for (i=0;i<ARRAY_SIZE(levels);i++) {
2715 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2717 r.in.alias_handle = handle;
2718 r.in.level = levels[i];
2720 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2721 if (!NT_STATUS_IS_OK(status)) {
2722 printf("QueryAliasInfo level %u failed - %s\n",
2723 levels[i], nt_errstr(status));
2731 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2732 struct policy_handle *handle)
2735 struct samr_QueryGroupInfo r;
2736 uint16_t levels[] = {1, 2, 3, 4, 5};
2740 for (i=0;i<ARRAY_SIZE(levels);i++) {
2741 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2743 r.in.group_handle = handle;
2744 r.in.level = levels[i];
2746 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2747 if (!NT_STATUS_IS_OK(status)) {
2748 printf("QueryGroupInfo level %u failed - %s\n",
2749 levels[i], nt_errstr(status));
2757 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2758 struct policy_handle *handle)
2761 struct samr_QueryGroupMember r;
2764 printf("Testing QueryGroupMember\n");
2766 r.in.group_handle = handle;
2768 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2769 if (!NT_STATUS_IS_OK(status)) {
2770 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2778 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2779 struct policy_handle *handle)
2782 struct samr_QueryGroupInfo r;
2783 struct samr_SetGroupInfo s;
2784 uint16_t levels[] = {1, 2, 3, 4};
2785 uint16_t set_ok[] = {0, 1, 1, 1};
2789 for (i=0;i<ARRAY_SIZE(levels);i++) {
2790 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2792 r.in.group_handle = handle;
2793 r.in.level = levels[i];
2795 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2796 if (!NT_STATUS_IS_OK(status)) {
2797 printf("QueryGroupInfo level %u failed - %s\n",
2798 levels[i], nt_errstr(status));
2802 printf("Testing SetGroupInfo level %u\n", levels[i]);
2804 s.in.group_handle = handle;
2805 s.in.level = levels[i];
2806 s.in.info = r.out.info;
2809 /* disabled this, as it changes the name only from the point of view of samr,
2810 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2811 the name is still reserved, so creating the old name fails, but deleting by the old name
2813 if (s.in.level == 2) {
2814 init_lsa_String(&s.in.info->string, "NewName");
2818 if (s.in.level == 4) {
2819 init_lsa_String(&s.in.info->description, "test description");
2822 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2824 if (!NT_STATUS_IS_OK(status)) {
2825 printf("SetGroupInfo level %u failed - %s\n",
2826 r.in.level, nt_errstr(status));
2831 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2832 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2833 r.in.level, nt_errstr(status));
2843 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2844 struct policy_handle *handle)
2847 struct samr_QueryUserInfo r;
2848 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2849 11, 12, 13, 14, 16, 17, 20, 21};
2853 for (i=0;i<ARRAY_SIZE(levels);i++) {
2854 printf("Testing QueryUserInfo level %u\n", levels[i]);
2856 r.in.user_handle = handle;
2857 r.in.level = levels[i];
2859 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2860 if (!NT_STATUS_IS_OK(status)) {
2861 printf("QueryUserInfo level %u failed - %s\n",
2862 levels[i], nt_errstr(status));
2870 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2871 struct policy_handle *handle)
2874 struct samr_QueryUserInfo2 r;
2875 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2876 11, 12, 13, 14, 16, 17, 20, 21};
2880 for (i=0;i<ARRAY_SIZE(levels);i++) {
2881 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2883 r.in.user_handle = handle;
2884 r.in.level = levels[i];
2886 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2887 if (!NT_STATUS_IS_OK(status)) {
2888 printf("QueryUserInfo2 level %u failed - %s\n",
2889 levels[i], nt_errstr(status));
2897 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2898 struct policy_handle *handle, uint32_t rid)
2901 struct samr_OpenUser r;
2902 struct policy_handle user_handle;
2905 printf("Testing OpenUser(%u)\n", rid);
2907 r.in.domain_handle = handle;
2908 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2910 r.out.user_handle = &user_handle;
2912 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2913 if (!NT_STATUS_IS_OK(status)) {
2914 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2918 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2922 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2926 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2930 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2934 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2938 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2945 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2946 struct policy_handle *handle, uint32_t rid)
2949 struct samr_OpenGroup r;
2950 struct policy_handle group_handle;
2953 printf("Testing OpenGroup(%u)\n", rid);
2955 r.in.domain_handle = handle;
2956 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2958 r.out.group_handle = &group_handle;
2960 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2961 if (!NT_STATUS_IS_OK(status)) {
2962 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2966 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2970 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2974 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2978 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2985 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2986 struct policy_handle *handle, uint32_t rid)
2989 struct samr_OpenAlias r;
2990 struct policy_handle alias_handle;
2993 printf("Testing OpenAlias(%u)\n", rid);
2995 r.in.domain_handle = handle;
2996 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2998 r.out.alias_handle = &alias_handle;
3000 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3001 if (!NT_STATUS_IS_OK(status)) {
3002 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3006 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3010 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3014 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3018 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3025 static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3026 struct policy_handle *handle, uint32_t rid,
3027 uint32_t acct_flag_mask)
3030 struct samr_OpenUser r;
3031 struct samr_QueryUserInfo q;
3032 struct policy_handle user_handle;
3035 printf("Testing OpenUser(%u)\n", rid);
3037 r.in.domain_handle = handle;
3038 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3040 r.out.user_handle = &user_handle;
3042 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3043 if (!NT_STATUS_IS_OK(status)) {
3044 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3048 q.in.user_handle = &user_handle;
3051 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 printf("QueryUserInfo level 16 failed - %s\n",
3057 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3058 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3059 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3064 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3071 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3072 struct policy_handle *handle)
3074 NTSTATUS status = STATUS_MORE_ENTRIES;
3075 struct samr_EnumDomainUsers r;
3076 uint32_t mask, resume_handle=0;
3079 struct samr_LookupNames n;
3080 struct samr_LookupRids lr ;
3081 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3082 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3083 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3086 printf("Testing EnumDomainUsers\n");
3088 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3089 r.in.domain_handle = handle;
3090 r.in.resume_handle = &resume_handle;
3091 r.in.acct_flags = mask = masks[mask_idx];
3092 r.in.max_size = (uint32_t)-1;
3093 r.out.resume_handle = &resume_handle;
3095 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3096 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3097 !NT_STATUS_IS_OK(status)) {
3098 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3103 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3107 if (r.out.sam->count == 0) {
3111 for (i=0;i<r.out.sam->count;i++) {
3113 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3116 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3122 printf("Testing LookupNames\n");
3123 n.in.domain_handle = handle;
3124 n.in.num_names = r.out.sam->count;
3125 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3126 for (i=0;i<r.out.sam->count;i++) {
3127 n.in.names[i].string = r.out.sam->entries[i].name.string;
3129 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3130 if (!NT_STATUS_IS_OK(status)) {
3131 printf("LookupNames failed - %s\n", nt_errstr(status));
3136 printf("Testing LookupRids\n");
3137 lr.in.domain_handle = handle;
3138 lr.in.num_rids = r.out.sam->count;
3139 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3140 for (i=0;i<r.out.sam->count;i++) {
3141 lr.in.rids[i] = r.out.sam->entries[i].idx;
3143 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3144 if (!NT_STATUS_IS_OK(status)) {
3145 printf("LookupRids failed - %s\n", nt_errstr(status));
3153 try blasting the server with a bunch of sync requests
3155 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3156 struct policy_handle *handle)
3159 struct samr_EnumDomainUsers r;
3160 uint32_t resume_handle=0;
3162 #define ASYNC_COUNT 100
3163 struct rpc_request *req[ASYNC_COUNT];
3165 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
3166 printf("samr async test disabled - enable dangerous tests to use\n");
3170 printf("Testing EnumDomainUsers_async\n");
3172 r.in.domain_handle = handle;
3173 r.in.resume_handle = &resume_handle;
3174 r.in.acct_flags = 0;
3175 r.in.max_size = (uint32_t)-1;
3176 r.out.resume_handle = &resume_handle;
3178 for (i=0;i<ASYNC_COUNT;i++) {
3179 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
3182 for (i=0;i<ASYNC_COUNT;i++) {
3183 status = dcerpc_ndr_request_recv(req[i]);
3184 if (!NT_STATUS_IS_OK(status)) {
3185 printf("EnumDomainUsers[%d] failed - %s\n",
3186 i, nt_errstr(status));
3191 printf("%d async requests OK\n", i);
3196 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3197 struct policy_handle *handle)
3200 struct samr_EnumDomainGroups r;
3201 uint32_t resume_handle=0;
3205 printf("Testing EnumDomainGroups\n");
3207 r.in.domain_handle = handle;
3208 r.in.resume_handle = &resume_handle;
3209 r.in.max_size = (uint32_t)-1;
3210 r.out.resume_handle = &resume_handle;
3212 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3222 for (i=0;i<r.out.sam->count;i++) {
3223 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3231 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3232 struct policy_handle *handle)
3235 struct samr_EnumDomainAliases r;
3236 uint32_t resume_handle=0;
3240 printf("Testing EnumDomainAliases\n");
3242 r.in.domain_handle = handle;
3243 r.in.resume_handle = &resume_handle;
3244 r.in.acct_flags = (uint32_t)-1;
3245 r.out.resume_handle = &resume_handle;
3247 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3248 if (!NT_STATUS_IS_OK(status)) {
3249 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3257 for (i=0;i<r.out.sam->count;i++) {
3258 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3266 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3267 struct policy_handle *handle)
3270 struct samr_GetDisplayEnumerationIndex r;
3272 uint16_t levels[] = {1, 2, 3, 4, 5};
3273 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3276 for (i=0;i<ARRAY_SIZE(levels);i++) {
3277 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3279 r.in.domain_handle = handle;
3280 r.in.level = levels[i];
3281 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3283 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3286 !NT_STATUS_IS_OK(status) &&
3287 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3288 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3289 levels[i], nt_errstr(status));
3293 init_lsa_String(&r.in.name, "zzzzzzzz");
3295 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3297 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3298 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3299 levels[i], nt_errstr(status));
3307 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3308 struct policy_handle *handle)
3311 struct samr_GetDisplayEnumerationIndex2 r;
3313 uint16_t levels[] = {1, 2, 3, 4, 5};
3314 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3317 for (i=0;i<ARRAY_SIZE(levels);i++) {
3318 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3320 r.in.domain_handle = handle;
3321 r.in.level = levels[i];
3322 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3324 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3326 !NT_STATUS_IS_OK(status) &&
3327 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3328 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3329 levels[i], nt_errstr(status));
3333 init_lsa_String(&r.in.name, "zzzzzzzz");
3335 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3336 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3337 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3338 levels[i], nt_errstr(status));
3346 #define STRING_EQUAL_QUERY(s1, s2, user) \
3347 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3348 /* odd, but valid */ \
3349 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3350 printf("%s mismatch for %s: %s != %s (%s)\n", \
3351 #s1, user.string, s1.string, s2.string, __location__); \
3354 #define INT_EQUAL_QUERY(s1, s2, user) \
3356 printf("%s mismatch for %s: 0x%x != 0x%x (%s)\n", \
3357 #s1, user.string, (unsigned int)s1, (unsigned int)s2, __location__); \
3361 static BOOL test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3362 struct samr_QueryDisplayInfo *querydisplayinfo,
3363 bool *seen_testuser)
3365 struct samr_OpenUser r;
3366 struct samr_QueryUserInfo q;
3367 struct policy_handle user_handle;
3370 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3371 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3372 for (i = 0; ; i++) {
3373 switch (querydisplayinfo->in.level) {
3375 if (i >= querydisplayinfo->out.info.info1.count) {
3378 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3381 if (i >= querydisplayinfo->out.info.info2.count) {
3384 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3390 /* Not interested in validating just the account name */
3394 r.out.user_handle = &user_handle;
3396 switch (querydisplayinfo->in.level) {
3399 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3400 if (!NT_STATUS_IS_OK(status)) {
3401 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3406 q.in.user_handle = &user_handle;
3408 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3409 if (!NT_STATUS_IS_OK(status)) {
3410 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3414 switch (querydisplayinfo->in.level) {
3416 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3417 *seen_testuser = true;
3419 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3420 q.out.info->info21.full_name, q.out.info->info21.account_name);
3421 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3422 q.out.info->info21.account_name, q.out.info->info21.account_name);
3423 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3424 q.out.info->info21.description, q.out.info->info21.account_name);
3425 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3426 q.out.info->info21.rid, q.out.info->info21.account_name);
3427 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3428 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3432 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3433 q.out.info->info21.account_name, q.out.info->info21.account_name);
3434 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3435 q.out.info->info21.description, q.out.info->info21.account_name);
3436 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3437 q.out.info->info21.rid, q.out.info->info21.account_name);
3438 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3439 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3441 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3442 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3443 q.out.info->info21.account_name.string);
3446 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3447 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3448 q.out.info->info21.account_name.string,
3449 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3450 q.out.info->info21.acct_flags);
3457 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3464 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3465 struct policy_handle *handle)
3468 struct samr_QueryDisplayInfo r;
3469 struct samr_QueryDomainInfo dom_info;
3471 uint16_t levels[] = {1, 2, 3, 4, 5};
3473 bool seen_testuser = false;
3475 for (i=0;i<ARRAY_SIZE(levels);i++) {
3476 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3479 status = STATUS_MORE_ENTRIES;
3480 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3481 r.in.domain_handle = handle;
3482 r.in.level = levels[i];
3483 r.in.max_entries = 2;
3484 r.in.buf_size = (uint32_t)-1;
3486 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3487 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3488 printf("QueryDisplayInfo level %u failed - %s\n",
3489 levels[i], nt_errstr(status));
3492 switch (r.in.level) {
3494 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3497 r.in.start_idx += r.out.info.info1.count;
3500 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3503 r.in.start_idx += r.out.info.info2.count;
3506 r.in.start_idx += r.out.info.info3.count;
3509 r.in.start_idx += r.out.info.info4.count;
3512 r.in.start_idx += r.out.info.info5.count;
3516 dom_info.in.domain_handle = handle;
3517 dom_info.in.level = 2;
3518 /* Check number of users returned is correct */
3519 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3520 if (!NT_STATUS_IS_OK(status)) {
3521 printf("QueryDomainInfo level %u failed - %s\n",
3522 r.in.level, nt_errstr(status));
3526 switch (r.in.level) {
3529 if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3530 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3531 r.in.start_idx, dom_info.out.info->info2.num_groups,
3532 dom_info.out.info->info2.domain_name.string);
3535 if (!seen_testuser) {
3536 struct policy_handle user_handle;
3537 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3538 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3539 dom_info.out.info->info2.domain_name.string);
3541 test_samr_handle_Close(p, mem_ctx, &user_handle);
3547 if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3548 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3549 r.in.start_idx, dom_info.out.info->info2.num_groups,
3550 dom_info.out.info->info2.domain_name.string);
3562 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3563 struct policy_handle *handle)
3566 struct samr_QueryDisplayInfo2 r;
3568 uint16_t levels[] = {1, 2, 3, 4, 5};
3571 for (i=0;i<ARRAY_SIZE(levels);i++) {
3572 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3574 r.in.domain_handle = handle;
3575 r.in.level = levels[i];
3577 r.in.max_entries = 1000;
3578 r.in.buf_size = (uint32_t)-1;
3580 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3581 if (!NT_STATUS_IS_OK(status)) {
3582 printf("QueryDisplayInfo2 level %u failed - %s\n",
3583 levels[i], nt_errstr(status));
3591 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3592 struct policy_handle *handle)
3595 struct samr_QueryDisplayInfo3 r;
3597 uint16_t levels[] = {1, 2, 3, 4, 5};
3600 for (i=0;i<ARRAY_SIZE(levels);i++) {
3601 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3603 r.in.domain_handle = handle;
3604 r.in.level = levels[i];
3606 r.in.max_entries = 1000;
3607 r.in.buf_size = (uint32_t)-1;
3609 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3610 if (!NT_STATUS_IS_OK(status)) {
3611 printf("QueryDisplayInfo3 level %u failed - %s\n",
3612 levels[i], nt_errstr(status));
3621 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3622 struct policy_handle *handle)
3625 struct samr_QueryDisplayInfo r;
3628 printf("Testing QueryDisplayInfo continuation\n");
3630 r.in.domain_handle = handle;
3633 r.in.max_entries = 1;
3634 r.in.buf_size = (uint32_t)-1;
3637 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3638 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3639 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3640 printf("expected idx %d but got %d\n",
3642 r.out.info.info1.entries[0].idx);
3646 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3647 !NT_STATUS_IS_OK(status)) {
3648 printf("QueryDisplayInfo level %u failed - %s\n",
3649 r.in.level, nt_errstr(status));
3654 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3655 NT_STATUS_IS_OK(status)) &&
3656 r.out.returned_size != 0);
3661 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3662 struct policy_handle *handle)
3665 struct samr_QueryDomainInfo r;
3666 struct samr_SetDomainInfo s;
3667 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3668 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3671 const char *domain_comment = talloc_asprintf(mem_ctx,
3672 "Tortured by Samba4 RPC-SAMR: %s",
3673 timestring(mem_ctx, time(NULL)));
3675 s.in.domain_handle = handle;
3677 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3679 s.in.info->info4.comment.string = domain_comment;
3680 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3681 if (!NT_STATUS_IS_OK(status)) {
3682 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3683 r.in.level, nt_errstr(status));
3687 for (i=0;i<ARRAY_SIZE(levels);i++) {
3688 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3690 r.in.domain_handle = handle;
3691 r.in.level = levels[i];
3693 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3694 if (!NT_STATUS_IS_OK(status)) {
3695 printf("QueryDomainInfo level %u failed - %s\n",
3696 r.in.level, nt_errstr(status));
3701 switch (levels[i]) {
3703 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3704 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3705 levels[i], r.out.info->info2.comment.string, domain_comment);
3708 if (!r.out.info->info2.primary.string) {
3709 printf("QueryDomainInfo level %u returned no PDC name\n",
3712 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3713 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3714 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3715 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3720 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3721 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3722 levels[i], r.out.info->info4.comment.string, domain_comment);
3727 if (!r.out.info->info6.primary.string) {
3728 printf("QueryDomainInfo level %u returned no PDC name\n",
3734 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3735 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3736 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3742 printf("Testing SetDomainInfo level %u\n", levels[i]);
3744 s.in.domain_handle = handle;
3745 s.in.level = levels[i];
3746 s.in.info = r.out.info;
3748 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 printf("SetDomainInfo level %u failed - %s\n",
3752 r.in.level, nt_errstr(status));
3757 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3758 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3759 r.in.level, nt_errstr(status));
3765 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3766 if (!NT_STATUS_IS_OK(status)) {
3767 printf("QueryDomainInfo level %u failed - %s\n",
3768 r.in.level, nt_errstr(status));
3778 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3779 struct policy_handle *handle)
3782 struct samr_QueryDomainInfo2 r;
3783 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3787 for (i=0;i<ARRAY_SIZE(levels);i++) {
3788 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3790 r.in.domain_handle = handle;
3791 r.in.level = levels[i];
3793 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3794 if (!NT_STATUS_IS_OK(status)) {
3795 printf("QueryDomainInfo2 level %u failed - %s\n",
3796 r.in.level, nt_errstr(status));
3805 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3806 set of group names. */
3807 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3808 struct policy_handle *handle)
3810 struct samr_EnumDomainGroups q1;
3811 struct samr_QueryDisplayInfo q2;
3813 uint32_t resume_handle=0;
3818 const char **names = NULL;
3820 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3822 q1.in.domain_handle = handle;
3823 q1.in.resume_handle = &resume_handle;
3825 q1.out.resume_handle = &resume_handle;
3827 status = STATUS_MORE_ENTRIES;
3828 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3829 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3831 if (!NT_STATUS_IS_OK(status) &&
3832 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3835 for (i=0; i<q1.out.num_entries; i++) {
3836 add_string_to_array(mem_ctx,
3837 q1.out.sam->entries[i].name.string,
3838 &names, &num_names);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3851 q2.in.domain_handle = handle;
3853 q2.in.start_idx = 0;
3854 q2.in.max_entries = 5;
3855 q2.in.buf_size = (uint32_t)-1;
3857 status = STATUS_MORE_ENTRIES;
3858 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3859 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3861 if (!NT_STATUS_IS_OK(status) &&
3862 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3865 for (i=0; i<q2.out.info.info5.count; i++) {
3867 const char *name = q2.out.info.info5.entries[i].account_name.string;
3869 for (j=0; j<num_names; j++) {
3870 if (names[j] == NULL)
3872 /* Hmm. No strequal in samba4 */
3873 if (strequal(names[j], name)) {
3881 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3886 q2.in.start_idx += q2.out.info.info5.count;
3889 if (!NT_STATUS_IS_OK(status)) {
3890 printf("QueryDisplayInfo level 5 failed - %s\n",
3895 for (i=0; i<num_names; i++) {
3896 if (names[i] != NULL) {
3897 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3906 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3907 struct policy_handle *group_handle)
3909 struct samr_DeleteDomainGroup d;
3913 printf("Testing DeleteDomainGroup\n");
3915 d.in.group_handle = group_handle;
3916 d.out.group_handle = group_handle;
3918 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3919 if (!NT_STATUS_IS_OK(status)) {
3920 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3927 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3928 struct policy_handle *domain_handle)
3930 struct samr_TestPrivateFunctionsDomain r;
3934 printf("Testing TestPrivateFunctionsDomain\n");
3936 r.in.domain_handle = domain_handle;
3938 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3939 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3940 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3947 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3948 struct dom_sid *domain_sid,
3949 struct policy_handle *domain_handle)
3951 struct samr_RidToSid r;
3954 struct dom_sid *calc_sid;
3955 int rids[] = { 0, 42, 512, 10200 };
3958 for (i=0;i<ARRAY_SIZE(rids);i++) {
3960 printf("Testing RidToSid\n");
3962 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3963 r.in.domain_handle = domain_handle;
3966 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3967 if (!NT_STATUS_IS_OK(status)) {
3968 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3971 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3973 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3974 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3975 dom_sid_string(mem_ctx, r.out.sid),
3976 dom_sid_string(mem_ctx, calc_sid));
3985 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3986 struct policy_handle *domain_handle)
3988 struct samr_GetBootKeyInformation r;
3992 printf("Testing GetBootKeyInformation\n");
3994 r.in.domain_handle = domain_handle;
3996 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
3997 if (!NT_STATUS_IS_OK(status)) {
3998 /* w2k3 seems to fail this sometimes and pass it sometimes */
3999 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4005 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4006 struct policy_handle *domain_handle,
4007 struct policy_handle *group_handle)
4010 struct samr_AddGroupMember r;
4011 struct samr_DeleteGroupMember d;
4012 struct samr_QueryGroupMember q;
4013 struct samr_SetMemberAttributesOfGroup s;
4017 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4018 if (!NT_STATUS_IS_OK(status)) {
4019 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4023 r.in.group_handle = group_handle;
4025 r.in.flags = 0; /* ??? */
4027 printf("Testing AddGroupMember and DeleteGroupMember\n");
4029 d.in.group_handle = group_handle;
4032 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
4033 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4034 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4039 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4045 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4046 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4047 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4052 if (lp_parm_bool(-1, "torture", "samba4", False)) {
4053 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4055 /* this one is quite strange. I am using random inputs in the
4056 hope of triggering an error that might give us a clue */
4058 s.in.group_handle = group_handle;
4059 s.in.unknown1 = random();
4060 s.in.unknown2 = random();
4062 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
4063 if (!NT_STATUS_IS_OK(status)) {
4064 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4069 q.in.group_handle = group_handle;
4071 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
4072 if (!NT_STATUS_IS_OK(status)) {
4073 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4077 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
4078 if (!NT_STATUS_IS_OK(status)) {
4079 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4083 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
4084 if (!NT_STATUS_IS_OK(status)) {
4085 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4093 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4094 struct policy_handle *domain_handle, struct policy_handle *group_handle)
4097 struct samr_CreateDomainGroup r;
4099 struct lsa_String name;
4102 init_lsa_String(&name, TEST_GROUPNAME);
4104 r.in.domain_handle = domain_handle;
4106 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4107 r.out.group_handle = group_handle;
4110 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4112 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4114 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4115 printf("Server refused create of '%s'\n", r.in.name->string);
4116 ZERO_STRUCTP(group_handle);
4120 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4121 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4123 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4127 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4129 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4130 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4132 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4136 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4138 if (!NT_STATUS_IS_OK(status)) {
4139 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4143 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4144 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4148 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4157 its not totally clear what this does. It seems to accept any sid you like.
4159 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4160 TALLOC_CTX *mem_ctx,
4161 struct policy_handle *domain_handle)
4164 struct samr_RemoveMemberFromForeignDomain r;
4166 r.in.domain_handle = domain_handle;
4167 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4169 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4170 if (!NT_STATUS_IS_OK(status)) {
4171 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4180 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4181 struct policy_handle *handle);
4183 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4184 struct policy_handle *handle, struct dom_sid *sid,
4185 enum torture_samr_choice which_ops)
4188 struct samr_OpenDomain r;
4189 struct policy_handle domain_handle;
4190 struct policy_handle alias_handle;
4191 struct policy_handle user_handle;
4192 struct policy_handle group_handle;
4195 ZERO_STRUCT(alias_handle);
4196 ZERO_STRUCT(user_handle);
4197 ZERO_STRUCT(group_handle);
4198 ZERO_STRUCT(domain_handle);
4200 printf("Testing OpenDomain\n");
4202 r.in.connect_handle = handle;
4203 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4205 r.out.domain_handle = &domain_handle;
4207 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
4208 if (!NT_STATUS_IS_OK(status)) {
4209 printf("OpenDomain failed - %s\n", nt_errstr(status));
4213 /* run the domain tests with the main handle closed - this tests
4214 the servers reference counting */
4215 ret &= test_samr_handle_Close(p, mem_ctx, handle);
4217 switch (which_ops) {
4218 case TORTURE_SAMR_USER_ATTRIBUTES:
4219 case TORTURE_SAMR_PASSWORDS:
4220 ret &= test_CreateUser2(p, mem_ctx, &domain_handle, which_ops);
4221 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4222 /* This test needs 'complex' users to validate */
4223 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
4225 case TORTURE_SAMR_OTHER:
4226 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle, which_ops);
4227 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
4228 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
4229 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
4230 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
4231 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
4232 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
4233 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
4234 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
4235 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
4236 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
4237 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
4238 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
4239 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
4241 if (lp_parm_bool(-1, "torture", "samba4", False)) {
4242 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4244 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
4245 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
4247 ret &= test_GroupList(p, mem_ctx, &domain_handle);
4248 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
4249 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
4250 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
4254 if (!policy_handle_empty(&user_handle) &&
4255 !test_DeleteUser(p, mem_ctx, &user_handle)) {
4259 if (!policy_handle_empty(&alias_handle) &&
4260 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
4264 if (!policy_handle_empty(&group_handle) &&
4265 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
4269 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
4271 /* reconnect the main handle */
4272 ret &= test_Connect(p, mem_ctx, handle);
4275 printf("Testing domain %s failed!\n", dom_sid_string(mem_ctx, sid));
4281 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4282 struct policy_handle *handle, const char *domain,
4283 enum torture_samr_choice which_ops)
4286 struct samr_LookupDomain r;
4287 struct lsa_String n1;
4288 struct lsa_String n2;
4291 printf("Testing LookupDomain(%s)\n", domain);
4293 /* check for correct error codes */
4294 r.in.connect_handle = handle;
4295 r.in.domain_name = &n2;
4298 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4299 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4300 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4304 init_lsa_String(&n2, "xxNODOMAINxx");
4306 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4307 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4308 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4312 r.in.connect_handle = handle;
4314 init_lsa_String(&n1, domain);
4315 r.in.domain_name = &n1;
4317 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4318 if (!NT_STATUS_IS_OK(status)) {
4319 printf("LookupDomain failed - %s\n", nt_errstr(status));
4323 if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
4327 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
4335 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4336 struct policy_handle *handle, enum torture_samr_choice which_ops)
4339 struct samr_EnumDomains r;
4340 uint32_t resume_handle = 0;
4344 r.in.connect_handle = handle;
4345 r.in.resume_handle = &resume_handle;
4346 r.in.buf_size = (uint32_t)-1;
4347 r.out.resume_handle = &resume_handle;
4349 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4350 if (!NT_STATUS_IS_OK(status)) {
4351 printf("EnumDomains failed - %s\n", nt_errstr(status));
4359 for (i=0;i<r.out.sam->count;i++) {
4360 if (!test_LookupDomain(p, mem_ctx, handle,
4361 r.out.sam->entries[i].name.string, which_ops)) {
4366 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4367 if (!NT_STATUS_IS_OK(status)) {
4368 printf("EnumDomains failed - %s\n", nt_errstr(status));
4376 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4377 struct policy_handle *handle)
4380 struct samr_Connect r;
4381 struct samr_Connect2 r2;
4382 struct samr_Connect3 r3;
4383 struct samr_Connect4 r4;
4384 struct samr_Connect5 r5;
4385 union samr_ConnectInfo info;
4386 struct policy_handle h;
4387 BOOL ret = True, got_handle = False;
4389 printf("testing samr_Connect\n");
4391 r.in.system_name = 0;
4392 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4393 r.out.connect_handle = &h;
4395 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4396 if (!NT_STATUS_IS_OK(status)) {
4397 printf("Connect failed - %s\n", nt_errstr(status));
4404 printf("testing samr_Connect2\n");
4406 r2.in.system_name = NULL;
4407 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4408 r2.out.connect_handle = &h;
4410 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4411 if (!NT_STATUS_IS_OK(status)) {
4412 printf("Connect2 failed - %s\n", nt_errstr(status));
4416 test_samr_handle_Close(p, mem_ctx, handle);
4422 printf("testing samr_Connect3\n");
4424 r3.in.system_name = NULL;
4426 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4427 r3.out.connect_handle = &h;
4429 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4430 if (!NT_STATUS_IS_OK(status)) {
4431 printf("Connect3 failed - %s\n", nt_errstr(status));
4435 test_samr_handle_Close(p, mem_ctx, handle);
4441 printf("testing samr_Connect4\n");
4443 r4.in.system_name = "";
4445 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4446 r4.out.connect_handle = &h;
4448 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4449 if (!NT_STATUS_IS_OK(status)) {
4450 printf("Connect4 failed - %s\n", nt_errstr(status));
4454 test_samr_handle_Close(p, mem_ctx, handle);
4460 printf("testing samr_Connect5\n");
4462 info.info1.unknown1 = 0;
4463 info.info1.unknown2 = 0;
4465 r5.in.system_name = "";
4466 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4469 r5.out.info = &info;
4470 r5.out.connect_handle = &h;
4472 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4473 if (!NT_STATUS_IS_OK(status)) {
4474 printf("Connect5 failed - %s\n", nt_errstr(status));
4478 test_samr_handle_Close(p, mem_ctx, handle);
4488 BOOL torture_rpc_samr(struct torture_context *torture)
4491 struct dcerpc_pipe *p;
4493 struct policy_handle handle;
4495 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4496 if (!NT_STATUS_IS_OK(status)) {
4500 ret &= test_Connect(p, torture, &handle);
4502 ret &= test_QuerySecurity(p, torture, &handle);
4504 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4506 ret &= test_SetDsrmPassword(p, torture, &handle);
4508 ret &= test_Shutdown(p, torture, &handle);
4510 ret &= test_samr_handle_Close(p, torture, &handle);
4516 BOOL torture_rpc_samr_users(struct torture_context *torture)
4519 struct dcerpc_pipe *p;
4521 struct policy_handle handle;
4523 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4524 if (!NT_STATUS_IS_OK(status)) {
4528 ret &= test_Connect(p, torture, &handle);
4530 ret &= test_QuerySecurity(p, torture, &handle);
4532 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4534 ret &= test_SetDsrmPassword(p, torture, &handle);
4536 ret &= test_Shutdown(p, torture, &handle);
4538 ret &= test_samr_handle_Close(p, torture, &handle);
4544 BOOL torture_rpc_samr_passwords(struct torture_context *torture)
4547 struct dcerpc_pipe *p;
4549 struct policy_handle handle;
4551 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4552 if (!NT_STATUS_IS_OK(status)) {
4556 ret &= test_Connect(p, torture, &handle);
4558 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4560 ret &= test_samr_handle_Close(p, torture, &handle);