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, struct torture_context *tctx,
81 struct policy_handle *handle)
84 struct samr_Shutdown r;
86 if (!torture_setting_bool(tctx, "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, tctx, &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, struct torture_context *tctx,
105 struct policy_handle *handle)
108 struct samr_SetDsrmPassword r;
109 struct lsa_String string;
110 struct samr_Password hash;
112 if (!torture_setting_bool(tctx, "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, tctx, &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,
138 struct torture_context *tctx,
139 struct policy_handle *handle)
142 struct samr_QuerySecurity r;
143 struct samr_SetSecurity s;
145 r.in.handle = handle;
148 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
149 if (!NT_STATUS_IS_OK(status)) {
150 printf("QuerySecurity failed - %s\n", nt_errstr(status));
154 if (r.out.sdbuf == NULL) {
158 s.in.handle = handle;
160 s.in.sdbuf = r.out.sdbuf;
162 if (torture_setting_bool(tctx, "samba4", false)) {
163 printf("skipping SetSecurity test against Samba4\n");
167 status = dcerpc_samr_SetSecurity(p, tctx, &s);
168 if (!NT_STATUS_IS_OK(status)) {
169 printf("SetSecurity failed - %s\n", nt_errstr(status));
173 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
174 if (!NT_STATUS_IS_OK(status)) {
175 printf("QuerySecurity failed - %s\n", nt_errstr(status));
183 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
184 struct policy_handle *handle, uint32_t base_acct_flags,
185 const char *base_account_name)
188 struct samr_SetUserInfo s;
189 struct samr_SetUserInfo2 s2;
190 struct samr_QueryUserInfo q;
191 struct samr_QueryUserInfo q0;
192 union samr_UserInfo u;
194 const char *test_account_name;
196 uint32_t user_extra_flags = 0;
197 if (base_acct_flags == ACB_NORMAL) {
198 /* When created, accounts are expired by default */
199 user_extra_flags = ACB_PW_EXPIRED;
202 s.in.user_handle = handle;
205 s2.in.user_handle = handle;
208 q.in.user_handle = handle;
212 #define TESTCALL(call, r) \
213 status = dcerpc_samr_ ##call(p, tctx, &r); \
214 if (!NT_STATUS_IS_OK(status)) { \
215 printf(#call " level %u failed - %s (%s)\n", \
216 r.in.level, nt_errstr(status), __location__); \
221 #define STRING_EQUAL(s1, s2, field) \
222 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
223 printf("Failed to set %s to '%s' (%s)\n", \
224 #field, s2, __location__); \
229 #define INT_EQUAL(i1, i2, field) \
231 printf("Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
232 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
237 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
238 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
240 TESTCALL(QueryUserInfo, q) \
242 s2.in.level = lvl1; \
245 ZERO_STRUCT(u.info21); \
246 u.info21.fields_present = fpval; \
248 init_lsa_String(&u.info ## lvl1.field1, value); \
249 TESTCALL(SetUserInfo, s) \
250 TESTCALL(SetUserInfo2, s2) \
251 init_lsa_String(&u.info ## lvl1.field1, ""); \
252 TESTCALL(QueryUserInfo, q); \
254 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
256 TESTCALL(QueryUserInfo, q) \
258 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
261 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
262 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
264 TESTCALL(QueryUserInfo, q) \
266 s2.in.level = lvl1; \
269 uint8_t *bits = u.info21.logon_hours.bits; \
270 ZERO_STRUCT(u.info21); \
271 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
272 u.info21.logon_hours.units_per_week = 168; \
273 u.info21.logon_hours.bits = bits; \
275 u.info21.fields_present = fpval; \
277 u.info ## lvl1.field1 = value; \
278 TESTCALL(SetUserInfo, s) \
279 TESTCALL(SetUserInfo2, s2) \
280 u.info ## lvl1.field1 = 0; \
281 TESTCALL(QueryUserInfo, q); \
283 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
285 TESTCALL(QueryUserInfo, q) \
287 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
290 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
291 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
295 do { TESTCALL(QueryUserInfo, q0) } while (0);
297 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
298 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
299 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
302 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
303 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
304 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
305 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
306 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
307 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
308 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
309 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
310 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
311 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
312 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
313 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
314 test_account_name = base_account_name;
315 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
316 SAMR_FIELD_ACCOUNT_NAME);
318 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
319 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
323 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
324 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
325 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
326 SAMR_FIELD_FULL_NAME);
328 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
329 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
333 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
334 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
335 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
336 SAMR_FIELD_FULL_NAME);
338 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
339 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
340 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
341 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
342 SAMR_FIELD_LOGON_SCRIPT);
344 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
345 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
346 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
347 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
348 SAMR_FIELD_PROFILE_PATH);
350 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
351 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
352 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
353 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
354 SAMR_FIELD_HOME_DIRECTORY);
355 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
356 SAMR_FIELD_HOME_DIRECTORY);
358 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
359 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
360 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
361 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
362 SAMR_FIELD_HOME_DRIVE);
363 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
364 SAMR_FIELD_HOME_DRIVE);
366 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
367 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
368 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
369 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
370 SAMR_FIELD_DESCRIPTION);
372 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
373 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
374 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
375 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
376 SAMR_FIELD_WORKSTATIONS);
377 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
378 SAMR_FIELD_WORKSTATIONS);
379 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
380 SAMR_FIELD_WORKSTATIONS);
381 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
382 SAMR_FIELD_WORKSTATIONS);
384 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
385 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
386 SAMR_FIELD_PARAMETERS);
387 TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
388 SAMR_FIELD_PARAMETERS);
390 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
391 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
392 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
393 SAMR_FIELD_COUNTRY_CODE);
394 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
395 SAMR_FIELD_COUNTRY_CODE);
397 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
398 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
399 SAMR_FIELD_CODE_PAGE);
400 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
401 SAMR_FIELD_CODE_PAGE);
403 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
404 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
405 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
406 SAMR_FIELD_ACCT_EXPIRY);
407 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
408 SAMR_FIELD_ACCT_EXPIRY);
409 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
410 SAMR_FIELD_ACCT_EXPIRY);
412 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
413 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
414 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
415 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
416 SAMR_FIELD_LOGON_HOURS);
418 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
419 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
420 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
422 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
423 (base_acct_flags | ACB_DISABLED),
424 (base_acct_flags | ACB_DISABLED | user_extra_flags),
427 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
428 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
429 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
430 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
432 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
433 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
434 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
438 /* The 'autolock' flag doesn't stick - check this */
439 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
440 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
441 (base_acct_flags | ACB_DISABLED | user_extra_flags),
444 /* Removing the 'disabled' flag doesn't stick - check this */
445 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
447 (base_acct_flags | ACB_DISABLED | user_extra_flags),
450 /* The 'store plaintext' flag does stick */
451 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
452 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
453 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
455 /* The 'use DES' flag does stick */
456 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
457 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
458 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
460 /* The 'don't require kerberos pre-authentication flag does stick */
461 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
462 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
463 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
465 /* The 'no kerberos PAC required' flag sticks */
466 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
467 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
468 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
471 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
472 (base_acct_flags | ACB_DISABLED),
473 (base_acct_flags | ACB_DISABLED | user_extra_flags),
474 SAMR_FIELD_ACCT_FLAGS);
477 /* these fail with win2003 - it appears you can't set the primary gid?
478 the set succeeds, but the gid isn't changed. Very weird! */
479 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
480 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
481 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
482 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
489 generate a random password for password change tests
491 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
493 size_t len = MAX(8, min_len) + (random() % 6);
494 char *s = generate_random_str(mem_ctx, len);
495 printf("Generated password '%s'\n", s);
500 generate a random password for password change tests
502 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
505 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
506 generate_random_buffer(password.data, password.length);
508 for (i=0; i < len; i++) {
509 if (((uint16_t *)password.data)[i] == 0) {
510 ((uint16_t *)password.data)[i] = 1;
518 generate a random password for password change tests (fixed length)
520 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
522 char *s = generate_random_str(mem_ctx, len);
523 printf("Generated password '%s'\n", s);
527 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
528 struct policy_handle *handle, char **password)
531 struct samr_SetUserInfo s;
532 union samr_UserInfo u;
534 DATA_BLOB session_key;
536 struct samr_GetUserPwInfo pwp;
537 int policy_min_pw_len = 0;
538 pwp.in.user_handle = handle;
540 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
541 if (NT_STATUS_IS_OK(status)) {
542 policy_min_pw_len = pwp.out.info.min_password_length;
544 newpass = samr_rand_pass(tctx, policy_min_pw_len);
546 s.in.user_handle = handle;
550 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
551 /* w2k3 ignores this length */
552 u.info24.pw_len = strlen_m(newpass) * 2;
554 status = dcerpc_fetch_session_key(p, &session_key);
555 if (!NT_STATUS_IS_OK(status)) {
556 printf("SetUserInfo level %u - no session key - %s\n",
557 s.in.level, nt_errstr(status));
561 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
563 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
565 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
566 if (!NT_STATUS_IS_OK(status)) {
567 printf("SetUserInfo level %u failed - %s\n",
568 s.in.level, nt_errstr(status));
578 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
579 struct policy_handle *handle, uint32_t fields_present,
583 struct samr_SetUserInfo s;
584 union samr_UserInfo u;
586 DATA_BLOB session_key;
588 struct samr_GetUserPwInfo pwp;
589 int policy_min_pw_len = 0;
590 pwp.in.user_handle = handle;
592 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
593 if (NT_STATUS_IS_OK(status)) {
594 policy_min_pw_len = pwp.out.info.min_password_length;
596 newpass = samr_rand_pass(tctx, policy_min_pw_len);
598 s.in.user_handle = handle;
604 u.info23.info.fields_present = fields_present;
606 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
608 status = dcerpc_fetch_session_key(p, &session_key);
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("SetUserInfo level %u - no session key - %s\n",
611 s.in.level, nt_errstr(status));
615 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
617 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
619 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
620 if (!NT_STATUS_IS_OK(status)) {
621 printf("SetUserInfo level %u failed - %s\n",
622 s.in.level, nt_errstr(status));
628 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
630 status = dcerpc_fetch_session_key(p, &session_key);
631 if (!NT_STATUS_IS_OK(status)) {
632 printf("SetUserInfo level %u - no session key - %s\n",
633 s.in.level, nt_errstr(status));
637 /* This should break the key nicely */
638 session_key.length--;
639 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
641 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
643 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
644 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
645 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
646 s.in.level, nt_errstr(status));
654 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
655 struct policy_handle *handle, bool makeshort,
659 struct samr_SetUserInfo s;
660 union samr_UserInfo u;
662 DATA_BLOB session_key;
663 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
664 uint8_t confounder[16];
666 struct MD5Context ctx;
667 struct samr_GetUserPwInfo pwp;
668 int policy_min_pw_len = 0;
669 pwp.in.user_handle = handle;
671 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
672 if (NT_STATUS_IS_OK(status)) {
673 policy_min_pw_len = pwp.out.info.min_password_length;
675 if (makeshort && policy_min_pw_len) {
676 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
678 newpass = samr_rand_pass(tctx, policy_min_pw_len);
681 s.in.user_handle = handle;
685 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
686 u.info26.pw_len = strlen(newpass);
688 status = dcerpc_fetch_session_key(p, &session_key);
689 if (!NT_STATUS_IS_OK(status)) {
690 printf("SetUserInfo level %u - no session key - %s\n",
691 s.in.level, nt_errstr(status));
695 generate_random_buffer((uint8_t *)confounder, 16);
698 MD5Update(&ctx, confounder, 16);
699 MD5Update(&ctx, session_key.data, session_key.length);
700 MD5Final(confounded_session_key.data, &ctx);
702 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
703 memcpy(&u.info26.password.data[516], confounder, 16);
705 printf("Testing SetUserInfo level 26 (set password ex)\n");
707 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
708 if (!NT_STATUS_IS_OK(status)) {
709 printf("SetUserInfo level %u failed - %s\n",
710 s.in.level, nt_errstr(status));
716 /* This should break the key nicely */
717 confounded_session_key.data[0]++;
719 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
720 memcpy(&u.info26.password.data[516], confounder, 16);
722 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
724 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
725 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
726 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
727 s.in.level, nt_errstr(status));
736 static bool test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
737 struct policy_handle *handle, uint32_t fields_present,
741 struct samr_SetUserInfo s;
742 union samr_UserInfo u;
744 DATA_BLOB session_key;
745 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
746 struct MD5Context ctx;
747 uint8_t confounder[16];
749 struct samr_GetUserPwInfo pwp;
750 int policy_min_pw_len = 0;
751 pwp.in.user_handle = handle;
753 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
754 if (NT_STATUS_IS_OK(status)) {
755 policy_min_pw_len = pwp.out.info.min_password_length;
757 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
759 s.in.user_handle = handle;
765 u.info25.info.fields_present = fields_present;
767 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
769 status = dcerpc_fetch_session_key(p, &session_key);
770 if (!NT_STATUS_IS_OK(status)) {
771 printf("SetUserInfo level %u - no session key - %s\n",
772 s.in.level, nt_errstr(status));
776 generate_random_buffer((uint8_t *)confounder, 16);
779 MD5Update(&ctx, confounder, 16);
780 MD5Update(&ctx, session_key.data, session_key.length);
781 MD5Final(confounded_session_key.data, &ctx);
783 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
784 memcpy(&u.info25.password.data[516], confounder, 16);
786 printf("Testing SetUserInfo level 25 (set password ex)\n");
788 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
789 if (!NT_STATUS_IS_OK(status)) {
790 printf("SetUserInfo level %u failed - %s\n",
791 s.in.level, nt_errstr(status));
797 /* This should break the key nicely */
798 confounded_session_key.data[0]++;
800 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
801 memcpy(&u.info25.password.data[516], confounder, 16);
803 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
805 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
806 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
807 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
808 s.in.level, nt_errstr(status));
815 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
816 struct policy_handle *handle)
819 struct samr_SetAliasInfo r;
820 struct samr_QueryAliasInfo q;
821 uint16_t levels[] = {2, 3};
825 /* Ignoring switch level 1, as that includes the number of members for the alias
826 * and setting this to a wrong value might have negative consequences
829 for (i=0;i<ARRAY_SIZE(levels);i++) {
830 printf("Testing SetAliasInfo level %u\n", levels[i]);
832 r.in.alias_handle = handle;
833 r.in.level = levels[i];
834 r.in.info = talloc(tctx, union samr_AliasInfo);
835 switch (r.in.level) {
836 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
837 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
838 "Test Description, should test I18N as well"); break;
839 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
842 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
843 if (!NT_STATUS_IS_OK(status)) {
844 printf("SetAliasInfo level %u failed - %s\n",
845 levels[i], nt_errstr(status));
849 q.in.alias_handle = handle;
850 q.in.level = levels[i];
852 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
853 if (!NT_STATUS_IS_OK(status)) {
854 printf("QueryAliasInfo level %u failed - %s\n",
855 levels[i], nt_errstr(status));
863 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
864 struct policy_handle *user_handle)
866 struct samr_GetGroupsForUser r;
869 torture_comment(tctx, "testing GetGroupsForUser\n");
871 r.in.user_handle = user_handle;
873 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
874 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
880 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
881 struct lsa_String *domain_name)
884 struct samr_GetDomPwInfo r;
886 r.in.domain_name = domain_name;
887 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
889 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
890 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
892 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
893 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
895 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
896 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
898 r.in.domain_name->string = "\\\\__NONAME__";
899 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
901 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
902 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
904 r.in.domain_name->string = "\\\\Builtin";
905 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
907 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
908 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
913 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
914 struct policy_handle *handle)
917 struct samr_GetUserPwInfo r;
919 torture_comment(tctx, "Testing GetUserPwInfo\n");
921 r.in.user_handle = handle;
923 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
924 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
929 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
930 struct policy_handle *domain_handle, const char *name,
934 struct samr_LookupNames n;
935 struct lsa_String sname[2];
937 init_lsa_String(&sname[0], name);
939 n.in.domain_handle = domain_handle;
942 status = dcerpc_samr_LookupNames(p, tctx, &n);
943 if (NT_STATUS_IS_OK(status)) {
944 *rid = n.out.rids.ids[0];
949 init_lsa_String(&sname[1], "xxNONAMExx");
951 status = dcerpc_samr_LookupNames(p, tctx, &n);
952 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
953 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
954 if (NT_STATUS_IS_OK(status)) {
955 return NT_STATUS_UNSUCCESSFUL;
961 status = dcerpc_samr_LookupNames(p, tctx, &n);
962 if (!NT_STATUS_IS_OK(status)) {
963 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
967 init_lsa_String(&sname[0], "xxNONAMExx");
969 status = dcerpc_samr_LookupNames(p, tctx, &n);
970 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
971 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
972 if (NT_STATUS_IS_OK(status)) {
973 return NT_STATUS_UNSUCCESSFUL;
978 init_lsa_String(&sname[0], "xxNONAMExx");
979 init_lsa_String(&sname[1], "xxNONAME2xx");
981 status = dcerpc_samr_LookupNames(p, tctx, &n);
982 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
983 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
984 if (NT_STATUS_IS_OK(status)) {
985 return NT_STATUS_UNSUCCESSFUL;
993 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
994 struct policy_handle *domain_handle,
995 const char *name, struct policy_handle *user_handle)
998 struct samr_OpenUser r;
1001 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1002 if (!NT_STATUS_IS_OK(status)) {
1006 r.in.domain_handle = domain_handle;
1007 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1009 r.out.user_handle = user_handle;
1010 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1019 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1020 struct policy_handle *handle)
1023 struct samr_ChangePasswordUser r;
1025 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1026 struct policy_handle user_handle;
1027 char *oldpass = "test";
1028 char *newpass = "test2";
1029 uint8_t old_nt_hash[16], new_nt_hash[16];
1030 uint8_t old_lm_hash[16], new_lm_hash[16];
1032 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1033 if (!NT_STATUS_IS_OK(status)) {
1037 printf("Testing ChangePasswordUser for user 'testuser'\n");
1039 printf("old password: %s\n", oldpass);
1040 printf("new password: %s\n", newpass);
1042 E_md4hash(oldpass, old_nt_hash);
1043 E_md4hash(newpass, new_nt_hash);
1044 E_deshash(oldpass, old_lm_hash);
1045 E_deshash(newpass, new_lm_hash);
1047 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1048 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1049 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1050 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1051 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1052 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1054 r.in.handle = &user_handle;
1055 r.in.lm_present = 1;
1056 r.in.old_lm_crypted = &hash1;
1057 r.in.new_lm_crypted = &hash2;
1058 r.in.nt_present = 1;
1059 r.in.old_nt_crypted = &hash3;
1060 r.in.new_nt_crypted = &hash4;
1061 r.in.cross1_present = 1;
1062 r.in.nt_cross = &hash5;
1063 r.in.cross2_present = 1;
1064 r.in.lm_cross = &hash6;
1066 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1067 if (!NT_STATUS_IS_OK(status)) {
1068 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1072 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1080 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1081 const char *acct_name,
1082 struct policy_handle *handle, char **password)
1085 struct samr_ChangePasswordUser r;
1087 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1088 struct policy_handle user_handle;
1090 uint8_t old_nt_hash[16], new_nt_hash[16];
1091 uint8_t old_lm_hash[16], new_lm_hash[16];
1092 bool changed = true;
1095 struct samr_GetUserPwInfo pwp;
1096 int policy_min_pw_len = 0;
1098 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1099 if (!NT_STATUS_IS_OK(status)) {
1102 pwp.in.user_handle = &user_handle;
1104 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1105 if (NT_STATUS_IS_OK(status)) {
1106 policy_min_pw_len = pwp.out.info.min_password_length;
1108 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1110 printf("Testing ChangePasswordUser\n");
1113 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1117 oldpass = *password;
1119 E_md4hash(oldpass, old_nt_hash);
1120 E_md4hash(newpass, new_nt_hash);
1121 E_deshash(oldpass, old_lm_hash);
1122 E_deshash(newpass, new_lm_hash);
1124 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1125 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1126 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1127 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1128 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1129 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1131 r.in.user_handle = &user_handle;
1132 r.in.lm_present = 1;
1133 /* Break the LM hash */
1135 r.in.old_lm_crypted = &hash1;
1136 r.in.new_lm_crypted = &hash2;
1137 r.in.nt_present = 1;
1138 r.in.old_nt_crypted = &hash3;
1139 r.in.new_nt_crypted = &hash4;
1140 r.in.cross1_present = 1;
1141 r.in.nt_cross = &hash5;
1142 r.in.cross2_present = 1;
1143 r.in.lm_cross = &hash6;
1145 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1146 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1147 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1151 /* Unbreak the LM hash */
1154 r.in.user_handle = &user_handle;
1155 r.in.lm_present = 1;
1156 r.in.old_lm_crypted = &hash1;
1157 r.in.new_lm_crypted = &hash2;
1158 /* Break the NT hash */
1160 r.in.nt_present = 1;
1161 r.in.old_nt_crypted = &hash3;
1162 r.in.new_nt_crypted = &hash4;
1163 r.in.cross1_present = 1;
1164 r.in.nt_cross = &hash5;
1165 r.in.cross2_present = 1;
1166 r.in.lm_cross = &hash6;
1168 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1169 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1170 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1174 /* Unbreak the NT hash */
1177 r.in.user_handle = &user_handle;
1178 r.in.lm_present = 1;
1179 r.in.old_lm_crypted = &hash1;
1180 r.in.new_lm_crypted = &hash2;
1181 r.in.nt_present = 1;
1182 r.in.old_nt_crypted = &hash3;
1183 r.in.new_nt_crypted = &hash4;
1184 r.in.cross1_present = 1;
1185 r.in.nt_cross = &hash5;
1186 r.in.cross2_present = 1;
1187 /* Break the LM cross */
1189 r.in.lm_cross = &hash6;
1191 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1192 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1193 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1197 /* Unbreak the LM cross */
1200 r.in.user_handle = &user_handle;
1201 r.in.lm_present = 1;
1202 r.in.old_lm_crypted = &hash1;
1203 r.in.new_lm_crypted = &hash2;
1204 r.in.nt_present = 1;
1205 r.in.old_nt_crypted = &hash3;
1206 r.in.new_nt_crypted = &hash4;
1207 r.in.cross1_present = 1;
1208 /* Break the NT cross */
1210 r.in.nt_cross = &hash5;
1211 r.in.cross2_present = 1;
1212 r.in.lm_cross = &hash6;
1214 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1215 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1216 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1220 /* Unbreak the NT cross */
1224 /* Reset the hashes to not broken values */
1225 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1226 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1227 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1228 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1229 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1230 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1232 r.in.user_handle = &user_handle;
1233 r.in.lm_present = 1;
1234 r.in.old_lm_crypted = &hash1;
1235 r.in.new_lm_crypted = &hash2;
1236 r.in.nt_present = 1;
1237 r.in.old_nt_crypted = &hash3;
1238 r.in.new_nt_crypted = &hash4;
1239 r.in.cross1_present = 1;
1240 r.in.nt_cross = &hash5;
1241 r.in.cross2_present = 0;
1242 r.in.lm_cross = NULL;
1244 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1245 if (NT_STATUS_IS_OK(status)) {
1247 *password = newpass;
1248 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1249 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1254 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1256 E_md4hash(oldpass, old_nt_hash);
1257 E_md4hash(newpass, new_nt_hash);
1258 E_deshash(oldpass, old_lm_hash);
1259 E_deshash(newpass, new_lm_hash);
1262 /* Reset the hashes to not broken values */
1263 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1264 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1265 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1266 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1267 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1268 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1270 r.in.user_handle = &user_handle;
1271 r.in.lm_present = 1;
1272 r.in.old_lm_crypted = &hash1;
1273 r.in.new_lm_crypted = &hash2;
1274 r.in.nt_present = 1;
1275 r.in.old_nt_crypted = &hash3;
1276 r.in.new_nt_crypted = &hash4;
1277 r.in.cross1_present = 0;
1278 r.in.nt_cross = NULL;
1279 r.in.cross2_present = 1;
1280 r.in.lm_cross = &hash6;
1282 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1283 if (NT_STATUS_IS_OK(status)) {
1285 *password = newpass;
1286 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1287 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1292 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1294 E_md4hash(oldpass, old_nt_hash);
1295 E_md4hash(newpass, new_nt_hash);
1296 E_deshash(oldpass, old_lm_hash);
1297 E_deshash(newpass, new_lm_hash);
1300 /* Reset the hashes to not broken values */
1301 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1302 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1303 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1304 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1305 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1306 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1308 r.in.user_handle = &user_handle;
1309 r.in.lm_present = 1;
1310 r.in.old_lm_crypted = &hash1;
1311 r.in.new_lm_crypted = &hash2;
1312 r.in.nt_present = 1;
1313 r.in.old_nt_crypted = &hash3;
1314 r.in.new_nt_crypted = &hash4;
1315 r.in.cross1_present = 1;
1316 r.in.nt_cross = &hash5;
1317 r.in.cross2_present = 1;
1318 r.in.lm_cross = &hash6;
1320 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1321 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1322 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1323 } else if (!NT_STATUS_IS_OK(status)) {
1324 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1328 *password = newpass;
1331 r.in.user_handle = &user_handle;
1332 r.in.lm_present = 1;
1333 r.in.old_lm_crypted = &hash1;
1334 r.in.new_lm_crypted = &hash2;
1335 r.in.nt_present = 1;
1336 r.in.old_nt_crypted = &hash3;
1337 r.in.new_nt_crypted = &hash4;
1338 r.in.cross1_present = 1;
1339 r.in.nt_cross = &hash5;
1340 r.in.cross2_present = 1;
1341 r.in.lm_cross = &hash6;
1344 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1345 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1346 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1347 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1348 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1354 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1362 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1363 const char *acct_name,
1364 struct policy_handle *handle, char **password)
1367 struct samr_OemChangePasswordUser2 r;
1369 struct samr_Password lm_verifier;
1370 struct samr_CryptPassword lm_pass;
1371 struct lsa_AsciiString server, account, account_bad;
1374 uint8_t old_lm_hash[16], new_lm_hash[16];
1376 struct samr_GetDomPwInfo dom_pw_info;
1377 int policy_min_pw_len = 0;
1379 struct lsa_String domain_name;
1381 domain_name.string = "";
1382 dom_pw_info.in.domain_name = &domain_name;
1384 printf("Testing OemChangePasswordUser2\n");
1387 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1391 oldpass = *password;
1393 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1394 if (NT_STATUS_IS_OK(status)) {
1395 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1398 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1400 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1401 account.string = acct_name;
1403 E_deshash(oldpass, old_lm_hash);
1404 E_deshash(newpass, new_lm_hash);
1406 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1407 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1408 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1410 r.in.server = &server;
1411 r.in.account = &account;
1412 r.in.password = &lm_pass;
1413 r.in.hash = &lm_verifier;
1415 /* Break the verification */
1416 lm_verifier.hash[0]++;
1418 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1420 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1421 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1422 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1427 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1428 /* Break the old password */
1430 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1431 /* unbreak it for the next operation */
1433 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1435 r.in.server = &server;
1436 r.in.account = &account;
1437 r.in.password = &lm_pass;
1438 r.in.hash = &lm_verifier;
1440 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1442 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1443 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1444 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1449 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1450 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1452 r.in.server = &server;
1453 r.in.account = &account;
1454 r.in.password = &lm_pass;
1457 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1459 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1460 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1461 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1466 /* This shouldn't be a valid name */
1467 account_bad.string = TEST_ACCOUNT_NAME "XX";
1468 r.in.account = &account_bad;
1470 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1472 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1473 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1478 /* This shouldn't be a valid name */
1479 account_bad.string = TEST_ACCOUNT_NAME "XX";
1480 r.in.account = &account_bad;
1481 r.in.password = &lm_pass;
1482 r.in.hash = &lm_verifier;
1484 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1486 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1487 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1492 /* This shouldn't be a valid name */
1493 account_bad.string = TEST_ACCOUNT_NAME "XX";
1494 r.in.account = &account_bad;
1495 r.in.password = NULL;
1496 r.in.hash = &lm_verifier;
1498 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1500 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1501 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1506 E_deshash(oldpass, old_lm_hash);
1507 E_deshash(newpass, new_lm_hash);
1509 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1510 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1511 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1513 r.in.server = &server;
1514 r.in.account = &account;
1515 r.in.password = &lm_pass;
1516 r.in.hash = &lm_verifier;
1518 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1519 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1520 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1521 } else if (!NT_STATUS_IS_OK(status)) {
1522 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1525 *password = newpass;
1532 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1533 const char *acct_name,
1535 char *newpass, bool allow_password_restriction)
1538 struct samr_ChangePasswordUser2 r;
1540 struct lsa_String server, account;
1541 struct samr_CryptPassword nt_pass, lm_pass;
1542 struct samr_Password nt_verifier, lm_verifier;
1544 uint8_t old_nt_hash[16], new_nt_hash[16];
1545 uint8_t old_lm_hash[16], new_lm_hash[16];
1547 struct samr_GetDomPwInfo dom_pw_info;
1549 struct lsa_String domain_name;
1551 domain_name.string = "";
1552 dom_pw_info.in.domain_name = &domain_name;
1554 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1557 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1560 oldpass = *password;
1563 int policy_min_pw_len = 0;
1564 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1565 if (NT_STATUS_IS_OK(status)) {
1566 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1569 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1572 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1573 init_lsa_String(&account, acct_name);
1575 E_md4hash(oldpass, old_nt_hash);
1576 E_md4hash(newpass, new_nt_hash);
1578 E_deshash(oldpass, old_lm_hash);
1579 E_deshash(newpass, new_lm_hash);
1581 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1582 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1583 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1585 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1586 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1587 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1589 r.in.server = &server;
1590 r.in.account = &account;
1591 r.in.nt_password = &nt_pass;
1592 r.in.nt_verifier = &nt_verifier;
1594 r.in.lm_password = &lm_pass;
1595 r.in.lm_verifier = &lm_verifier;
1597 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1598 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1599 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1600 } else if (!NT_STATUS_IS_OK(status)) {
1601 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1604 *password = newpass;
1611 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1612 const char *account_string,
1613 int policy_min_pw_len,
1615 const char *newpass,
1616 NTTIME last_password_change,
1617 bool handle_reject_reason)
1620 struct samr_ChangePasswordUser3 r;
1622 struct lsa_String server, account, account_bad;
1623 struct samr_CryptPassword nt_pass, lm_pass;
1624 struct samr_Password nt_verifier, lm_verifier;
1626 uint8_t old_nt_hash[16], new_nt_hash[16];
1627 uint8_t old_lm_hash[16], new_lm_hash[16];
1630 printf("Testing ChangePasswordUser3\n");
1632 if (newpass == NULL) {
1634 if (policy_min_pw_len == 0) {
1635 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1637 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1639 } while (check_password_quality(newpass) == false);
1641 printf("Using password '%s'\n", newpass);
1645 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1649 oldpass = *password;
1650 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1651 init_lsa_String(&account, account_string);
1653 E_md4hash(oldpass, old_nt_hash);
1654 E_md4hash(newpass, new_nt_hash);
1656 E_deshash(oldpass, old_lm_hash);
1657 E_deshash(newpass, new_lm_hash);
1659 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1660 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1661 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1663 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1664 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1665 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1667 /* Break the verification */
1668 nt_verifier.hash[0]++;
1670 r.in.server = &server;
1671 r.in.account = &account;
1672 r.in.nt_password = &nt_pass;
1673 r.in.nt_verifier = &nt_verifier;
1675 r.in.lm_password = &lm_pass;
1676 r.in.lm_verifier = &lm_verifier;
1677 r.in.password3 = NULL;
1679 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1680 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1681 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1682 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1687 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1688 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1689 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1691 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1692 /* Break the NT hash */
1694 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1695 /* Unbreak it again */
1697 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1699 r.in.server = &server;
1700 r.in.account = &account;
1701 r.in.nt_password = &nt_pass;
1702 r.in.nt_verifier = &nt_verifier;
1704 r.in.lm_password = &lm_pass;
1705 r.in.lm_verifier = &lm_verifier;
1706 r.in.password3 = NULL;
1708 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1709 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1710 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1711 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1716 /* This shouldn't be a valid name */
1717 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1719 r.in.account = &account_bad;
1720 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1721 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1722 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1727 E_md4hash(oldpass, old_nt_hash);
1728 E_md4hash(newpass, new_nt_hash);
1730 E_deshash(oldpass, old_lm_hash);
1731 E_deshash(newpass, new_lm_hash);
1733 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1734 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1735 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1737 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1738 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1739 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1741 r.in.server = &server;
1742 r.in.account = &account;
1743 r.in.nt_password = &nt_pass;
1744 r.in.nt_verifier = &nt_verifier;
1746 r.in.lm_password = &lm_pass;
1747 r.in.lm_verifier = &lm_verifier;
1748 r.in.password3 = NULL;
1750 unix_to_nt_time(&t, time(NULL));
1752 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1754 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1757 && handle_reject_reason
1758 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1759 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1761 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1762 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1763 SAMR_REJECT_OTHER, r.out.reject->reason);
1768 /* We tested the order of precendence which is as follows:
1777 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1778 (last_password_change + r.out.dominfo->min_password_age > t)) {
1780 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1781 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1782 SAMR_REJECT_OTHER, r.out.reject->reason);
1786 } else if ((r.out.dominfo->min_password_length > 0) &&
1787 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1789 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1790 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1791 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1795 } else if ((r.out.dominfo->password_history_length > 0) &&
1796 strequal(oldpass, newpass)) {
1798 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1799 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1800 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1803 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1805 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1806 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1807 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1813 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1814 /* retry with adjusted size */
1815 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1816 r.out.dominfo->min_password_length,
1817 password, NULL, 0, false);
1821 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1822 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1823 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1824 SAMR_REJECT_OTHER, r.out.reject->reason);
1827 /* Perhaps the server has a 'min password age' set? */
1829 } else if (!NT_STATUS_IS_OK(status)) {
1830 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1833 *password = talloc_strdup(mem_ctx, newpass);
1839 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1840 const char *account_string,
1841 struct policy_handle *handle,
1845 struct samr_ChangePasswordUser3 r;
1846 struct samr_SetUserInfo s;
1847 union samr_UserInfo u;
1848 DATA_BLOB session_key;
1849 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
1850 uint8_t confounder[16];
1851 struct MD5Context ctx;
1854 struct lsa_String server, account;
1855 struct samr_CryptPassword nt_pass;
1856 struct samr_Password nt_verifier;
1857 DATA_BLOB new_random_pass;
1860 uint8_t old_nt_hash[16], new_nt_hash[16];
1863 new_random_pass = samr_very_rand_pass(mem_ctx, 128);
1866 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1870 oldpass = *password;
1871 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1872 init_lsa_String(&account, account_string);
1874 s.in.user_handle = handle;
1880 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1882 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1884 status = dcerpc_fetch_session_key(p, &session_key);
1885 if (!NT_STATUS_IS_OK(status)) {
1886 printf("SetUserInfo level %u - no session key - %s\n",
1887 s.in.level, nt_errstr(status));
1891 generate_random_buffer((uint8_t *)confounder, 16);
1894 MD5Update(&ctx, confounder, 16);
1895 MD5Update(&ctx, session_key.data, session_key.length);
1896 MD5Final(confounded_session_key.data, &ctx);
1898 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1899 memcpy(&u.info25.password.data[516], confounder, 16);
1901 printf("Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1903 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
1904 if (!NT_STATUS_IS_OK(status)) {
1905 printf("SetUserInfo level %u failed - %s\n",
1906 s.in.level, nt_errstr(status));
1910 printf("Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1912 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1914 new_random_pass = samr_very_rand_pass(mem_ctx, 128);
1916 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1918 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1919 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1920 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1922 r.in.server = &server;
1923 r.in.account = &account;
1924 r.in.nt_password = &nt_pass;
1925 r.in.nt_verifier = &nt_verifier;
1927 r.in.lm_password = NULL;
1928 r.in.lm_verifier = NULL;
1929 r.in.password3 = NULL;
1931 unix_to_nt_time(&t, time(NULL));
1933 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1935 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1936 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1937 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1938 SAMR_REJECT_OTHER, r.out.reject->reason);
1941 /* Perhaps the server has a 'min password age' set? */
1943 } else if (!NT_STATUS_IS_OK(status)) {
1944 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1948 newpass = samr_rand_pass(mem_ctx, 128);
1950 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1952 E_md4hash(newpass, new_nt_hash);
1954 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1955 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1956 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1958 r.in.server = &server;
1959 r.in.account = &account;
1960 r.in.nt_password = &nt_pass;
1961 r.in.nt_verifier = &nt_verifier;
1963 r.in.lm_password = NULL;
1964 r.in.lm_verifier = NULL;
1965 r.in.password3 = NULL;
1967 unix_to_nt_time(&t, time(NULL));
1969 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1971 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1972 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1973 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1974 SAMR_REJECT_OTHER, r.out.reject->reason);
1977 /* Perhaps the server has a 'min password age' set? */
1979 } else if (!NT_STATUS_IS_OK(status)) {
1980 printf("ChangePasswordUser3 (on second random password) failed - %s\n", nt_errstr(status));
1983 *password = talloc_strdup(mem_ctx, newpass);
1990 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1991 struct policy_handle *alias_handle)
1993 struct samr_GetMembersInAlias r;
1994 struct lsa_SidArray sids;
1998 printf("Testing GetMembersInAlias\n");
2000 r.in.alias_handle = alias_handle;
2003 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
2004 if (!NT_STATUS_IS_OK(status)) {
2005 printf("GetMembersInAlias failed - %s\n",
2013 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2014 struct policy_handle *alias_handle,
2015 const struct dom_sid *domain_sid)
2017 struct samr_AddAliasMember r;
2018 struct samr_DeleteAliasMember d;
2021 struct dom_sid *sid;
2023 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
2025 printf("testing AddAliasMember\n");
2026 r.in.alias_handle = alias_handle;
2029 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
2030 if (!NT_STATUS_IS_OK(status)) {
2031 printf("AddAliasMember failed - %s\n", nt_errstr(status));
2035 d.in.alias_handle = alias_handle;
2038 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
2039 if (!NT_STATUS_IS_OK(status)) {
2040 printf("DelAliasMember failed - %s\n", nt_errstr(status));
2047 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2048 struct policy_handle *alias_handle)
2050 struct samr_AddMultipleMembersToAlias a;
2051 struct samr_RemoveMultipleMembersFromAlias r;
2054 struct lsa_SidArray sids;
2056 printf("testing AddMultipleMembersToAlias\n");
2057 a.in.alias_handle = alias_handle;
2061 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
2063 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
2064 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
2065 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
2067 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
2068 if (!NT_STATUS_IS_OK(status)) {
2069 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
2074 printf("testing RemoveMultipleMembersFromAlias\n");
2075 r.in.alias_handle = alias_handle;
2078 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2079 if (!NT_STATUS_IS_OK(status)) {
2080 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2084 /* strange! removing twice doesn't give any error */
2085 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2086 if (!NT_STATUS_IS_OK(status)) {
2087 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2091 /* but removing an alias that isn't there does */
2092 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
2094 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2095 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
2096 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2103 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2104 struct policy_handle *user_handle)
2106 struct samr_TestPrivateFunctionsUser r;
2110 printf("Testing TestPrivateFunctionsUser\n");
2112 r.in.user_handle = user_handle;
2114 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
2115 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2116 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
2124 static bool test_user_ops(struct dcerpc_pipe *p,
2125 struct torture_context *tctx,
2126 struct policy_handle *user_handle,
2127 struct policy_handle *domain_handle,
2128 uint32_t base_acct_flags,
2129 const char *base_acct_name, enum torture_samr_choice which_ops)
2131 char *password = NULL;
2132 struct samr_QueryUserInfo q;
2138 const uint32_t password_fields[] = {
2139 SAMR_FIELD_PASSWORD,
2140 SAMR_FIELD_PASSWORD2,
2141 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2145 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2146 if (!NT_STATUS_IS_OK(status)) {
2150 switch (which_ops) {
2151 case TORTURE_SAMR_USER_ATTRIBUTES:
2152 if (!test_QuerySecurity(p, tctx, user_handle)) {
2156 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2160 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2164 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2169 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2173 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2177 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2181 case TORTURE_SAMR_PASSWORDS:
2182 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2183 char simple_pass[9];
2184 char *v = generate_random_str(tctx, 1);
2186 ZERO_STRUCT(simple_pass);
2187 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2189 printf("Testing machine account password policy rules\n");
2191 /* Workstation trust accounts don't seem to need to honour password quality policy */
2192 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2196 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2200 /* reset again, to allow another 'user' password change */
2201 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2205 /* Try a 'short' password */
2206 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2210 /* Try a compleatly random password */
2211 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2216 for (i = 0; password_fields[i]; i++) {
2217 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2221 /* check it was set right */
2222 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2227 for (i = 0; password_fields[i]; i++) {
2228 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2232 /* check it was set right */
2233 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2238 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2242 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2246 q.in.user_handle = user_handle;
2249 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2250 if (!NT_STATUS_IS_OK(status)) {
2251 printf("QueryUserInfo level %u failed - %s\n",
2252 q.in.level, nt_errstr(status));
2255 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2256 if ((q.out.info->info5.acct_flags) != expected_flags) {
2257 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2258 q.out.info->info5.acct_flags,
2262 if (q.out.info->info5.rid != rid) {
2263 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2264 q.out.info->info5.rid, rid);
2270 case TORTURE_SAMR_OTHER:
2271 /* We just need the account to exist */
2277 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2278 struct policy_handle *alias_handle,
2279 const struct dom_sid *domain_sid)
2283 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2287 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2291 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2295 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2299 if (torture_setting_bool(tctx, "samba4", false)) {
2300 printf("skipping MultipleMembers Alias tests against Samba4\n");
2304 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2312 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2313 struct policy_handle *user_handle)
2315 struct samr_DeleteUser d;
2318 printf("Testing DeleteUser\n");
2320 d.in.user_handle = user_handle;
2321 d.out.user_handle = user_handle;
2323 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2324 if (!NT_STATUS_IS_OK(status)) {
2325 printf("DeleteUser failed - %s\n", nt_errstr(status));
2332 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2333 struct policy_handle *handle, const char *name)
2336 struct samr_DeleteUser d;
2337 struct policy_handle user_handle;
2340 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2341 if (!NT_STATUS_IS_OK(status)) {
2345 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2346 if (!NT_STATUS_IS_OK(status)) {
2350 d.in.user_handle = &user_handle;
2351 d.out.user_handle = &user_handle;
2352 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2353 if (!NT_STATUS_IS_OK(status)) {
2360 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2365 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2366 struct policy_handle *handle, const char *name)
2369 struct samr_OpenGroup r;
2370 struct samr_DeleteDomainGroup d;
2371 struct policy_handle group_handle;
2374 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2375 if (!NT_STATUS_IS_OK(status)) {
2379 r.in.domain_handle = handle;
2380 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2382 r.out.group_handle = &group_handle;
2383 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2384 if (!NT_STATUS_IS_OK(status)) {
2388 d.in.group_handle = &group_handle;
2389 d.out.group_handle = &group_handle;
2390 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2391 if (!NT_STATUS_IS_OK(status)) {
2398 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2403 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2404 struct policy_handle *domain_handle, const char *name)
2407 struct samr_OpenAlias r;
2408 struct samr_DeleteDomAlias d;
2409 struct policy_handle alias_handle;
2412 printf("testing DeleteAlias_byname\n");
2414 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2415 if (!NT_STATUS_IS_OK(status)) {
2419 r.in.domain_handle = domain_handle;
2420 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2422 r.out.alias_handle = &alias_handle;
2423 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2424 if (!NT_STATUS_IS_OK(status)) {
2428 d.in.alias_handle = &alias_handle;
2429 d.out.alias_handle = &alias_handle;
2430 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2431 if (!NT_STATUS_IS_OK(status)) {
2438 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2442 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2443 struct policy_handle *alias_handle)
2445 struct samr_DeleteDomAlias d;
2448 printf("Testing DeleteAlias\n");
2450 d.in.alias_handle = alias_handle;
2451 d.out.alias_handle = alias_handle;
2453 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2454 if (!NT_STATUS_IS_OK(status)) {
2455 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2462 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2463 struct policy_handle *domain_handle,
2464 struct policy_handle *alias_handle,
2465 const struct dom_sid *domain_sid)
2468 struct samr_CreateDomAlias r;
2469 struct lsa_String name;
2473 init_lsa_String(&name, TEST_ALIASNAME);
2474 r.in.domain_handle = domain_handle;
2475 r.in.alias_name = &name;
2476 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2477 r.out.alias_handle = alias_handle;
2480 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2482 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2484 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2485 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2486 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2489 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2495 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2496 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2499 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2502 if (!NT_STATUS_IS_OK(status)) {
2503 printf("CreateAlias failed - %s\n", nt_errstr(status));
2507 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2514 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2515 const char *acct_name,
2516 struct policy_handle *domain_handle, char **password)
2524 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2528 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2532 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2536 /* test what happens when setting the old password again */
2537 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2542 char simple_pass[9];
2543 char *v = generate_random_str(mem_ctx, 1);
2545 ZERO_STRUCT(simple_pass);
2546 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2548 /* test what happens when picking a simple password */
2549 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2554 /* set samr_SetDomainInfo level 1 with min_length 5 */
2556 struct samr_QueryDomainInfo r;
2557 struct samr_SetDomainInfo s;
2558 uint16_t len_old, len;
2559 uint32_t pwd_prop_old;
2560 int64_t min_pwd_age_old;
2565 r.in.domain_handle = domain_handle;
2568 printf("testing samr_QueryDomainInfo level 1\n");
2569 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2570 if (!NT_STATUS_IS_OK(status)) {
2574 s.in.domain_handle = domain_handle;
2576 s.in.info = r.out.info;
2578 /* remember the old min length, so we can reset it */
2579 len_old = s.in.info->info1.min_password_length;
2580 s.in.info->info1.min_password_length = len;
2581 pwd_prop_old = s.in.info->info1.password_properties;
2582 /* turn off password complexity checks for this test */
2583 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2585 min_pwd_age_old = s.in.info->info1.min_password_age;
2586 s.in.info->info1.min_password_age = 0;
2588 printf("testing samr_SetDomainInfo level 1\n");
2589 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2590 if (!NT_STATUS_IS_OK(status)) {
2594 printf("calling test_ChangePasswordUser3 with too short password\n");
2596 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2600 s.in.info->info1.min_password_length = len_old;
2601 s.in.info->info1.password_properties = pwd_prop_old;
2602 s.in.info->info1.min_password_age = min_pwd_age_old;
2604 printf("testing samr_SetDomainInfo level 1\n");
2605 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2606 if (!NT_STATUS_IS_OK(status)) {
2614 struct samr_OpenUser r;
2615 struct samr_QueryUserInfo q;
2616 struct samr_LookupNames n;
2617 struct policy_handle user_handle;
2619 n.in.domain_handle = domain_handle;
2621 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2622 n.in.names[0].string = acct_name;
2624 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2625 if (!NT_STATUS_IS_OK(status)) {
2626 printf("LookupNames failed - %s\n", nt_errstr(status));
2630 r.in.domain_handle = domain_handle;
2631 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2632 r.in.rid = n.out.rids.ids[0];
2633 r.out.user_handle = &user_handle;
2635 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2636 if (!NT_STATUS_IS_OK(status)) {
2637 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2641 q.in.user_handle = &user_handle;
2644 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2645 if (!NT_STATUS_IS_OK(status)) {
2646 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2650 printf("calling test_ChangePasswordUser3 with too early password change\n");
2652 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2653 q.out.info->info5.last_password_change, true)) {
2658 /* we change passwords twice - this has the effect of verifying
2659 they were changed correctly for the final call */
2660 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2664 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2671 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2672 struct policy_handle *domain_handle,
2673 struct policy_handle *user_handle_out,
2674 struct dom_sid *domain_sid,
2675 enum torture_samr_choice which_ops)
2678 TALLOC_CTX *user_ctx;
2681 struct samr_CreateUser r;
2682 struct samr_QueryUserInfo q;
2683 struct samr_DeleteUser d;
2686 /* This call creates a 'normal' account - check that it really does */
2687 const uint32_t acct_flags = ACB_NORMAL;
2688 struct lsa_String name;
2691 struct policy_handle user_handle;
2692 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2693 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2695 r.in.domain_handle = domain_handle;
2696 r.in.account_name = &name;
2697 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2698 r.out.user_handle = &user_handle;
2701 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2703 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2705 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2706 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2707 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2710 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2716 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2717 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2718 talloc_free(user_ctx);
2721 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2723 if (!NT_STATUS_IS_OK(status)) {
2724 talloc_free(user_ctx);
2725 printf("CreateUser failed - %s\n", nt_errstr(status));
2728 q.in.user_handle = &user_handle;
2731 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2732 if (!NT_STATUS_IS_OK(status)) {
2733 printf("QueryUserInfo level %u failed - %s\n",
2734 q.in.level, nt_errstr(status));
2737 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2738 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2739 q.out.info->info16.acct_flags,
2745 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2746 acct_flags, name.string, which_ops)) {
2750 if (user_handle_out) {
2751 *user_handle_out = user_handle;
2753 printf("Testing DeleteUser (createuser test)\n");
2755 d.in.user_handle = &user_handle;
2756 d.out.user_handle = &user_handle;
2758 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2759 if (!NT_STATUS_IS_OK(status)) {
2760 printf("DeleteUser failed - %s\n", nt_errstr(status));
2767 talloc_free(user_ctx);
2773 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2774 struct policy_handle *domain_handle,
2775 struct dom_sid *domain_sid,
2776 enum torture_samr_choice which_ops)
2779 struct samr_CreateUser2 r;
2780 struct samr_QueryUserInfo q;
2781 struct samr_DeleteUser d;
2782 struct policy_handle user_handle;
2784 struct lsa_String name;
2789 uint32_t acct_flags;
2790 const char *account_name;
2792 } account_types[] = {
2793 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2794 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2795 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2796 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2797 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2798 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2799 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2800 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2801 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2802 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2803 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2804 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2805 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2806 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2807 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2810 for (i = 0; account_types[i].account_name; i++) {
2811 TALLOC_CTX *user_ctx;
2812 uint32_t acct_flags = account_types[i].acct_flags;
2813 uint32_t access_granted;
2814 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2815 init_lsa_String(&name, account_types[i].account_name);
2817 r.in.domain_handle = domain_handle;
2818 r.in.account_name = &name;
2819 r.in.acct_flags = acct_flags;
2820 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2821 r.out.user_handle = &user_handle;
2822 r.out.access_granted = &access_granted;
2825 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2827 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2829 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2830 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2831 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2834 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2841 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2842 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2843 talloc_free(user_ctx);
2847 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2850 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2851 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2852 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2856 if (NT_STATUS_IS_OK(status)) {
2857 q.in.user_handle = &user_handle;
2860 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2861 if (!NT_STATUS_IS_OK(status)) {
2862 printf("QueryUserInfo level %u failed - %s\n",
2863 q.in.level, nt_errstr(status));
2866 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2867 if (acct_flags == ACB_NORMAL) {
2868 expected_flags |= ACB_PW_EXPIRED;
2870 if ((q.out.info->info5.acct_flags) != expected_flags) {
2871 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2872 q.out.info->info5.acct_flags,
2876 switch (acct_flags) {
2878 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2879 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2880 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2885 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2886 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2887 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2892 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2893 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2894 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2901 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2902 acct_flags, name.string, which_ops)) {
2906 printf("Testing DeleteUser (createuser2 test)\n");
2908 d.in.user_handle = &user_handle;
2909 d.out.user_handle = &user_handle;
2911 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2912 if (!NT_STATUS_IS_OK(status)) {
2913 printf("DeleteUser failed - %s\n", nt_errstr(status));
2917 talloc_free(user_ctx);
2923 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2924 struct policy_handle *handle)
2927 struct samr_QueryAliasInfo r;
2928 uint16_t levels[] = {1, 2, 3};
2932 for (i=0;i<ARRAY_SIZE(levels);i++) {
2933 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2935 r.in.alias_handle = handle;
2936 r.in.level = levels[i];
2938 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 printf("QueryAliasInfo level %u failed - %s\n",
2941 levels[i], nt_errstr(status));
2949 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2950 struct policy_handle *handle)
2953 struct samr_QueryGroupInfo r;
2954 uint16_t levels[] = {1, 2, 3, 4, 5};
2958 for (i=0;i<ARRAY_SIZE(levels);i++) {
2959 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2961 r.in.group_handle = handle;
2962 r.in.level = levels[i];
2964 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2965 if (!NT_STATUS_IS_OK(status)) {
2966 printf("QueryGroupInfo level %u failed - %s\n",
2967 levels[i], nt_errstr(status));
2975 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2976 struct policy_handle *handle)
2979 struct samr_QueryGroupMember r;
2982 printf("Testing QueryGroupMember\n");
2984 r.in.group_handle = handle;
2986 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2987 if (!NT_STATUS_IS_OK(status)) {
2988 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2996 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2997 struct policy_handle *handle)
3000 struct samr_QueryGroupInfo r;
3001 struct samr_SetGroupInfo s;
3002 uint16_t levels[] = {1, 2, 3, 4};
3003 uint16_t set_ok[] = {0, 1, 1, 1};
3007 for (i=0;i<ARRAY_SIZE(levels);i++) {
3008 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3010 r.in.group_handle = handle;
3011 r.in.level = levels[i];
3013 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3014 if (!NT_STATUS_IS_OK(status)) {
3015 printf("QueryGroupInfo level %u failed - %s\n",
3016 levels[i], nt_errstr(status));
3020 printf("Testing SetGroupInfo level %u\n", levels[i]);
3022 s.in.group_handle = handle;
3023 s.in.level = levels[i];
3024 s.in.info = r.out.info;
3027 /* disabled this, as it changes the name only from the point of view of samr,
3028 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3029 the name is still reserved, so creating the old name fails, but deleting by the old name
3031 if (s.in.level == 2) {
3032 init_lsa_String(&s.in.info->string, "NewName");
3036 if (s.in.level == 4) {
3037 init_lsa_String(&s.in.info->description, "test description");
3040 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3042 if (!NT_STATUS_IS_OK(status)) {
3043 printf("SetGroupInfo level %u failed - %s\n",
3044 r.in.level, nt_errstr(status));
3049 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3050 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3051 r.in.level, nt_errstr(status));
3061 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3062 struct policy_handle *handle)
3065 struct samr_QueryUserInfo r;
3066 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3067 11, 12, 13, 14, 16, 17, 20, 21};
3071 for (i=0;i<ARRAY_SIZE(levels);i++) {
3072 printf("Testing QueryUserInfo level %u\n", levels[i]);
3074 r.in.user_handle = handle;
3075 r.in.level = levels[i];
3077 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3078 if (!NT_STATUS_IS_OK(status)) {
3079 printf("QueryUserInfo level %u failed - %s\n",
3080 levels[i], nt_errstr(status));
3088 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3089 struct policy_handle *handle)
3092 struct samr_QueryUserInfo2 r;
3093 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3094 11, 12, 13, 14, 16, 17, 20, 21};
3098 for (i=0;i<ARRAY_SIZE(levels);i++) {
3099 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3101 r.in.user_handle = handle;
3102 r.in.level = levels[i];
3104 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3105 if (!NT_STATUS_IS_OK(status)) {
3106 printf("QueryUserInfo2 level %u failed - %s\n",
3107 levels[i], nt_errstr(status));
3115 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3116 struct policy_handle *handle, uint32_t rid)
3119 struct samr_OpenUser r;
3120 struct policy_handle user_handle;
3123 printf("Testing OpenUser(%u)\n", rid);
3125 r.in.domain_handle = handle;
3126 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3128 r.out.user_handle = &user_handle;
3130 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3131 if (!NT_STATUS_IS_OK(status)) {
3132 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3136 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3140 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3144 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3148 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3152 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3156 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3163 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3164 struct policy_handle *handle, uint32_t rid)
3167 struct samr_OpenGroup r;
3168 struct policy_handle group_handle;
3171 printf("Testing OpenGroup(%u)\n", rid);
3173 r.in.domain_handle = handle;
3174 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3176 r.out.group_handle = &group_handle;
3178 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3179 if (!NT_STATUS_IS_OK(status)) {
3180 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3184 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3188 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3192 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3196 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3203 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3204 struct policy_handle *handle, uint32_t rid)
3207 struct samr_OpenAlias r;
3208 struct policy_handle alias_handle;
3211 printf("Testing OpenAlias(%u)\n", rid);
3213 r.in.domain_handle = handle;
3214 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3216 r.out.alias_handle = &alias_handle;
3218 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3219 if (!NT_STATUS_IS_OK(status)) {
3220 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3224 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3228 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3232 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3236 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3243 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3244 struct policy_handle *handle, uint32_t rid,
3245 uint32_t acct_flag_mask)
3248 struct samr_OpenUser r;
3249 struct samr_QueryUserInfo q;
3250 struct policy_handle user_handle;
3253 printf("Testing OpenUser(%u)\n", rid);
3255 r.in.domain_handle = handle;
3256 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3258 r.out.user_handle = &user_handle;
3260 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3261 if (!NT_STATUS_IS_OK(status)) {
3262 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3266 q.in.user_handle = &user_handle;
3269 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3270 if (!NT_STATUS_IS_OK(status)) {
3271 printf("QueryUserInfo level 16 failed - %s\n",
3275 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3276 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3277 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3282 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3289 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3290 struct policy_handle *handle)
3292 NTSTATUS status = STATUS_MORE_ENTRIES;
3293 struct samr_EnumDomainUsers r;
3294 uint32_t mask, resume_handle=0;
3297 struct samr_LookupNames n;
3298 struct samr_LookupRids lr ;
3299 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3300 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3301 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3304 printf("Testing EnumDomainUsers\n");
3306 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3307 r.in.domain_handle = handle;
3308 r.in.resume_handle = &resume_handle;
3309 r.in.acct_flags = mask = masks[mask_idx];
3310 r.in.max_size = (uint32_t)-1;
3311 r.out.resume_handle = &resume_handle;
3313 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3314 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3315 !NT_STATUS_IS_OK(status)) {
3316 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3321 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3325 if (r.out.sam->count == 0) {
3329 for (i=0;i<r.out.sam->count;i++) {
3331 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3334 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3340 printf("Testing LookupNames\n");
3341 n.in.domain_handle = handle;
3342 n.in.num_names = r.out.sam->count;
3343 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3344 for (i=0;i<r.out.sam->count;i++) {
3345 n.in.names[i].string = r.out.sam->entries[i].name.string;
3347 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3348 if (!NT_STATUS_IS_OK(status)) {
3349 printf("LookupNames failed - %s\n", nt_errstr(status));
3354 printf("Testing LookupRids\n");
3355 lr.in.domain_handle = handle;
3356 lr.in.num_rids = r.out.sam->count;
3357 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3358 for (i=0;i<r.out.sam->count;i++) {
3359 lr.in.rids[i] = r.out.sam->entries[i].idx;
3361 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3362 if (!NT_STATUS_IS_OK(status)) {
3363 printf("LookupRids failed - %s\n", nt_errstr(status));
3371 try blasting the server with a bunch of sync requests
3373 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx,
3374 struct policy_handle *handle)
3377 struct samr_EnumDomainUsers r;
3378 uint32_t resume_handle=0;
3380 #define ASYNC_COUNT 100
3381 struct rpc_request *req[ASYNC_COUNT];
3383 if (!torture_setting_bool(tctx, "dangerous", false)) {
3384 printf("samr async test disabled - enable dangerous tests to use\n");
3388 printf("Testing EnumDomainUsers_async\n");
3390 r.in.domain_handle = handle;
3391 r.in.resume_handle = &resume_handle;
3392 r.in.acct_flags = 0;
3393 r.in.max_size = (uint32_t)-1;
3394 r.out.resume_handle = &resume_handle;
3396 for (i=0;i<ASYNC_COUNT;i++) {
3397 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3400 for (i=0;i<ASYNC_COUNT;i++) {
3401 status = dcerpc_ndr_request_recv(req[i]);
3402 if (!NT_STATUS_IS_OK(status)) {
3403 printf("EnumDomainUsers[%d] failed - %s\n",
3404 i, nt_errstr(status));
3409 printf("%d async requests OK\n", i);
3414 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3415 struct policy_handle *handle)
3418 struct samr_EnumDomainGroups r;
3419 uint32_t resume_handle=0;
3423 printf("Testing EnumDomainGroups\n");
3425 r.in.domain_handle = handle;
3426 r.in.resume_handle = &resume_handle;
3427 r.in.max_size = (uint32_t)-1;
3428 r.out.resume_handle = &resume_handle;
3430 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3431 if (!NT_STATUS_IS_OK(status)) {
3432 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3440 for (i=0;i<r.out.sam->count;i++) {
3441 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3449 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3450 struct policy_handle *handle)
3453 struct samr_EnumDomainAliases r;
3454 uint32_t resume_handle=0;
3458 printf("Testing EnumDomainAliases\n");
3460 r.in.domain_handle = handle;
3461 r.in.resume_handle = &resume_handle;
3462 r.in.acct_flags = (uint32_t)-1;
3463 r.out.resume_handle = &resume_handle;
3465 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3466 if (!NT_STATUS_IS_OK(status)) {
3467 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3475 for (i=0;i<r.out.sam->count;i++) {
3476 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3484 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3485 struct policy_handle *handle)
3488 struct samr_GetDisplayEnumerationIndex r;
3490 uint16_t levels[] = {1, 2, 3, 4, 5};
3491 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3494 for (i=0;i<ARRAY_SIZE(levels);i++) {
3495 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3497 r.in.domain_handle = handle;
3498 r.in.level = levels[i];
3499 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3501 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3504 !NT_STATUS_IS_OK(status) &&
3505 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3506 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3507 levels[i], nt_errstr(status));
3511 init_lsa_String(&r.in.name, "zzzzzzzz");
3513 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3515 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3516 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3517 levels[i], nt_errstr(status));
3525 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3526 struct policy_handle *handle)
3529 struct samr_GetDisplayEnumerationIndex2 r;
3531 uint16_t levels[] = {1, 2, 3, 4, 5};
3532 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3535 for (i=0;i<ARRAY_SIZE(levels);i++) {
3536 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3538 r.in.domain_handle = handle;
3539 r.in.level = levels[i];
3540 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3542 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3544 !NT_STATUS_IS_OK(status) &&
3545 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3546 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3547 levels[i], nt_errstr(status));
3551 init_lsa_String(&r.in.name, "zzzzzzzz");
3553 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3554 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3555 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3556 levels[i], nt_errstr(status));
3564 #define STRING_EQUAL_QUERY(s1, s2, user) \
3565 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3566 /* odd, but valid */ \
3567 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3568 printf("%s mismatch for %s: %s != %s (%s)\n", \
3569 #s1, user.string, s1.string, s2.string, __location__); \
3572 #define INT_EQUAL_QUERY(s1, s2, user) \
3574 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3575 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3579 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3580 struct samr_QueryDisplayInfo *querydisplayinfo,
3581 bool *seen_testuser)
3583 struct samr_OpenUser r;
3584 struct samr_QueryUserInfo q;
3585 struct policy_handle user_handle;
3588 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3589 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3590 for (i = 0; ; i++) {
3591 switch (querydisplayinfo->in.level) {
3593 if (i >= querydisplayinfo->out.info.info1.count) {
3596 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3599 if (i >= querydisplayinfo->out.info.info2.count) {
3602 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3608 /* Not interested in validating just the account name */
3612 r.out.user_handle = &user_handle;
3614 switch (querydisplayinfo->in.level) {
3617 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3618 if (!NT_STATUS_IS_OK(status)) {
3619 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3624 q.in.user_handle = &user_handle;
3626 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3627 if (!NT_STATUS_IS_OK(status)) {
3628 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3632 switch (querydisplayinfo->in.level) {
3634 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3635 *seen_testuser = true;
3637 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3638 q.out.info->info21.full_name, q.out.info->info21.account_name);
3639 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3640 q.out.info->info21.account_name, q.out.info->info21.account_name);
3641 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3642 q.out.info->info21.description, q.out.info->info21.account_name);
3643 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3644 q.out.info->info21.rid, q.out.info->info21.account_name);
3645 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3646 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3650 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3651 q.out.info->info21.account_name, q.out.info->info21.account_name);
3652 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3653 q.out.info->info21.description, q.out.info->info21.account_name);
3654 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3655 q.out.info->info21.rid, q.out.info->info21.account_name);
3656 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3657 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3659 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3660 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3661 q.out.info->info21.account_name.string);
3664 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3665 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3666 q.out.info->info21.account_name.string,
3667 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3668 q.out.info->info21.acct_flags);
3675 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3682 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3683 struct policy_handle *handle)
3686 struct samr_QueryDisplayInfo r;
3687 struct samr_QueryDomainInfo dom_info;
3689 uint16_t levels[] = {1, 2, 3, 4, 5};
3691 bool seen_testuser = false;
3693 for (i=0;i<ARRAY_SIZE(levels);i++) {
3694 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3697 status = STATUS_MORE_ENTRIES;
3698 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3699 r.in.domain_handle = handle;
3700 r.in.level = levels[i];
3701 r.in.max_entries = 2;
3702 r.in.buf_size = (uint32_t)-1;
3704 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3705 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3706 printf("QueryDisplayInfo level %u failed - %s\n",
3707 levels[i], nt_errstr(status));
3710 switch (r.in.level) {
3712 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3715 r.in.start_idx += r.out.info.info1.count;
3718 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3721 r.in.start_idx += r.out.info.info2.count;
3724 r.in.start_idx += r.out.info.info3.count;
3727 r.in.start_idx += r.out.info.info4.count;
3730 r.in.start_idx += r.out.info.info5.count;
3734 dom_info.in.domain_handle = handle;
3735 dom_info.in.level = 2;
3736 /* Check number of users returned is correct */
3737 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3738 if (!NT_STATUS_IS_OK(status)) {
3739 printf("QueryDomainInfo level %u failed - %s\n",
3740 r.in.level, nt_errstr(status));
3744 switch (r.in.level) {
3747 if (dom_info.out.info->general.num_users < r.in.start_idx) {
3748 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3749 r.in.start_idx, dom_info.out.info->general.num_groups,
3750 dom_info.out.info->general.domain_name.string);
3753 if (!seen_testuser) {
3754 struct policy_handle user_handle;
3755 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3756 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3757 dom_info.out.info->general.domain_name.string);
3759 test_samr_handle_Close(p, mem_ctx, &user_handle);
3765 if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3766 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3767 r.in.start_idx, dom_info.out.info->general.num_groups,
3768 dom_info.out.info->general.domain_name.string);
3780 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3781 struct policy_handle *handle)
3784 struct samr_QueryDisplayInfo2 r;
3786 uint16_t levels[] = {1, 2, 3, 4, 5};
3789 for (i=0;i<ARRAY_SIZE(levels);i++) {
3790 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3792 r.in.domain_handle = handle;
3793 r.in.level = levels[i];
3795 r.in.max_entries = 1000;
3796 r.in.buf_size = (uint32_t)-1;
3798 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3799 if (!NT_STATUS_IS_OK(status)) {
3800 printf("QueryDisplayInfo2 level %u failed - %s\n",
3801 levels[i], nt_errstr(status));
3809 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3810 struct policy_handle *handle)
3813 struct samr_QueryDisplayInfo3 r;
3815 uint16_t levels[] = {1, 2, 3, 4, 5};
3818 for (i=0;i<ARRAY_SIZE(levels);i++) {
3819 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3821 r.in.domain_handle = handle;
3822 r.in.level = levels[i];
3824 r.in.max_entries = 1000;
3825 r.in.buf_size = (uint32_t)-1;
3827 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3828 if (!NT_STATUS_IS_OK(status)) {
3829 printf("QueryDisplayInfo3 level %u failed - %s\n",
3830 levels[i], nt_errstr(status));
3839 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3840 struct policy_handle *handle)
3843 struct samr_QueryDisplayInfo r;
3846 printf("Testing QueryDisplayInfo continuation\n");
3848 r.in.domain_handle = handle;
3851 r.in.max_entries = 1;
3852 r.in.buf_size = (uint32_t)-1;
3855 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3856 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3857 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3858 printf("expected idx %d but got %d\n",
3860 r.out.info.info1.entries[0].idx);
3864 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3865 !NT_STATUS_IS_OK(status)) {
3866 printf("QueryDisplayInfo level %u failed - %s\n",
3867 r.in.level, nt_errstr(status));
3872 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3873 NT_STATUS_IS_OK(status)) &&
3874 r.out.returned_size != 0);
3879 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3880 struct policy_handle *handle)
3883 struct samr_QueryDomainInfo r;
3884 struct samr_SetDomainInfo s;
3885 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3886 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3889 const char *domain_comment = talloc_asprintf(mem_ctx,
3890 "Tortured by Samba4 RPC-SAMR: %s",
3891 timestring(mem_ctx, time(NULL)));
3893 s.in.domain_handle = handle;
3895 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3897 s.in.info->oem.oem_information.string = domain_comment;
3898 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3899 if (!NT_STATUS_IS_OK(status)) {
3900 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3901 r.in.level, nt_errstr(status));
3905 for (i=0;i<ARRAY_SIZE(levels);i++) {
3906 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3908 r.in.domain_handle = handle;
3909 r.in.level = levels[i];
3911 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3912 if (!NT_STATUS_IS_OK(status)) {
3913 printf("QueryDomainInfo level %u failed - %s\n",
3914 r.in.level, nt_errstr(status));
3919 switch (levels[i]) {
3921 if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3922 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3923 levels[i], r.out.info->general.oem_information.string, domain_comment);
3926 if (!r.out.info->general.primary.string) {
3927 printf("QueryDomainInfo level %u returned no PDC name\n",
3930 } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3931 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3932 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3933 levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3938 if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3939 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3940 levels[i], r.out.info->oem.oem_information.string, domain_comment);
3945 if (!r.out.info->info6.primary.string) {
3946 printf("QueryDomainInfo level %u returned no PDC name\n",
3952 if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3953 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3954 levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3960 printf("Testing SetDomainInfo level %u\n", levels[i]);
3962 s.in.domain_handle = handle;
3963 s.in.level = levels[i];
3964 s.in.info = r.out.info;
3966 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3968 if (!NT_STATUS_IS_OK(status)) {
3969 printf("SetDomainInfo level %u failed - %s\n",
3970 r.in.level, nt_errstr(status));
3975 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3976 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3977 r.in.level, nt_errstr(status));
3983 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3984 if (!NT_STATUS_IS_OK(status)) {
3985 printf("QueryDomainInfo level %u failed - %s\n",
3986 r.in.level, nt_errstr(status));
3996 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3997 struct policy_handle *handle)
4000 struct samr_QueryDomainInfo2 r;
4001 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4005 for (i=0;i<ARRAY_SIZE(levels);i++) {
4006 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4008 r.in.domain_handle = handle;
4009 r.in.level = levels[i];
4011 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
4012 if (!NT_STATUS_IS_OK(status)) {
4013 printf("QueryDomainInfo2 level %u failed - %s\n",
4014 r.in.level, nt_errstr(status));
4023 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4024 set of group names. */
4025 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
4026 struct policy_handle *handle)
4028 struct samr_EnumDomainGroups q1;
4029 struct samr_QueryDisplayInfo q2;
4031 uint32_t resume_handle=0;
4036 const char **names = NULL;
4038 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
4040 q1.in.domain_handle = handle;
4041 q1.in.resume_handle = &resume_handle;
4043 q1.out.resume_handle = &resume_handle;
4045 status = STATUS_MORE_ENTRIES;
4046 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4047 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
4049 if (!NT_STATUS_IS_OK(status) &&
4050 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4053 for (i=0; i<q1.out.num_entries; i++) {
4054 add_string_to_array(tctx,
4055 q1.out.sam->entries[i].name.string,
4056 &names, &num_names);
4060 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
4063 printf("EnumDomainGroups failed to return q1.out.sam\n");
4067 q2.in.domain_handle = handle;
4069 q2.in.start_idx = 0;
4070 q2.in.max_entries = 5;
4071 q2.in.buf_size = (uint32_t)-1;
4073 status = STATUS_MORE_ENTRIES;
4074 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4075 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
4077 if (!NT_STATUS_IS_OK(status) &&
4078 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4081 for (i=0; i<q2.out.info.info5.count; i++) {
4083 const char *name = q2.out.info.info5.entries[i].account_name.string;
4085 for (j=0; j<num_names; j++) {
4086 if (names[j] == NULL)
4088 if (strequal(names[j], name)) {
4096 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4101 q2.in.start_idx += q2.out.info.info5.count;
4104 if (!NT_STATUS_IS_OK(status)) {
4105 printf("QueryDisplayInfo level 5 failed - %s\n",
4110 for (i=0; i<num_names; i++) {
4111 if (names[i] != NULL) {
4112 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4121 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
4122 struct policy_handle *group_handle)
4124 struct samr_DeleteDomainGroup d;
4128 printf("Testing DeleteDomainGroup\n");
4130 d.in.group_handle = group_handle;
4131 d.out.group_handle = group_handle;
4133 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
4134 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
4139 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4140 struct policy_handle *domain_handle)
4142 struct samr_TestPrivateFunctionsDomain r;
4146 printf("Testing TestPrivateFunctionsDomain\n");
4148 r.in.domain_handle = domain_handle;
4150 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
4151 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
4156 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4157 struct dom_sid *domain_sid,
4158 struct policy_handle *domain_handle)
4160 struct samr_RidToSid r;
4163 struct dom_sid *calc_sid;
4164 int rids[] = { 0, 42, 512, 10200 };
4167 for (i=0;i<ARRAY_SIZE(rids);i++) {
4169 printf("Testing RidToSid\n");
4171 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
4172 r.in.domain_handle = domain_handle;
4175 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
4176 if (!NT_STATUS_IS_OK(status)) {
4177 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4180 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4182 if (!dom_sid_equal(calc_sid, r.out.sid)) {
4183 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4184 dom_sid_string(mem_ctx, r.out.sid),
4185 dom_sid_string(mem_ctx, calc_sid));
4194 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4195 struct policy_handle *domain_handle)
4197 struct samr_GetBootKeyInformation r;
4201 printf("Testing GetBootKeyInformation\n");
4203 r.in.domain_handle = domain_handle;
4205 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4206 if (!NT_STATUS_IS_OK(status)) {
4207 /* w2k3 seems to fail this sometimes and pass it sometimes */
4208 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4214 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4215 struct policy_handle *domain_handle,
4216 struct policy_handle *group_handle)
4219 struct samr_AddGroupMember r;
4220 struct samr_DeleteGroupMember d;
4221 struct samr_QueryGroupMember q;
4222 struct samr_SetMemberAttributesOfGroup s;
4226 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4227 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
4229 r.in.group_handle = group_handle;
4231 r.in.flags = 0; /* ??? */
4233 printf("Testing AddGroupMember and DeleteGroupMember\n");
4235 d.in.group_handle = group_handle;
4238 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4239 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
4241 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4242 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4244 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4245 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
4247 if (torture_setting_bool(tctx, "samba4", false)) {
4248 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
4250 /* this one is quite strange. I am using random inputs in the
4251 hope of triggering an error that might give us a clue */
4253 s.in.group_handle = group_handle;
4254 s.in.unknown1 = random();
4255 s.in.unknown2 = random();
4257 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4258 if (!NT_STATUS_IS_OK(status)) {
4259 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4264 q.in.group_handle = group_handle;
4266 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4267 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
4269 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4270 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
4272 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4273 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
4279 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
4280 struct torture_context *tctx,
4281 struct policy_handle *domain_handle,
4282 struct policy_handle *group_handle,
4283 struct dom_sid *domain_sid)
4286 struct samr_CreateDomainGroup r;
4288 struct lsa_String name;
4291 init_lsa_String(&name, TEST_GROUPNAME);
4293 r.in.domain_handle = domain_handle;
4295 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4296 r.out.group_handle = group_handle;
4299 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4301 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4303 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4304 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4305 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
4308 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4314 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4315 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
4316 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4320 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4322 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4323 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
4325 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4329 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
4331 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
4333 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
4334 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4338 if (!test_SetGroupInfo(p, tctx, group_handle)) {
4347 its not totally clear what this does. It seems to accept any sid you like.
4349 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4350 struct torture_context *tctx,
4351 struct policy_handle *domain_handle)
4354 struct samr_RemoveMemberFromForeignDomain r;
4356 r.in.domain_handle = domain_handle;
4357 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
4359 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
4360 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
4367 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4368 struct policy_handle *handle);
4370 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4371 struct policy_handle *handle, struct dom_sid *sid,
4372 enum torture_samr_choice which_ops)
4375 struct samr_OpenDomain r;
4376 struct policy_handle domain_handle;
4377 struct policy_handle alias_handle;
4378 struct policy_handle user_handle;
4379 struct policy_handle group_handle;
4382 ZERO_STRUCT(alias_handle);
4383 ZERO_STRUCT(user_handle);
4384 ZERO_STRUCT(group_handle);
4385 ZERO_STRUCT(domain_handle);
4387 printf("Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4389 r.in.connect_handle = handle;
4390 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4392 r.out.domain_handle = &domain_handle;
4394 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4395 if (!NT_STATUS_IS_OK(status)) {
4396 printf("OpenDomain failed - %s\n", nt_errstr(status));
4400 /* run the domain tests with the main handle closed - this tests
4401 the servers reference counting */
4402 ret &= test_samr_handle_Close(p, tctx, handle);
4404 switch (which_ops) {
4405 case TORTURE_SAMR_USER_ATTRIBUTES:
4406 case TORTURE_SAMR_PASSWORDS:
4407 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4408 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4409 /* This test needs 'complex' users to validate */
4410 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4412 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4415 case TORTURE_SAMR_OTHER:
4416 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4418 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4420 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4421 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4422 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4423 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4424 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4425 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4426 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4427 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4428 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4429 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4430 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4431 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4432 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4434 if (torture_setting_bool(tctx, "samba4", false)) {
4435 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4437 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4438 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4440 ret &= test_GroupList(p, tctx, &domain_handle);
4441 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4442 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4443 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4445 printf("Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4450 if (!policy_handle_empty(&user_handle) &&
4451 !test_DeleteUser(p, tctx, &user_handle)) {
4455 if (!policy_handle_empty(&alias_handle) &&
4456 !test_DeleteAlias(p, tctx, &alias_handle)) {
4460 if (!policy_handle_empty(&group_handle) &&
4461 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4465 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4467 /* reconnect the main handle */
4468 ret &= test_Connect(p, tctx, handle);
4471 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4477 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4478 struct policy_handle *handle, const char *domain,
4479 enum torture_samr_choice which_ops)
4482 struct samr_LookupDomain r;
4483 struct lsa_String n1;
4484 struct lsa_String n2;
4487 printf("Testing LookupDomain(%s)\n", domain);
4489 /* check for correct error codes */
4490 r.in.connect_handle = handle;
4491 r.in.domain_name = &n2;
4494 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4495 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4496 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4500 init_lsa_String(&n2, "xxNODOMAINxx");
4502 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4503 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4504 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4508 r.in.connect_handle = handle;
4510 init_lsa_String(&n1, domain);
4511 r.in.domain_name = &n1;
4513 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4514 if (!NT_STATUS_IS_OK(status)) {
4515 printf("LookupDomain failed - %s\n", nt_errstr(status));
4519 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4523 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4531 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4532 struct policy_handle *handle, enum torture_samr_choice which_ops)
4535 struct samr_EnumDomains r;
4536 uint32_t resume_handle = 0;
4540 r.in.connect_handle = handle;
4541 r.in.resume_handle = &resume_handle;
4542 r.in.buf_size = (uint32_t)-1;
4543 r.out.resume_handle = &resume_handle;
4545 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4546 if (!NT_STATUS_IS_OK(status)) {
4547 printf("EnumDomains failed - %s\n", nt_errstr(status));
4555 for (i=0;i<r.out.sam->count;i++) {
4556 if (!test_LookupDomain(p, tctx, handle,
4557 r.out.sam->entries[i].name.string, which_ops)) {
4562 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4563 if (!NT_STATUS_IS_OK(status)) {
4564 printf("EnumDomains failed - %s\n", nt_errstr(status));
4572 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4573 struct policy_handle *handle)
4576 struct samr_Connect r;
4577 struct samr_Connect2 r2;
4578 struct samr_Connect3 r3;
4579 struct samr_Connect4 r4;
4580 struct samr_Connect5 r5;
4581 union samr_ConnectInfo info;
4582 struct policy_handle h;
4583 bool ret = true, got_handle = false;
4585 printf("testing samr_Connect\n");
4587 r.in.system_name = 0;
4588 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4589 r.out.connect_handle = &h;
4591 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4592 if (!NT_STATUS_IS_OK(status)) {
4593 printf("Connect failed - %s\n", nt_errstr(status));
4600 printf("testing samr_Connect2\n");
4602 r2.in.system_name = NULL;
4603 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4604 r2.out.connect_handle = &h;
4606 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4607 if (!NT_STATUS_IS_OK(status)) {
4608 printf("Connect2 failed - %s\n", nt_errstr(status));
4612 test_samr_handle_Close(p, mem_ctx, handle);
4618 printf("testing samr_Connect3\n");
4620 r3.in.system_name = NULL;
4622 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4623 r3.out.connect_handle = &h;
4625 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4626 if (!NT_STATUS_IS_OK(status)) {
4627 printf("Connect3 failed - %s\n", nt_errstr(status));
4631 test_samr_handle_Close(p, mem_ctx, handle);
4637 printf("testing samr_Connect4\n");
4639 r4.in.system_name = "";
4640 r4.in.client_version = 0;
4641 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4642 r4.out.connect_handle = &h;
4644 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4645 if (!NT_STATUS_IS_OK(status)) {
4646 printf("Connect4 failed - %s\n", nt_errstr(status));
4650 test_samr_handle_Close(p, mem_ctx, handle);
4656 printf("testing samr_Connect5\n");
4658 info.info1.client_version = 0;
4659 info.info1.unknown2 = 0;
4661 r5.in.system_name = "";
4662 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4665 r5.out.info = &info;
4666 r5.out.connect_handle = &h;
4668 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4669 if (!NT_STATUS_IS_OK(status)) {
4670 printf("Connect5 failed - %s\n", nt_errstr(status));
4674 test_samr_handle_Close(p, mem_ctx, handle);
4684 bool torture_rpc_samr(struct torture_context *torture)
4687 struct dcerpc_pipe *p;
4689 struct policy_handle handle;
4691 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4692 if (!NT_STATUS_IS_OK(status)) {
4696 ret &= test_Connect(p, torture, &handle);
4698 ret &= test_QuerySecurity(p, torture, &handle);
4700 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4702 ret &= test_SetDsrmPassword(p, torture, &handle);
4704 ret &= test_Shutdown(p, torture, &handle);
4706 ret &= test_samr_handle_Close(p, torture, &handle);
4712 bool torture_rpc_samr_users(struct torture_context *torture)
4715 struct dcerpc_pipe *p;
4717 struct policy_handle handle;
4719 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4720 if (!NT_STATUS_IS_OK(status)) {
4724 ret &= test_Connect(p, torture, &handle);
4726 ret &= test_QuerySecurity(p, torture, &handle);
4728 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4730 ret &= test_SetDsrmPassword(p, torture, &handle);
4732 ret &= test_Shutdown(p, torture, &handle);
4734 ret &= test_samr_handle_Close(p, torture, &handle);
4740 bool torture_rpc_samr_passwords(struct torture_context *torture)
4743 struct dcerpc_pipe *p;
4745 struct policy_handle handle;
4747 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4748 if (!NT_STATUS_IS_OK(status)) {
4752 ret &= test_Connect(p, torture, &handle);
4754 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4756 ret &= test_samr_handle_Close(p, torture, &handle);