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, TALLOC_CTX *mem_ctx,
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, mem_ctx, &pwp);
541 if (NT_STATUS_IS_OK(status)) {
542 policy_min_pw_len = pwp.out.info.min_password_length;
544 newpass = samr_rand_pass(mem_ctx, 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 printf("Testing SetUserInfo level 24 (set password)\n");
565 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &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, TALLOC_CTX *mem_ctx,
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, mem_ctx, &pwp);
593 if (NT_STATUS_IS_OK(status)) {
594 policy_min_pw_len = pwp.out.info.min_password_length;
596 newpass = samr_rand_pass(mem_ctx, 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 printf("Testing SetUserInfo level 23 (set password)\n");
619 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &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 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
643 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &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, TALLOC_CTX *mem_ctx,
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(mem_ctx, 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, mem_ctx, &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(mem_ctx, policy_min_pw_len - 1);
678 newpass = samr_rand_pass(mem_ctx, 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, mem_ctx, &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 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
724 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &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;
870 printf("testing GetGroupsForUser\n");
872 r.in.user_handle = user_handle;
874 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
875 if (!NT_STATUS_IS_OK(status)) {
876 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
884 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
885 struct lsa_String *domain_name)
888 struct samr_GetDomPwInfo r;
891 r.in.domain_name = domain_name;
892 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
894 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
895 if (!NT_STATUS_IS_OK(status)) {
896 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
900 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
901 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
903 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
904 if (!NT_STATUS_IS_OK(status)) {
905 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
909 r.in.domain_name->string = "\\\\__NONAME__";
910 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
912 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
913 if (!NT_STATUS_IS_OK(status)) {
914 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
918 r.in.domain_name->string = "\\\\Builtin";
919 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
921 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
922 if (!NT_STATUS_IS_OK(status)) {
923 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
931 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
932 struct policy_handle *handle)
935 struct samr_GetUserPwInfo r;
938 printf("Testing GetUserPwInfo\n");
940 r.in.user_handle = handle;
942 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
943 if (!NT_STATUS_IS_OK(status)) {
944 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
951 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
952 struct policy_handle *domain_handle, const char *name,
956 struct samr_LookupNames n;
957 struct lsa_String sname[2];
959 init_lsa_String(&sname[0], name);
961 n.in.domain_handle = domain_handle;
964 status = dcerpc_samr_LookupNames(p, tctx, &n);
965 if (NT_STATUS_IS_OK(status)) {
966 *rid = n.out.rids.ids[0];
971 init_lsa_String(&sname[1], "xxNONAMExx");
973 status = dcerpc_samr_LookupNames(p, tctx, &n);
974 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
975 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
976 if (NT_STATUS_IS_OK(status)) {
977 return NT_STATUS_UNSUCCESSFUL;
983 status = dcerpc_samr_LookupNames(p, tctx, &n);
984 if (!NT_STATUS_IS_OK(status)) {
985 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
989 init_lsa_String(&sname[0], "xxNONAMExx");
991 status = dcerpc_samr_LookupNames(p, tctx, &n);
992 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
993 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
994 if (NT_STATUS_IS_OK(status)) {
995 return NT_STATUS_UNSUCCESSFUL;
1000 init_lsa_String(&sname[0], "xxNONAMExx");
1001 init_lsa_String(&sname[1], "xxNONAME2xx");
1003 status = dcerpc_samr_LookupNames(p, tctx, &n);
1004 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1005 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1006 if (NT_STATUS_IS_OK(status)) {
1007 return NT_STATUS_UNSUCCESSFUL;
1012 return NT_STATUS_OK;
1015 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1016 struct policy_handle *domain_handle,
1017 const char *name, struct policy_handle *user_handle)
1020 struct samr_OpenUser r;
1023 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1024 if (!NT_STATUS_IS_OK(status)) {
1028 r.in.domain_handle = domain_handle;
1029 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1031 r.out.user_handle = user_handle;
1032 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1033 if (!NT_STATUS_IS_OK(status)) {
1034 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1041 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1042 struct policy_handle *handle)
1045 struct samr_ChangePasswordUser r;
1047 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1048 struct policy_handle user_handle;
1049 char *oldpass = "test";
1050 char *newpass = "test2";
1051 uint8_t old_nt_hash[16], new_nt_hash[16];
1052 uint8_t old_lm_hash[16], new_lm_hash[16];
1054 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1055 if (!NT_STATUS_IS_OK(status)) {
1059 printf("Testing ChangePasswordUser for user 'testuser'\n");
1061 printf("old password: %s\n", oldpass);
1062 printf("new password: %s\n", newpass);
1064 E_md4hash(oldpass, old_nt_hash);
1065 E_md4hash(newpass, new_nt_hash);
1066 E_deshash(oldpass, old_lm_hash);
1067 E_deshash(newpass, new_lm_hash);
1069 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1070 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1071 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1072 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1073 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1074 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1076 r.in.handle = &user_handle;
1077 r.in.lm_present = 1;
1078 r.in.old_lm_crypted = &hash1;
1079 r.in.new_lm_crypted = &hash2;
1080 r.in.nt_present = 1;
1081 r.in.old_nt_crypted = &hash3;
1082 r.in.new_nt_crypted = &hash4;
1083 r.in.cross1_present = 1;
1084 r.in.nt_cross = &hash5;
1085 r.in.cross2_present = 1;
1086 r.in.lm_cross = &hash6;
1088 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1094 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1102 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1103 const char *acct_name,
1104 struct policy_handle *handle, char **password)
1107 struct samr_ChangePasswordUser r;
1109 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1110 struct policy_handle user_handle;
1112 uint8_t old_nt_hash[16], new_nt_hash[16];
1113 uint8_t old_lm_hash[16], new_lm_hash[16];
1114 bool changed = true;
1117 struct samr_GetUserPwInfo pwp;
1118 int policy_min_pw_len = 0;
1120 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1121 if (!NT_STATUS_IS_OK(status)) {
1124 pwp.in.user_handle = &user_handle;
1126 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1127 if (NT_STATUS_IS_OK(status)) {
1128 policy_min_pw_len = pwp.out.info.min_password_length;
1130 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1132 printf("Testing ChangePasswordUser\n");
1135 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1139 oldpass = *password;
1141 E_md4hash(oldpass, old_nt_hash);
1142 E_md4hash(newpass, new_nt_hash);
1143 E_deshash(oldpass, old_lm_hash);
1144 E_deshash(newpass, new_lm_hash);
1146 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1147 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1148 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1149 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1150 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1151 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1153 r.in.user_handle = &user_handle;
1154 r.in.lm_present = 1;
1155 /* Break the LM hash */
1157 r.in.old_lm_crypted = &hash1;
1158 r.in.new_lm_crypted = &hash2;
1159 r.in.nt_present = 1;
1160 r.in.old_nt_crypted = &hash3;
1161 r.in.new_nt_crypted = &hash4;
1162 r.in.cross1_present = 1;
1163 r.in.nt_cross = &hash5;
1164 r.in.cross2_present = 1;
1165 r.in.lm_cross = &hash6;
1167 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1168 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1169 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1173 /* Unbreak the LM hash */
1176 r.in.user_handle = &user_handle;
1177 r.in.lm_present = 1;
1178 r.in.old_lm_crypted = &hash1;
1179 r.in.new_lm_crypted = &hash2;
1180 /* Break the NT hash */
1182 r.in.nt_present = 1;
1183 r.in.old_nt_crypted = &hash3;
1184 r.in.new_nt_crypted = &hash4;
1185 r.in.cross1_present = 1;
1186 r.in.nt_cross = &hash5;
1187 r.in.cross2_present = 1;
1188 r.in.lm_cross = &hash6;
1190 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1191 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1192 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1196 /* Unbreak the NT hash */
1199 r.in.user_handle = &user_handle;
1200 r.in.lm_present = 1;
1201 r.in.old_lm_crypted = &hash1;
1202 r.in.new_lm_crypted = &hash2;
1203 r.in.nt_present = 1;
1204 r.in.old_nt_crypted = &hash3;
1205 r.in.new_nt_crypted = &hash4;
1206 r.in.cross1_present = 1;
1207 r.in.nt_cross = &hash5;
1208 r.in.cross2_present = 1;
1209 /* Break the LM cross */
1211 r.in.lm_cross = &hash6;
1213 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1214 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1215 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1219 /* Unbreak the LM cross */
1222 r.in.user_handle = &user_handle;
1223 r.in.lm_present = 1;
1224 r.in.old_lm_crypted = &hash1;
1225 r.in.new_lm_crypted = &hash2;
1226 r.in.nt_present = 1;
1227 r.in.old_nt_crypted = &hash3;
1228 r.in.new_nt_crypted = &hash4;
1229 r.in.cross1_present = 1;
1230 /* Break the NT cross */
1232 r.in.nt_cross = &hash5;
1233 r.in.cross2_present = 1;
1234 r.in.lm_cross = &hash6;
1236 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1237 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1238 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1242 /* Unbreak the NT cross */
1246 /* Reset the hashes to not broken values */
1247 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1248 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1249 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1250 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1251 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1252 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1254 r.in.user_handle = &user_handle;
1255 r.in.lm_present = 1;
1256 r.in.old_lm_crypted = &hash1;
1257 r.in.new_lm_crypted = &hash2;
1258 r.in.nt_present = 1;
1259 r.in.old_nt_crypted = &hash3;
1260 r.in.new_nt_crypted = &hash4;
1261 r.in.cross1_present = 1;
1262 r.in.nt_cross = &hash5;
1263 r.in.cross2_present = 0;
1264 r.in.lm_cross = NULL;
1266 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1267 if (NT_STATUS_IS_OK(status)) {
1269 *password = newpass;
1270 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1271 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1276 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1278 E_md4hash(oldpass, old_nt_hash);
1279 E_md4hash(newpass, new_nt_hash);
1280 E_deshash(oldpass, old_lm_hash);
1281 E_deshash(newpass, new_lm_hash);
1284 /* Reset the hashes to not broken values */
1285 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1286 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1287 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1288 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1289 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1290 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1292 r.in.user_handle = &user_handle;
1293 r.in.lm_present = 1;
1294 r.in.old_lm_crypted = &hash1;
1295 r.in.new_lm_crypted = &hash2;
1296 r.in.nt_present = 1;
1297 r.in.old_nt_crypted = &hash3;
1298 r.in.new_nt_crypted = &hash4;
1299 r.in.cross1_present = 0;
1300 r.in.nt_cross = NULL;
1301 r.in.cross2_present = 1;
1302 r.in.lm_cross = &hash6;
1304 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1305 if (NT_STATUS_IS_OK(status)) {
1307 *password = newpass;
1308 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1309 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1314 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1316 E_md4hash(oldpass, old_nt_hash);
1317 E_md4hash(newpass, new_nt_hash);
1318 E_deshash(oldpass, old_lm_hash);
1319 E_deshash(newpass, new_lm_hash);
1322 /* Reset the hashes to not broken values */
1323 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1324 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1325 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1326 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1327 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1328 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1330 r.in.user_handle = &user_handle;
1331 r.in.lm_present = 1;
1332 r.in.old_lm_crypted = &hash1;
1333 r.in.new_lm_crypted = &hash2;
1334 r.in.nt_present = 1;
1335 r.in.old_nt_crypted = &hash3;
1336 r.in.new_nt_crypted = &hash4;
1337 r.in.cross1_present = 1;
1338 r.in.nt_cross = &hash5;
1339 r.in.cross2_present = 1;
1340 r.in.lm_cross = &hash6;
1342 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1343 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1344 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1345 } else if (!NT_STATUS_IS_OK(status)) {
1346 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1350 *password = newpass;
1353 r.in.user_handle = &user_handle;
1354 r.in.lm_present = 1;
1355 r.in.old_lm_crypted = &hash1;
1356 r.in.new_lm_crypted = &hash2;
1357 r.in.nt_present = 1;
1358 r.in.old_nt_crypted = &hash3;
1359 r.in.new_nt_crypted = &hash4;
1360 r.in.cross1_present = 1;
1361 r.in.nt_cross = &hash5;
1362 r.in.cross2_present = 1;
1363 r.in.lm_cross = &hash6;
1366 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1367 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1368 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1369 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1370 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1376 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1384 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1385 const char *acct_name,
1386 struct policy_handle *handle, char **password)
1389 struct samr_OemChangePasswordUser2 r;
1391 struct samr_Password lm_verifier;
1392 struct samr_CryptPassword lm_pass;
1393 struct lsa_AsciiString server, account, account_bad;
1396 uint8_t old_lm_hash[16], new_lm_hash[16];
1398 struct samr_GetDomPwInfo dom_pw_info;
1399 int policy_min_pw_len = 0;
1401 struct lsa_String domain_name;
1403 domain_name.string = "";
1404 dom_pw_info.in.domain_name = &domain_name;
1406 printf("Testing OemChangePasswordUser2\n");
1409 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1413 oldpass = *password;
1415 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1416 if (NT_STATUS_IS_OK(status)) {
1417 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1420 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1422 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1423 account.string = acct_name;
1425 E_deshash(oldpass, old_lm_hash);
1426 E_deshash(newpass, new_lm_hash);
1428 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1429 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1430 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1432 r.in.server = &server;
1433 r.in.account = &account;
1434 r.in.password = &lm_pass;
1435 r.in.hash = &lm_verifier;
1437 /* Break the verification */
1438 lm_verifier.hash[0]++;
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 invalid password verifier - %s\n",
1449 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1450 /* Break the old password */
1452 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1453 /* unbreak it for the next operation */
1455 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1457 r.in.server = &server;
1458 r.in.account = &account;
1459 r.in.password = &lm_pass;
1460 r.in.hash = &lm_verifier;
1462 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1464 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1465 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1466 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1471 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1472 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1474 r.in.server = &server;
1475 r.in.account = &account;
1476 r.in.password = &lm_pass;
1479 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1481 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1482 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1483 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1488 /* This shouldn't be a valid name */
1489 account_bad.string = TEST_ACCOUNT_NAME "XX";
1490 r.in.account = &account_bad;
1492 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1494 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1495 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1500 /* This shouldn't be a valid name */
1501 account_bad.string = TEST_ACCOUNT_NAME "XX";
1502 r.in.account = &account_bad;
1503 r.in.password = &lm_pass;
1504 r.in.hash = &lm_verifier;
1506 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1508 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1509 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1514 /* This shouldn't be a valid name */
1515 account_bad.string = TEST_ACCOUNT_NAME "XX";
1516 r.in.account = &account_bad;
1517 r.in.password = NULL;
1518 r.in.hash = &lm_verifier;
1520 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1522 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1523 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1528 E_deshash(oldpass, old_lm_hash);
1529 E_deshash(newpass, new_lm_hash);
1531 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1532 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1533 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1535 r.in.server = &server;
1536 r.in.account = &account;
1537 r.in.password = &lm_pass;
1538 r.in.hash = &lm_verifier;
1540 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1541 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1542 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1543 } else if (!NT_STATUS_IS_OK(status)) {
1544 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1547 *password = newpass;
1554 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1555 const char *acct_name,
1557 char *newpass, bool allow_password_restriction)
1560 struct samr_ChangePasswordUser2 r;
1562 struct lsa_String server, account;
1563 struct samr_CryptPassword nt_pass, lm_pass;
1564 struct samr_Password nt_verifier, lm_verifier;
1566 uint8_t old_nt_hash[16], new_nt_hash[16];
1567 uint8_t old_lm_hash[16], new_lm_hash[16];
1569 struct samr_GetDomPwInfo dom_pw_info;
1571 struct lsa_String domain_name;
1573 domain_name.string = "";
1574 dom_pw_info.in.domain_name = &domain_name;
1576 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1579 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1582 oldpass = *password;
1585 int policy_min_pw_len = 0;
1586 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1587 if (NT_STATUS_IS_OK(status)) {
1588 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1591 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1594 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1595 init_lsa_String(&account, acct_name);
1597 E_md4hash(oldpass, old_nt_hash);
1598 E_md4hash(newpass, new_nt_hash);
1600 E_deshash(oldpass, old_lm_hash);
1601 E_deshash(newpass, new_lm_hash);
1603 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1604 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1605 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1607 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1608 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1609 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1611 r.in.server = &server;
1612 r.in.account = &account;
1613 r.in.nt_password = &nt_pass;
1614 r.in.nt_verifier = &nt_verifier;
1616 r.in.lm_password = &lm_pass;
1617 r.in.lm_verifier = &lm_verifier;
1619 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1620 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1621 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1622 } else if (!NT_STATUS_IS_OK(status)) {
1623 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1626 *password = newpass;
1633 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1634 const char *account_string,
1635 int policy_min_pw_len,
1637 const char *newpass,
1638 NTTIME last_password_change,
1639 bool handle_reject_reason)
1642 struct samr_ChangePasswordUser3 r;
1644 struct lsa_String server, account, account_bad;
1645 struct samr_CryptPassword nt_pass, lm_pass;
1646 struct samr_Password nt_verifier, lm_verifier;
1648 uint8_t old_nt_hash[16], new_nt_hash[16];
1649 uint8_t old_lm_hash[16], new_lm_hash[16];
1652 printf("Testing ChangePasswordUser3\n");
1654 if (newpass == NULL) {
1656 if (policy_min_pw_len == 0) {
1657 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1659 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1661 } while (check_password_quality(newpass) == false);
1663 printf("Using password '%s'\n", newpass);
1667 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1671 oldpass = *password;
1672 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1673 init_lsa_String(&account, account_string);
1675 E_md4hash(oldpass, old_nt_hash);
1676 E_md4hash(newpass, new_nt_hash);
1678 E_deshash(oldpass, old_lm_hash);
1679 E_deshash(newpass, new_lm_hash);
1681 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1682 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1683 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1685 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1686 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1687 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1689 /* Break the verification */
1690 nt_verifier.hash[0]++;
1692 r.in.server = &server;
1693 r.in.account = &account;
1694 r.in.nt_password = &nt_pass;
1695 r.in.nt_verifier = &nt_verifier;
1697 r.in.lm_password = &lm_pass;
1698 r.in.lm_verifier = &lm_verifier;
1699 r.in.password3 = NULL;
1701 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1702 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1703 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1704 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1709 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1710 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1711 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1713 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1714 /* Break the NT hash */
1716 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1717 /* Unbreak it again */
1719 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1721 r.in.server = &server;
1722 r.in.account = &account;
1723 r.in.nt_password = &nt_pass;
1724 r.in.nt_verifier = &nt_verifier;
1726 r.in.lm_password = &lm_pass;
1727 r.in.lm_verifier = &lm_verifier;
1728 r.in.password3 = NULL;
1730 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1731 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1732 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1733 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1738 /* This shouldn't be a valid name */
1739 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1741 r.in.account = &account_bad;
1742 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1743 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1744 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1749 E_md4hash(oldpass, old_nt_hash);
1750 E_md4hash(newpass, new_nt_hash);
1752 E_deshash(oldpass, old_lm_hash);
1753 E_deshash(newpass, new_lm_hash);
1755 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1756 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1757 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1759 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1760 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1761 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1763 r.in.server = &server;
1764 r.in.account = &account;
1765 r.in.nt_password = &nt_pass;
1766 r.in.nt_verifier = &nt_verifier;
1768 r.in.lm_password = &lm_pass;
1769 r.in.lm_verifier = &lm_verifier;
1770 r.in.password3 = NULL;
1772 unix_to_nt_time(&t, time(NULL));
1774 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1776 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1779 && handle_reject_reason
1780 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1781 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1783 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1784 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1785 SAMR_REJECT_OTHER, r.out.reject->reason);
1790 /* We tested the order of precendence which is as follows:
1799 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1800 (last_password_change + r.out.dominfo->min_password_age > t)) {
1802 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1803 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1804 SAMR_REJECT_OTHER, r.out.reject->reason);
1808 } else if ((r.out.dominfo->min_password_length > 0) &&
1809 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1811 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1812 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1813 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1817 } else if ((r.out.dominfo->password_history_length > 0) &&
1818 strequal(oldpass, newpass)) {
1820 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1821 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1822 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1825 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1827 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1828 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1829 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1835 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1836 /* retry with adjusted size */
1837 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1838 r.out.dominfo->min_password_length,
1839 password, NULL, 0, false);
1843 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1844 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1845 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1846 SAMR_REJECT_OTHER, r.out.reject->reason);
1849 /* Perhaps the server has a 'min password age' set? */
1851 } else if (!NT_STATUS_IS_OK(status)) {
1852 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1855 *password = talloc_strdup(mem_ctx, newpass);
1861 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1862 const char *account_string,
1863 struct policy_handle *handle,
1867 struct samr_ChangePasswordUser3 r;
1868 struct samr_SetUserInfo s;
1869 union samr_UserInfo u;
1870 DATA_BLOB session_key;
1871 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
1872 uint8_t confounder[16];
1873 struct MD5Context ctx;
1876 struct lsa_String server, account;
1877 struct samr_CryptPassword nt_pass;
1878 struct samr_Password nt_verifier;
1879 DATA_BLOB new_random_pass;
1882 uint8_t old_nt_hash[16], new_nt_hash[16];
1885 new_random_pass = samr_very_rand_pass(mem_ctx, 128);
1888 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1892 oldpass = *password;
1893 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1894 init_lsa_String(&account, account_string);
1896 s.in.user_handle = handle;
1902 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1904 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1906 status = dcerpc_fetch_session_key(p, &session_key);
1907 if (!NT_STATUS_IS_OK(status)) {
1908 printf("SetUserInfo level %u - no session key - %s\n",
1909 s.in.level, nt_errstr(status));
1913 generate_random_buffer((uint8_t *)confounder, 16);
1916 MD5Update(&ctx, confounder, 16);
1917 MD5Update(&ctx, session_key.data, session_key.length);
1918 MD5Final(confounded_session_key.data, &ctx);
1920 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1921 memcpy(&u.info25.password.data[516], confounder, 16);
1923 printf("Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1925 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
1926 if (!NT_STATUS_IS_OK(status)) {
1927 printf("SetUserInfo level %u failed - %s\n",
1928 s.in.level, nt_errstr(status));
1932 printf("Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1934 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1936 new_random_pass = samr_very_rand_pass(mem_ctx, 128);
1938 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1940 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1941 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1942 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1944 r.in.server = &server;
1945 r.in.account = &account;
1946 r.in.nt_password = &nt_pass;
1947 r.in.nt_verifier = &nt_verifier;
1949 r.in.lm_password = NULL;
1950 r.in.lm_verifier = NULL;
1951 r.in.password3 = NULL;
1953 unix_to_nt_time(&t, time(NULL));
1955 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1957 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1958 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1959 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1960 SAMR_REJECT_OTHER, r.out.reject->reason);
1963 /* Perhaps the server has a 'min password age' set? */
1965 } else if (!NT_STATUS_IS_OK(status)) {
1966 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1970 newpass = samr_rand_pass(mem_ctx, 128);
1972 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1974 E_md4hash(newpass, new_nt_hash);
1976 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1977 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1978 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1980 r.in.server = &server;
1981 r.in.account = &account;
1982 r.in.nt_password = &nt_pass;
1983 r.in.nt_verifier = &nt_verifier;
1985 r.in.lm_password = NULL;
1986 r.in.lm_verifier = NULL;
1987 r.in.password3 = NULL;
1989 unix_to_nt_time(&t, time(NULL));
1991 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1993 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1994 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1995 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1996 SAMR_REJECT_OTHER, r.out.reject->reason);
1999 /* Perhaps the server has a 'min password age' set? */
2001 } else if (!NT_STATUS_IS_OK(status)) {
2002 printf("ChangePasswordUser3 (on second random password) failed - %s\n", nt_errstr(status));
2005 *password = talloc_strdup(mem_ctx, newpass);
2012 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2013 struct policy_handle *alias_handle)
2015 struct samr_GetMembersInAlias r;
2016 struct lsa_SidArray sids;
2020 printf("Testing GetMembersInAlias\n");
2022 r.in.alias_handle = alias_handle;
2025 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
2026 if (!NT_STATUS_IS_OK(status)) {
2027 printf("GetMembersInAlias failed - %s\n",
2035 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2036 struct policy_handle *alias_handle,
2037 const struct dom_sid *domain_sid)
2039 struct samr_AddAliasMember r;
2040 struct samr_DeleteAliasMember d;
2043 struct dom_sid *sid;
2045 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
2047 printf("testing AddAliasMember\n");
2048 r.in.alias_handle = alias_handle;
2051 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
2052 if (!NT_STATUS_IS_OK(status)) {
2053 printf("AddAliasMember failed - %s\n", nt_errstr(status));
2057 d.in.alias_handle = alias_handle;
2060 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
2061 if (!NT_STATUS_IS_OK(status)) {
2062 printf("DelAliasMember failed - %s\n", nt_errstr(status));
2069 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2070 struct policy_handle *alias_handle)
2072 struct samr_AddMultipleMembersToAlias a;
2073 struct samr_RemoveMultipleMembersFromAlias r;
2076 struct lsa_SidArray sids;
2078 printf("testing AddMultipleMembersToAlias\n");
2079 a.in.alias_handle = alias_handle;
2083 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
2085 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
2086 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
2087 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
2089 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
2090 if (!NT_STATUS_IS_OK(status)) {
2091 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
2096 printf("testing RemoveMultipleMembersFromAlias\n");
2097 r.in.alias_handle = alias_handle;
2100 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2101 if (!NT_STATUS_IS_OK(status)) {
2102 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2106 /* strange! removing twice doesn't give any error */
2107 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2108 if (!NT_STATUS_IS_OK(status)) {
2109 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2113 /* but removing an alias that isn't there does */
2114 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
2116 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2117 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
2118 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2125 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2126 struct policy_handle *user_handle)
2128 struct samr_TestPrivateFunctionsUser r;
2132 printf("Testing TestPrivateFunctionsUser\n");
2134 r.in.user_handle = user_handle;
2136 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
2137 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2138 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
2146 static bool test_user_ops(struct dcerpc_pipe *p,
2147 struct torture_context *tctx,
2148 struct policy_handle *user_handle,
2149 struct policy_handle *domain_handle,
2150 uint32_t base_acct_flags,
2151 const char *base_acct_name, enum torture_samr_choice which_ops)
2153 char *password = NULL;
2154 struct samr_QueryUserInfo q;
2160 const uint32_t password_fields[] = {
2161 SAMR_FIELD_PASSWORD,
2162 SAMR_FIELD_PASSWORD2,
2163 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2167 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2168 if (!NT_STATUS_IS_OK(status)) {
2172 switch (which_ops) {
2173 case TORTURE_SAMR_USER_ATTRIBUTES:
2174 if (!test_QuerySecurity(p, tctx, user_handle)) {
2178 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2182 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2186 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2191 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2195 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2199 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2203 case TORTURE_SAMR_PASSWORDS:
2204 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2205 char simple_pass[9];
2206 char *v = generate_random_str(tctx, 1);
2208 ZERO_STRUCT(simple_pass);
2209 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2211 printf("Testing machine account password policy rules\n");
2213 /* Workstation trust accounts don't seem to need to honour password quality policy */
2214 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2218 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2222 /* reset again, to allow another 'user' password change */
2223 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2227 /* Try a 'short' password */
2228 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2232 /* Try a compleatly random password */
2233 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2238 for (i = 0; password_fields[i]; i++) {
2239 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2243 /* check it was set right */
2244 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2249 for (i = 0; password_fields[i]; i++) {
2250 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2254 /* check it was set right */
2255 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2260 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2264 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2268 q.in.user_handle = user_handle;
2271 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2272 if (!NT_STATUS_IS_OK(status)) {
2273 printf("QueryUserInfo level %u failed - %s\n",
2274 q.in.level, nt_errstr(status));
2277 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2278 if ((q.out.info->info5.acct_flags) != expected_flags) {
2279 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2280 q.out.info->info5.acct_flags,
2284 if (q.out.info->info5.rid != rid) {
2285 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2286 q.out.info->info5.rid, rid);
2292 case TORTURE_SAMR_OTHER:
2293 /* We just need the account to exist */
2299 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2300 struct policy_handle *alias_handle,
2301 const struct dom_sid *domain_sid)
2305 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2309 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2313 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2317 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2321 if (torture_setting_bool(tctx, "samba4", false)) {
2322 printf("skipping MultipleMembers Alias tests against Samba4\n");
2326 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2334 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2335 struct policy_handle *user_handle)
2337 struct samr_DeleteUser d;
2340 printf("Testing DeleteUser\n");
2342 d.in.user_handle = user_handle;
2343 d.out.user_handle = user_handle;
2345 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2346 if (!NT_STATUS_IS_OK(status)) {
2347 printf("DeleteUser failed - %s\n", nt_errstr(status));
2354 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2355 struct policy_handle *handle, const char *name)
2358 struct samr_DeleteUser d;
2359 struct policy_handle user_handle;
2362 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2363 if (!NT_STATUS_IS_OK(status)) {
2367 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2368 if (!NT_STATUS_IS_OK(status)) {
2372 d.in.user_handle = &user_handle;
2373 d.out.user_handle = &user_handle;
2374 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2375 if (!NT_STATUS_IS_OK(status)) {
2382 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2387 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2388 struct policy_handle *handle, const char *name)
2391 struct samr_OpenGroup r;
2392 struct samr_DeleteDomainGroup d;
2393 struct policy_handle group_handle;
2396 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2397 if (!NT_STATUS_IS_OK(status)) {
2401 r.in.domain_handle = handle;
2402 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2404 r.out.group_handle = &group_handle;
2405 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2406 if (!NT_STATUS_IS_OK(status)) {
2410 d.in.group_handle = &group_handle;
2411 d.out.group_handle = &group_handle;
2412 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2413 if (!NT_STATUS_IS_OK(status)) {
2420 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2425 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2426 struct policy_handle *domain_handle, const char *name)
2429 struct samr_OpenAlias r;
2430 struct samr_DeleteDomAlias d;
2431 struct policy_handle alias_handle;
2434 printf("testing DeleteAlias_byname\n");
2436 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2437 if (!NT_STATUS_IS_OK(status)) {
2441 r.in.domain_handle = domain_handle;
2442 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2444 r.out.alias_handle = &alias_handle;
2445 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2446 if (!NT_STATUS_IS_OK(status)) {
2450 d.in.alias_handle = &alias_handle;
2451 d.out.alias_handle = &alias_handle;
2452 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2453 if (!NT_STATUS_IS_OK(status)) {
2460 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2464 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2465 struct policy_handle *alias_handle)
2467 struct samr_DeleteDomAlias d;
2470 printf("Testing DeleteAlias\n");
2472 d.in.alias_handle = alias_handle;
2473 d.out.alias_handle = alias_handle;
2475 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2476 if (!NT_STATUS_IS_OK(status)) {
2477 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2484 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2485 struct policy_handle *domain_handle,
2486 struct policy_handle *alias_handle,
2487 const struct dom_sid *domain_sid)
2490 struct samr_CreateDomAlias r;
2491 struct lsa_String name;
2495 init_lsa_String(&name, TEST_ALIASNAME);
2496 r.in.domain_handle = domain_handle;
2497 r.in.alias_name = &name;
2498 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2499 r.out.alias_handle = alias_handle;
2502 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2504 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2506 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2507 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2508 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2511 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2517 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2518 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2521 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2524 if (!NT_STATUS_IS_OK(status)) {
2525 printf("CreateAlias failed - %s\n", nt_errstr(status));
2529 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2536 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2537 const char *acct_name,
2538 struct policy_handle *domain_handle, char **password)
2546 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2550 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2554 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2558 /* test what happens when setting the old password again */
2559 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2564 char simple_pass[9];
2565 char *v = generate_random_str(mem_ctx, 1);
2567 ZERO_STRUCT(simple_pass);
2568 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2570 /* test what happens when picking a simple password */
2571 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2576 /* set samr_SetDomainInfo level 1 with min_length 5 */
2578 struct samr_QueryDomainInfo r;
2579 struct samr_SetDomainInfo s;
2580 uint16_t len_old, len;
2581 uint32_t pwd_prop_old;
2582 int64_t min_pwd_age_old;
2587 r.in.domain_handle = domain_handle;
2590 printf("testing samr_QueryDomainInfo level 1\n");
2591 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2592 if (!NT_STATUS_IS_OK(status)) {
2596 s.in.domain_handle = domain_handle;
2598 s.in.info = r.out.info;
2600 /* remember the old min length, so we can reset it */
2601 len_old = s.in.info->info1.min_password_length;
2602 s.in.info->info1.min_password_length = len;
2603 pwd_prop_old = s.in.info->info1.password_properties;
2604 /* turn off password complexity checks for this test */
2605 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2607 min_pwd_age_old = s.in.info->info1.min_password_age;
2608 s.in.info->info1.min_password_age = 0;
2610 printf("testing samr_SetDomainInfo level 1\n");
2611 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2612 if (!NT_STATUS_IS_OK(status)) {
2616 printf("calling test_ChangePasswordUser3 with too short password\n");
2618 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2622 s.in.info->info1.min_password_length = len_old;
2623 s.in.info->info1.password_properties = pwd_prop_old;
2624 s.in.info->info1.min_password_age = min_pwd_age_old;
2626 printf("testing samr_SetDomainInfo level 1\n");
2627 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2628 if (!NT_STATUS_IS_OK(status)) {
2636 struct samr_OpenUser r;
2637 struct samr_QueryUserInfo q;
2638 struct samr_LookupNames n;
2639 struct policy_handle user_handle;
2641 n.in.domain_handle = domain_handle;
2643 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2644 n.in.names[0].string = acct_name;
2646 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2647 if (!NT_STATUS_IS_OK(status)) {
2648 printf("LookupNames failed - %s\n", nt_errstr(status));
2652 r.in.domain_handle = domain_handle;
2653 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2654 r.in.rid = n.out.rids.ids[0];
2655 r.out.user_handle = &user_handle;
2657 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2658 if (!NT_STATUS_IS_OK(status)) {
2659 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2663 q.in.user_handle = &user_handle;
2666 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2667 if (!NT_STATUS_IS_OK(status)) {
2668 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2672 printf("calling test_ChangePasswordUser3 with too early password change\n");
2674 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2675 q.out.info->info5.last_password_change, true)) {
2680 /* we change passwords twice - this has the effect of verifying
2681 they were changed correctly for the final call */
2682 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2686 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2693 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2694 struct policy_handle *domain_handle,
2695 struct policy_handle *user_handle_out,
2696 struct dom_sid *domain_sid,
2697 enum torture_samr_choice which_ops)
2700 TALLOC_CTX *user_ctx;
2703 struct samr_CreateUser r;
2704 struct samr_QueryUserInfo q;
2705 struct samr_DeleteUser d;
2708 /* This call creates a 'normal' account - check that it really does */
2709 const uint32_t acct_flags = ACB_NORMAL;
2710 struct lsa_String name;
2713 struct policy_handle user_handle;
2714 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2715 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2717 r.in.domain_handle = domain_handle;
2718 r.in.account_name = &name;
2719 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2720 r.out.user_handle = &user_handle;
2723 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2725 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2727 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2728 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2729 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2732 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2738 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2739 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2740 talloc_free(user_ctx);
2743 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2745 if (!NT_STATUS_IS_OK(status)) {
2746 talloc_free(user_ctx);
2747 printf("CreateUser failed - %s\n", nt_errstr(status));
2750 q.in.user_handle = &user_handle;
2753 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2754 if (!NT_STATUS_IS_OK(status)) {
2755 printf("QueryUserInfo level %u failed - %s\n",
2756 q.in.level, nt_errstr(status));
2759 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2760 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2761 q.out.info->info16.acct_flags,
2767 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2768 acct_flags, name.string, which_ops)) {
2772 if (user_handle_out) {
2773 *user_handle_out = user_handle;
2775 printf("Testing DeleteUser (createuser test)\n");
2777 d.in.user_handle = &user_handle;
2778 d.out.user_handle = &user_handle;
2780 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2781 if (!NT_STATUS_IS_OK(status)) {
2782 printf("DeleteUser failed - %s\n", nt_errstr(status));
2789 talloc_free(user_ctx);
2795 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2796 struct policy_handle *domain_handle,
2797 struct dom_sid *domain_sid,
2798 enum torture_samr_choice which_ops)
2801 struct samr_CreateUser2 r;
2802 struct samr_QueryUserInfo q;
2803 struct samr_DeleteUser d;
2804 struct policy_handle user_handle;
2806 struct lsa_String name;
2811 uint32_t acct_flags;
2812 const char *account_name;
2814 } account_types[] = {
2815 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2816 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2817 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2818 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2819 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2820 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2821 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2822 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2823 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2824 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2825 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2826 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2827 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2828 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2829 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2832 for (i = 0; account_types[i].account_name; i++) {
2833 TALLOC_CTX *user_ctx;
2834 uint32_t acct_flags = account_types[i].acct_flags;
2835 uint32_t access_granted;
2836 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2837 init_lsa_String(&name, account_types[i].account_name);
2839 r.in.domain_handle = domain_handle;
2840 r.in.account_name = &name;
2841 r.in.acct_flags = acct_flags;
2842 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2843 r.out.user_handle = &user_handle;
2844 r.out.access_granted = &access_granted;
2847 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2849 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2851 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2852 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2853 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2856 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2863 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2864 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2865 talloc_free(user_ctx);
2869 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2872 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2873 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2874 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2878 if (NT_STATUS_IS_OK(status)) {
2879 q.in.user_handle = &user_handle;
2882 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2883 if (!NT_STATUS_IS_OK(status)) {
2884 printf("QueryUserInfo level %u failed - %s\n",
2885 q.in.level, nt_errstr(status));
2888 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2889 if (acct_flags == ACB_NORMAL) {
2890 expected_flags |= ACB_PW_EXPIRED;
2892 if ((q.out.info->info5.acct_flags) != expected_flags) {
2893 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2894 q.out.info->info5.acct_flags,
2898 switch (acct_flags) {
2900 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2901 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2902 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2907 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2908 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2909 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2914 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2915 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2916 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2923 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2924 acct_flags, name.string, which_ops)) {
2928 printf("Testing DeleteUser (createuser2 test)\n");
2930 d.in.user_handle = &user_handle;
2931 d.out.user_handle = &user_handle;
2933 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2934 if (!NT_STATUS_IS_OK(status)) {
2935 printf("DeleteUser failed - %s\n", nt_errstr(status));
2939 talloc_free(user_ctx);
2945 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2946 struct policy_handle *handle)
2949 struct samr_QueryAliasInfo r;
2950 uint16_t levels[] = {1, 2, 3};
2954 for (i=0;i<ARRAY_SIZE(levels);i++) {
2955 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2957 r.in.alias_handle = handle;
2958 r.in.level = levels[i];
2960 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2961 if (!NT_STATUS_IS_OK(status)) {
2962 printf("QueryAliasInfo level %u failed - %s\n",
2963 levels[i], nt_errstr(status));
2971 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2972 struct policy_handle *handle)
2975 struct samr_QueryGroupInfo r;
2976 uint16_t levels[] = {1, 2, 3, 4, 5};
2980 for (i=0;i<ARRAY_SIZE(levels);i++) {
2981 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2983 r.in.group_handle = handle;
2984 r.in.level = levels[i];
2986 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2987 if (!NT_STATUS_IS_OK(status)) {
2988 printf("QueryGroupInfo level %u failed - %s\n",
2989 levels[i], nt_errstr(status));
2997 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2998 struct policy_handle *handle)
3001 struct samr_QueryGroupMember r;
3004 printf("Testing QueryGroupMember\n");
3006 r.in.group_handle = handle;
3008 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3009 if (!NT_STATUS_IS_OK(status)) {
3010 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3018 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3019 struct policy_handle *handle)
3022 struct samr_QueryGroupInfo r;
3023 struct samr_SetGroupInfo s;
3024 uint16_t levels[] = {1, 2, 3, 4};
3025 uint16_t set_ok[] = {0, 1, 1, 1};
3029 for (i=0;i<ARRAY_SIZE(levels);i++) {
3030 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3032 r.in.group_handle = handle;
3033 r.in.level = levels[i];
3035 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3036 if (!NT_STATUS_IS_OK(status)) {
3037 printf("QueryGroupInfo level %u failed - %s\n",
3038 levels[i], nt_errstr(status));
3042 printf("Testing SetGroupInfo level %u\n", levels[i]);
3044 s.in.group_handle = handle;
3045 s.in.level = levels[i];
3046 s.in.info = r.out.info;
3049 /* disabled this, as it changes the name only from the point of view of samr,
3050 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3051 the name is still reserved, so creating the old name fails, but deleting by the old name
3053 if (s.in.level == 2) {
3054 init_lsa_String(&s.in.info->string, "NewName");
3058 if (s.in.level == 4) {
3059 init_lsa_String(&s.in.info->description, "test description");
3062 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3064 if (!NT_STATUS_IS_OK(status)) {
3065 printf("SetGroupInfo level %u failed - %s\n",
3066 r.in.level, nt_errstr(status));
3071 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3072 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3073 r.in.level, nt_errstr(status));
3083 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3084 struct policy_handle *handle)
3087 struct samr_QueryUserInfo r;
3088 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3089 11, 12, 13, 14, 16, 17, 20, 21};
3093 for (i=0;i<ARRAY_SIZE(levels);i++) {
3094 printf("Testing QueryUserInfo level %u\n", levels[i]);
3096 r.in.user_handle = handle;
3097 r.in.level = levels[i];
3099 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3100 if (!NT_STATUS_IS_OK(status)) {
3101 printf("QueryUserInfo level %u failed - %s\n",
3102 levels[i], nt_errstr(status));
3110 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3111 struct policy_handle *handle)
3114 struct samr_QueryUserInfo2 r;
3115 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3116 11, 12, 13, 14, 16, 17, 20, 21};
3120 for (i=0;i<ARRAY_SIZE(levels);i++) {
3121 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3123 r.in.user_handle = handle;
3124 r.in.level = levels[i];
3126 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3127 if (!NT_STATUS_IS_OK(status)) {
3128 printf("QueryUserInfo2 level %u failed - %s\n",
3129 levels[i], nt_errstr(status));
3137 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3138 struct policy_handle *handle, uint32_t rid)
3141 struct samr_OpenUser r;
3142 struct policy_handle user_handle;
3145 printf("Testing OpenUser(%u)\n", rid);
3147 r.in.domain_handle = handle;
3148 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3150 r.out.user_handle = &user_handle;
3152 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3153 if (!NT_STATUS_IS_OK(status)) {
3154 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3158 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3162 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3166 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3170 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3174 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3178 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3185 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3186 struct policy_handle *handle, uint32_t rid)
3189 struct samr_OpenGroup r;
3190 struct policy_handle group_handle;
3193 printf("Testing OpenGroup(%u)\n", rid);
3195 r.in.domain_handle = handle;
3196 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3198 r.out.group_handle = &group_handle;
3200 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3201 if (!NT_STATUS_IS_OK(status)) {
3202 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3206 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3210 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3214 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3218 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3225 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3226 struct policy_handle *handle, uint32_t rid)
3229 struct samr_OpenAlias r;
3230 struct policy_handle alias_handle;
3233 printf("Testing OpenAlias(%u)\n", rid);
3235 r.in.domain_handle = handle;
3236 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3238 r.out.alias_handle = &alias_handle;
3240 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3241 if (!NT_STATUS_IS_OK(status)) {
3242 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3246 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3250 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3254 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3258 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3265 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3266 struct policy_handle *handle, uint32_t rid,
3267 uint32_t acct_flag_mask)
3270 struct samr_OpenUser r;
3271 struct samr_QueryUserInfo q;
3272 struct policy_handle user_handle;
3275 printf("Testing OpenUser(%u)\n", rid);
3277 r.in.domain_handle = handle;
3278 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3280 r.out.user_handle = &user_handle;
3282 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3283 if (!NT_STATUS_IS_OK(status)) {
3284 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3288 q.in.user_handle = &user_handle;
3291 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3292 if (!NT_STATUS_IS_OK(status)) {
3293 printf("QueryUserInfo level 16 failed - %s\n",
3297 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3298 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3299 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3304 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3311 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3312 struct policy_handle *handle)
3314 NTSTATUS status = STATUS_MORE_ENTRIES;
3315 struct samr_EnumDomainUsers r;
3316 uint32_t mask, resume_handle=0;
3319 struct samr_LookupNames n;
3320 struct samr_LookupRids lr ;
3321 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3322 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3323 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3326 printf("Testing EnumDomainUsers\n");
3328 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3329 r.in.domain_handle = handle;
3330 r.in.resume_handle = &resume_handle;
3331 r.in.acct_flags = mask = masks[mask_idx];
3332 r.in.max_size = (uint32_t)-1;
3333 r.out.resume_handle = &resume_handle;
3335 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3336 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3337 !NT_STATUS_IS_OK(status)) {
3338 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3343 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3347 if (r.out.sam->count == 0) {
3351 for (i=0;i<r.out.sam->count;i++) {
3353 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3356 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3362 printf("Testing LookupNames\n");
3363 n.in.domain_handle = handle;
3364 n.in.num_names = r.out.sam->count;
3365 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3366 for (i=0;i<r.out.sam->count;i++) {
3367 n.in.names[i].string = r.out.sam->entries[i].name.string;
3369 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3370 if (!NT_STATUS_IS_OK(status)) {
3371 printf("LookupNames failed - %s\n", nt_errstr(status));
3376 printf("Testing LookupRids\n");
3377 lr.in.domain_handle = handle;
3378 lr.in.num_rids = r.out.sam->count;
3379 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3380 for (i=0;i<r.out.sam->count;i++) {
3381 lr.in.rids[i] = r.out.sam->entries[i].idx;
3383 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3384 if (!NT_STATUS_IS_OK(status)) {
3385 printf("LookupRids failed - %s\n", nt_errstr(status));
3393 try blasting the server with a bunch of sync requests
3395 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx,
3396 struct policy_handle *handle)
3399 struct samr_EnumDomainUsers r;
3400 uint32_t resume_handle=0;
3402 #define ASYNC_COUNT 100
3403 struct rpc_request *req[ASYNC_COUNT];
3405 if (!torture_setting_bool(tctx, "dangerous", false)) {
3406 printf("samr async test disabled - enable dangerous tests to use\n");
3410 printf("Testing EnumDomainUsers_async\n");
3412 r.in.domain_handle = handle;
3413 r.in.resume_handle = &resume_handle;
3414 r.in.acct_flags = 0;
3415 r.in.max_size = (uint32_t)-1;
3416 r.out.resume_handle = &resume_handle;
3418 for (i=0;i<ASYNC_COUNT;i++) {
3419 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3422 for (i=0;i<ASYNC_COUNT;i++) {
3423 status = dcerpc_ndr_request_recv(req[i]);
3424 if (!NT_STATUS_IS_OK(status)) {
3425 printf("EnumDomainUsers[%d] failed - %s\n",
3426 i, nt_errstr(status));
3431 printf("%d async requests OK\n", i);
3436 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3437 struct policy_handle *handle)
3440 struct samr_EnumDomainGroups r;
3441 uint32_t resume_handle=0;
3445 printf("Testing EnumDomainGroups\n");
3447 r.in.domain_handle = handle;
3448 r.in.resume_handle = &resume_handle;
3449 r.in.max_size = (uint32_t)-1;
3450 r.out.resume_handle = &resume_handle;
3452 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3453 if (!NT_STATUS_IS_OK(status)) {
3454 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3462 for (i=0;i<r.out.sam->count;i++) {
3463 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3471 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3472 struct policy_handle *handle)
3475 struct samr_EnumDomainAliases r;
3476 uint32_t resume_handle=0;
3480 printf("Testing EnumDomainAliases\n");
3482 r.in.domain_handle = handle;
3483 r.in.resume_handle = &resume_handle;
3484 r.in.acct_flags = (uint32_t)-1;
3485 r.out.resume_handle = &resume_handle;
3487 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3488 if (!NT_STATUS_IS_OK(status)) {
3489 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3497 for (i=0;i<r.out.sam->count;i++) {
3498 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3506 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3507 struct policy_handle *handle)
3510 struct samr_GetDisplayEnumerationIndex r;
3512 uint16_t levels[] = {1, 2, 3, 4, 5};
3513 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3516 for (i=0;i<ARRAY_SIZE(levels);i++) {
3517 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3519 r.in.domain_handle = handle;
3520 r.in.level = levels[i];
3521 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3523 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3526 !NT_STATUS_IS_OK(status) &&
3527 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3528 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3529 levels[i], nt_errstr(status));
3533 init_lsa_String(&r.in.name, "zzzzzzzz");
3535 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3537 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3538 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3539 levels[i], nt_errstr(status));
3547 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3548 struct policy_handle *handle)
3551 struct samr_GetDisplayEnumerationIndex2 r;
3553 uint16_t levels[] = {1, 2, 3, 4, 5};
3554 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3557 for (i=0;i<ARRAY_SIZE(levels);i++) {
3558 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3560 r.in.domain_handle = handle;
3561 r.in.level = levels[i];
3562 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3564 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3566 !NT_STATUS_IS_OK(status) &&
3567 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3568 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3569 levels[i], nt_errstr(status));
3573 init_lsa_String(&r.in.name, "zzzzzzzz");
3575 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3576 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3577 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3578 levels[i], nt_errstr(status));
3586 #define STRING_EQUAL_QUERY(s1, s2, user) \
3587 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3588 /* odd, but valid */ \
3589 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3590 printf("%s mismatch for %s: %s != %s (%s)\n", \
3591 #s1, user.string, s1.string, s2.string, __location__); \
3594 #define INT_EQUAL_QUERY(s1, s2, user) \
3596 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3597 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3601 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3602 struct samr_QueryDisplayInfo *querydisplayinfo,
3603 bool *seen_testuser)
3605 struct samr_OpenUser r;
3606 struct samr_QueryUserInfo q;
3607 struct policy_handle user_handle;
3610 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3611 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3612 for (i = 0; ; i++) {
3613 switch (querydisplayinfo->in.level) {
3615 if (i >= querydisplayinfo->out.info.info1.count) {
3618 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3621 if (i >= querydisplayinfo->out.info.info2.count) {
3624 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3630 /* Not interested in validating just the account name */
3634 r.out.user_handle = &user_handle;
3636 switch (querydisplayinfo->in.level) {
3639 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3640 if (!NT_STATUS_IS_OK(status)) {
3641 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3646 q.in.user_handle = &user_handle;
3648 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3649 if (!NT_STATUS_IS_OK(status)) {
3650 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3654 switch (querydisplayinfo->in.level) {
3656 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3657 *seen_testuser = true;
3659 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3660 q.out.info->info21.full_name, q.out.info->info21.account_name);
3661 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3662 q.out.info->info21.account_name, q.out.info->info21.account_name);
3663 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3664 q.out.info->info21.description, q.out.info->info21.account_name);
3665 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3666 q.out.info->info21.rid, q.out.info->info21.account_name);
3667 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3668 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3672 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3673 q.out.info->info21.account_name, q.out.info->info21.account_name);
3674 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3675 q.out.info->info21.description, q.out.info->info21.account_name);
3676 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3677 q.out.info->info21.rid, q.out.info->info21.account_name);
3678 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3679 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3681 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3682 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3683 q.out.info->info21.account_name.string);
3686 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3687 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3688 q.out.info->info21.account_name.string,
3689 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3690 q.out.info->info21.acct_flags);
3697 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3704 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3705 struct policy_handle *handle)
3708 struct samr_QueryDisplayInfo r;
3709 struct samr_QueryDomainInfo dom_info;
3711 uint16_t levels[] = {1, 2, 3, 4, 5};
3713 bool seen_testuser = false;
3715 for (i=0;i<ARRAY_SIZE(levels);i++) {
3716 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3719 status = STATUS_MORE_ENTRIES;
3720 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3721 r.in.domain_handle = handle;
3722 r.in.level = levels[i];
3723 r.in.max_entries = 2;
3724 r.in.buf_size = (uint32_t)-1;
3726 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3727 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3728 printf("QueryDisplayInfo level %u failed - %s\n",
3729 levels[i], nt_errstr(status));
3732 switch (r.in.level) {
3734 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3737 r.in.start_idx += r.out.info.info1.count;
3740 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3743 r.in.start_idx += r.out.info.info2.count;
3746 r.in.start_idx += r.out.info.info3.count;
3749 r.in.start_idx += r.out.info.info4.count;
3752 r.in.start_idx += r.out.info.info5.count;
3756 dom_info.in.domain_handle = handle;
3757 dom_info.in.level = 2;
3758 /* Check number of users returned is correct */
3759 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3760 if (!NT_STATUS_IS_OK(status)) {
3761 printf("QueryDomainInfo level %u failed - %s\n",
3762 r.in.level, nt_errstr(status));
3766 switch (r.in.level) {
3769 if (dom_info.out.info->general.num_users < r.in.start_idx) {
3770 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3771 r.in.start_idx, dom_info.out.info->general.num_groups,
3772 dom_info.out.info->general.domain_name.string);
3775 if (!seen_testuser) {
3776 struct policy_handle user_handle;
3777 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3778 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3779 dom_info.out.info->general.domain_name.string);
3781 test_samr_handle_Close(p, mem_ctx, &user_handle);
3787 if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3788 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3789 r.in.start_idx, dom_info.out.info->general.num_groups,
3790 dom_info.out.info->general.domain_name.string);
3802 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3803 struct policy_handle *handle)
3806 struct samr_QueryDisplayInfo2 r;
3808 uint16_t levels[] = {1, 2, 3, 4, 5};
3811 for (i=0;i<ARRAY_SIZE(levels);i++) {
3812 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3814 r.in.domain_handle = handle;
3815 r.in.level = levels[i];
3817 r.in.max_entries = 1000;
3818 r.in.buf_size = (uint32_t)-1;
3820 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3821 if (!NT_STATUS_IS_OK(status)) {
3822 printf("QueryDisplayInfo2 level %u failed - %s\n",
3823 levels[i], nt_errstr(status));
3831 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3832 struct policy_handle *handle)
3835 struct samr_QueryDisplayInfo3 r;
3837 uint16_t levels[] = {1, 2, 3, 4, 5};
3840 for (i=0;i<ARRAY_SIZE(levels);i++) {
3841 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3843 r.in.domain_handle = handle;
3844 r.in.level = levels[i];
3846 r.in.max_entries = 1000;
3847 r.in.buf_size = (uint32_t)-1;
3849 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3850 if (!NT_STATUS_IS_OK(status)) {
3851 printf("QueryDisplayInfo3 level %u failed - %s\n",
3852 levels[i], nt_errstr(status));
3861 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3862 struct policy_handle *handle)
3865 struct samr_QueryDisplayInfo r;
3868 printf("Testing QueryDisplayInfo continuation\n");
3870 r.in.domain_handle = handle;
3873 r.in.max_entries = 1;
3874 r.in.buf_size = (uint32_t)-1;
3877 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3878 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3879 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3880 printf("expected idx %d but got %d\n",
3882 r.out.info.info1.entries[0].idx);
3886 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3887 !NT_STATUS_IS_OK(status)) {
3888 printf("QueryDisplayInfo level %u failed - %s\n",
3889 r.in.level, nt_errstr(status));
3894 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3895 NT_STATUS_IS_OK(status)) &&
3896 r.out.returned_size != 0);
3901 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3902 struct policy_handle *handle)
3905 struct samr_QueryDomainInfo r;
3906 struct samr_SetDomainInfo s;
3907 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3908 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3911 const char *domain_comment = talloc_asprintf(mem_ctx,
3912 "Tortured by Samba4 RPC-SAMR: %s",
3913 timestring(mem_ctx, time(NULL)));
3915 s.in.domain_handle = handle;
3917 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3919 s.in.info->oem.oem_information.string = domain_comment;
3920 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3921 if (!NT_STATUS_IS_OK(status)) {
3922 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3923 r.in.level, nt_errstr(status));
3927 for (i=0;i<ARRAY_SIZE(levels);i++) {
3928 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3930 r.in.domain_handle = handle;
3931 r.in.level = levels[i];
3933 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 printf("QueryDomainInfo level %u failed - %s\n",
3936 r.in.level, nt_errstr(status));
3941 switch (levels[i]) {
3943 if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3944 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3945 levels[i], r.out.info->general.oem_information.string, domain_comment);
3948 if (!r.out.info->general.primary.string) {
3949 printf("QueryDomainInfo level %u returned no PDC name\n",
3952 } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3953 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3954 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3955 levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3960 if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3961 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3962 levels[i], r.out.info->oem.oem_information.string, domain_comment);
3967 if (!r.out.info->info6.primary.string) {
3968 printf("QueryDomainInfo level %u returned no PDC name\n",
3974 if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3975 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3976 levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3982 printf("Testing SetDomainInfo level %u\n", levels[i]);
3984 s.in.domain_handle = handle;
3985 s.in.level = levels[i];
3986 s.in.info = r.out.info;
3988 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3990 if (!NT_STATUS_IS_OK(status)) {
3991 printf("SetDomainInfo level %u failed - %s\n",
3992 r.in.level, nt_errstr(status));
3997 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3998 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3999 r.in.level, nt_errstr(status));
4005 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
4006 if (!NT_STATUS_IS_OK(status)) {
4007 printf("QueryDomainInfo level %u failed - %s\n",
4008 r.in.level, nt_errstr(status));
4018 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4019 struct policy_handle *handle)
4022 struct samr_QueryDomainInfo2 r;
4023 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4027 for (i=0;i<ARRAY_SIZE(levels);i++) {
4028 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4030 r.in.domain_handle = handle;
4031 r.in.level = levels[i];
4033 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
4034 if (!NT_STATUS_IS_OK(status)) {
4035 printf("QueryDomainInfo2 level %u failed - %s\n",
4036 r.in.level, nt_errstr(status));
4045 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4046 set of group names. */
4047 static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4048 struct policy_handle *handle)
4050 struct samr_EnumDomainGroups q1;
4051 struct samr_QueryDisplayInfo q2;
4053 uint32_t resume_handle=0;
4058 const char **names = NULL;
4060 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
4062 q1.in.domain_handle = handle;
4063 q1.in.resume_handle = &resume_handle;
4065 q1.out.resume_handle = &resume_handle;
4067 status = STATUS_MORE_ENTRIES;
4068 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4069 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
4071 if (!NT_STATUS_IS_OK(status) &&
4072 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4075 for (i=0; i<q1.out.num_entries; i++) {
4076 add_string_to_array(mem_ctx,
4077 q1.out.sam->entries[i].name.string,
4078 &names, &num_names);
4082 if (!NT_STATUS_IS_OK(status)) {
4083 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4088 printf("EnumDomainGroups failed to return q1.out.sam\n");
4092 q2.in.domain_handle = handle;
4094 q2.in.start_idx = 0;
4095 q2.in.max_entries = 5;
4096 q2.in.buf_size = (uint32_t)-1;
4098 status = STATUS_MORE_ENTRIES;
4099 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4100 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
4102 if (!NT_STATUS_IS_OK(status) &&
4103 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4106 for (i=0; i<q2.out.info.info5.count; i++) {
4108 const char *name = q2.out.info.info5.entries[i].account_name.string;
4110 for (j=0; j<num_names; j++) {
4111 if (names[j] == NULL)
4113 if (strequal(names[j], name)) {
4121 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4126 q2.in.start_idx += q2.out.info.info5.count;
4129 if (!NT_STATUS_IS_OK(status)) {
4130 printf("QueryDisplayInfo level 5 failed - %s\n",
4135 for (i=0; i<num_names; i++) {
4136 if (names[i] != NULL) {
4137 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4146 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4147 struct policy_handle *group_handle)
4149 struct samr_DeleteDomainGroup d;
4153 printf("Testing DeleteDomainGroup\n");
4155 d.in.group_handle = group_handle;
4156 d.out.group_handle = group_handle;
4158 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
4159 if (!NT_STATUS_IS_OK(status)) {
4160 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
4167 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4168 struct policy_handle *domain_handle)
4170 struct samr_TestPrivateFunctionsDomain r;
4174 printf("Testing TestPrivateFunctionsDomain\n");
4176 r.in.domain_handle = domain_handle;
4178 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
4179 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
4180 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
4187 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4188 struct dom_sid *domain_sid,
4189 struct policy_handle *domain_handle)
4191 struct samr_RidToSid r;
4194 struct dom_sid *calc_sid;
4195 int rids[] = { 0, 42, 512, 10200 };
4198 for (i=0;i<ARRAY_SIZE(rids);i++) {
4200 printf("Testing RidToSid\n");
4202 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
4203 r.in.domain_handle = domain_handle;
4206 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
4207 if (!NT_STATUS_IS_OK(status)) {
4208 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4211 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4213 if (!dom_sid_equal(calc_sid, r.out.sid)) {
4214 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4215 dom_sid_string(mem_ctx, r.out.sid),
4216 dom_sid_string(mem_ctx, calc_sid));
4225 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4226 struct policy_handle *domain_handle)
4228 struct samr_GetBootKeyInformation r;
4232 printf("Testing GetBootKeyInformation\n");
4234 r.in.domain_handle = domain_handle;
4236 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4237 if (!NT_STATUS_IS_OK(status)) {
4238 /* w2k3 seems to fail this sometimes and pass it sometimes */
4239 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4245 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4246 struct policy_handle *domain_handle,
4247 struct policy_handle *group_handle)
4250 struct samr_AddGroupMember r;
4251 struct samr_DeleteGroupMember d;
4252 struct samr_QueryGroupMember q;
4253 struct samr_SetMemberAttributesOfGroup s;
4257 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4258 if (!NT_STATUS_IS_OK(status)) {
4259 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4263 r.in.group_handle = group_handle;
4265 r.in.flags = 0; /* ??? */
4267 printf("Testing AddGroupMember and DeleteGroupMember\n");
4269 d.in.group_handle = group_handle;
4272 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4273 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4274 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4279 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4280 if (!NT_STATUS_IS_OK(status)) {
4281 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4285 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4286 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4287 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4292 if (torture_setting_bool(tctx, "samba4", false)) {
4293 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4295 /* this one is quite strange. I am using random inputs in the
4296 hope of triggering an error that might give us a clue */
4298 s.in.group_handle = group_handle;
4299 s.in.unknown1 = random();
4300 s.in.unknown2 = random();
4302 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4303 if (!NT_STATUS_IS_OK(status)) {
4304 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4309 q.in.group_handle = group_handle;
4311 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4312 if (!NT_STATUS_IS_OK(status)) {
4313 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4317 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4318 if (!NT_STATUS_IS_OK(status)) {
4319 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4323 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4324 if (!NT_STATUS_IS_OK(status)) {
4325 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4333 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4334 struct policy_handle *domain_handle,
4335 struct policy_handle *group_handle,
4336 struct dom_sid *domain_sid)
4339 struct samr_CreateDomainGroup r;
4341 struct lsa_String name;
4344 init_lsa_String(&name, TEST_GROUPNAME);
4346 r.in.domain_handle = domain_handle;
4348 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4349 r.out.group_handle = group_handle;
4352 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4354 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4356 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
4357 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4358 printf("Server correctly refused create of '%s'\n", r.in.name->string);
4361 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4367 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4368 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4369 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4373 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4375 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4376 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4378 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4382 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4384 if (!NT_STATUS_IS_OK(status)) {
4385 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4389 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4390 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4394 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4403 its not totally clear what this does. It seems to accept any sid you like.
4405 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4406 TALLOC_CTX *mem_ctx,
4407 struct policy_handle *domain_handle)
4410 struct samr_RemoveMemberFromForeignDomain r;
4412 r.in.domain_handle = domain_handle;
4413 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4415 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4416 if (!NT_STATUS_IS_OK(status)) {
4417 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4426 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4427 struct policy_handle *handle);
4429 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4430 struct policy_handle *handle, struct dom_sid *sid,
4431 enum torture_samr_choice which_ops)
4434 struct samr_OpenDomain r;
4435 struct policy_handle domain_handle;
4436 struct policy_handle alias_handle;
4437 struct policy_handle user_handle;
4438 struct policy_handle group_handle;
4441 ZERO_STRUCT(alias_handle);
4442 ZERO_STRUCT(user_handle);
4443 ZERO_STRUCT(group_handle);
4444 ZERO_STRUCT(domain_handle);
4446 printf("Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4448 r.in.connect_handle = handle;
4449 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4451 r.out.domain_handle = &domain_handle;
4453 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4454 if (!NT_STATUS_IS_OK(status)) {
4455 printf("OpenDomain failed - %s\n", nt_errstr(status));
4459 /* run the domain tests with the main handle closed - this tests
4460 the servers reference counting */
4461 ret &= test_samr_handle_Close(p, tctx, handle);
4463 switch (which_ops) {
4464 case TORTURE_SAMR_USER_ATTRIBUTES:
4465 case TORTURE_SAMR_PASSWORDS:
4466 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4467 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4468 /* This test needs 'complex' users to validate */
4469 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4471 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4474 case TORTURE_SAMR_OTHER:
4475 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4477 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4479 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4480 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4481 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4482 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4483 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4484 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4485 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4486 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4487 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4488 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4489 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4490 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4491 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4493 if (torture_setting_bool(tctx, "samba4", false)) {
4494 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4496 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4497 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4499 ret &= test_GroupList(p, tctx, &domain_handle);
4500 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4501 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4502 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4504 printf("Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4509 if (!policy_handle_empty(&user_handle) &&
4510 !test_DeleteUser(p, tctx, &user_handle)) {
4514 if (!policy_handle_empty(&alias_handle) &&
4515 !test_DeleteAlias(p, tctx, &alias_handle)) {
4519 if (!policy_handle_empty(&group_handle) &&
4520 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4524 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4526 /* reconnect the main handle */
4527 ret &= test_Connect(p, tctx, handle);
4530 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4536 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4537 struct policy_handle *handle, const char *domain,
4538 enum torture_samr_choice which_ops)
4541 struct samr_LookupDomain r;
4542 struct lsa_String n1;
4543 struct lsa_String n2;
4546 printf("Testing LookupDomain(%s)\n", domain);
4548 /* check for correct error codes */
4549 r.in.connect_handle = handle;
4550 r.in.domain_name = &n2;
4553 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4554 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4555 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4559 init_lsa_String(&n2, "xxNODOMAINxx");
4561 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4562 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4563 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4567 r.in.connect_handle = handle;
4569 init_lsa_String(&n1, domain);
4570 r.in.domain_name = &n1;
4572 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4573 if (!NT_STATUS_IS_OK(status)) {
4574 printf("LookupDomain failed - %s\n", nt_errstr(status));
4578 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4582 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4590 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4591 struct policy_handle *handle, enum torture_samr_choice which_ops)
4594 struct samr_EnumDomains r;
4595 uint32_t resume_handle = 0;
4599 r.in.connect_handle = handle;
4600 r.in.resume_handle = &resume_handle;
4601 r.in.buf_size = (uint32_t)-1;
4602 r.out.resume_handle = &resume_handle;
4604 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4605 if (!NT_STATUS_IS_OK(status)) {
4606 printf("EnumDomains failed - %s\n", nt_errstr(status));
4614 for (i=0;i<r.out.sam->count;i++) {
4615 if (!test_LookupDomain(p, tctx, handle,
4616 r.out.sam->entries[i].name.string, which_ops)) {
4621 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4622 if (!NT_STATUS_IS_OK(status)) {
4623 printf("EnumDomains failed - %s\n", nt_errstr(status));
4631 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4632 struct policy_handle *handle)
4635 struct samr_Connect r;
4636 struct samr_Connect2 r2;
4637 struct samr_Connect3 r3;
4638 struct samr_Connect4 r4;
4639 struct samr_Connect5 r5;
4640 union samr_ConnectInfo info;
4641 struct policy_handle h;
4642 bool ret = true, got_handle = false;
4644 printf("testing samr_Connect\n");
4646 r.in.system_name = 0;
4647 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4648 r.out.connect_handle = &h;
4650 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4651 if (!NT_STATUS_IS_OK(status)) {
4652 printf("Connect failed - %s\n", nt_errstr(status));
4659 printf("testing samr_Connect2\n");
4661 r2.in.system_name = NULL;
4662 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4663 r2.out.connect_handle = &h;
4665 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4666 if (!NT_STATUS_IS_OK(status)) {
4667 printf("Connect2 failed - %s\n", nt_errstr(status));
4671 test_samr_handle_Close(p, mem_ctx, handle);
4677 printf("testing samr_Connect3\n");
4679 r3.in.system_name = NULL;
4681 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4682 r3.out.connect_handle = &h;
4684 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4685 if (!NT_STATUS_IS_OK(status)) {
4686 printf("Connect3 failed - %s\n", nt_errstr(status));
4690 test_samr_handle_Close(p, mem_ctx, handle);
4696 printf("testing samr_Connect4\n");
4698 r4.in.system_name = "";
4699 r4.in.client_version = 0;
4700 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4701 r4.out.connect_handle = &h;
4703 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4704 if (!NT_STATUS_IS_OK(status)) {
4705 printf("Connect4 failed - %s\n", nt_errstr(status));
4709 test_samr_handle_Close(p, mem_ctx, handle);
4715 printf("testing samr_Connect5\n");
4717 info.info1.client_version = 0;
4718 info.info1.unknown2 = 0;
4720 r5.in.system_name = "";
4721 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4724 r5.out.info = &info;
4725 r5.out.connect_handle = &h;
4727 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4728 if (!NT_STATUS_IS_OK(status)) {
4729 printf("Connect5 failed - %s\n", nt_errstr(status));
4733 test_samr_handle_Close(p, mem_ctx, handle);
4743 bool torture_rpc_samr(struct torture_context *torture)
4746 struct dcerpc_pipe *p;
4748 struct policy_handle handle;
4750 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4751 if (!NT_STATUS_IS_OK(status)) {
4755 ret &= test_Connect(p, torture, &handle);
4757 ret &= test_QuerySecurity(p, torture, &handle);
4759 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4761 ret &= test_SetDsrmPassword(p, torture, &handle);
4763 ret &= test_Shutdown(p, torture, &handle);
4765 ret &= test_samr_handle_Close(p, torture, &handle);
4771 bool torture_rpc_samr_users(struct torture_context *torture)
4774 struct dcerpc_pipe *p;
4776 struct policy_handle handle;
4778 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4779 if (!NT_STATUS_IS_OK(status)) {
4783 ret &= test_Connect(p, torture, &handle);
4785 ret &= test_QuerySecurity(p, torture, &handle);
4787 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4789 ret &= test_SetDsrmPassword(p, torture, &handle);
4791 ret &= test_Shutdown(p, torture, &handle);
4793 ret &= test_samr_handle_Close(p, torture, &handle);
4799 bool torture_rpc_samr_passwords(struct torture_context *torture)
4802 struct dcerpc_pipe *p;
4804 struct policy_handle handle;
4806 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4807 if (!NT_STATUS_IS_OK(status)) {
4811 ret &= test_Connect(p, torture, &handle);
4813 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4815 ret &= test_samr_handle_Close(p, torture, &handle);