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"
31 #include "param/param.h"
33 #define TEST_ACCOUNT_NAME "samrtorturetest"
34 #define TEST_ALIASNAME "samrtorturetestalias"
35 #define TEST_GROUPNAME "samrtorturetestgroup"
36 #define TEST_MACHINENAME "samrtestmach$"
37 #define TEST_DOMAINNAME "samrtestdom$"
39 enum torture_samr_choice {
40 TORTURE_SAMR_PASSWORDS,
41 TORTURE_SAMR_USER_ATTRIBUTES,
45 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
46 struct policy_handle *handle);
48 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
49 struct policy_handle *handle);
51 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
52 struct policy_handle *handle);
54 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55 const char *acct_name,
56 struct policy_handle *domain_handle, char **password);
58 static void init_lsa_String(struct lsa_String *string, const char *s)
63 bool test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
64 struct policy_handle *handle)
70 r.out.handle = handle;
72 status = dcerpc_samr_Close(p, mem_ctx, &r);
73 if (!NT_STATUS_IS_OK(status)) {
74 printf("Close handle failed - %s\n", nt_errstr(status));
81 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
82 struct policy_handle *handle)
85 struct samr_Shutdown r;
87 if (!torture_setting_bool(tctx, "dangerous", false)) {
88 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
92 r.in.connect_handle = handle;
94 printf("testing samr_Shutdown\n");
96 status = dcerpc_samr_Shutdown(p, tctx, &r);
97 if (!NT_STATUS_IS_OK(status)) {
98 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
118 E_md4hash("TeSTDSRM123", hash.hash);
120 init_lsa_String(&string, "Administrator");
126 printf("testing samr_SetDsrmPassword\n");
128 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
129 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
130 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
138 static bool test_QuerySecurity(struct dcerpc_pipe *p,
139 struct torture_context *tctx,
140 struct policy_handle *handle)
143 struct samr_QuerySecurity r;
144 struct samr_SetSecurity s;
146 r.in.handle = handle;
149 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
150 if (!NT_STATUS_IS_OK(status)) {
151 printf("QuerySecurity failed - %s\n", nt_errstr(status));
155 if (r.out.sdbuf == NULL) {
159 s.in.handle = handle;
161 s.in.sdbuf = r.out.sdbuf;
163 if (torture_setting_bool(tctx, "samba4", false)) {
164 printf("skipping SetSecurity test against Samba4\n");
168 status = dcerpc_samr_SetSecurity(p, tctx, &s);
169 if (!NT_STATUS_IS_OK(status)) {
170 printf("SetSecurity failed - %s\n", nt_errstr(status));
174 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
175 if (!NT_STATUS_IS_OK(status)) {
176 printf("QuerySecurity failed - %s\n", nt_errstr(status));
184 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
185 struct policy_handle *handle, uint32_t base_acct_flags,
186 const char *base_account_name)
189 struct samr_SetUserInfo s;
190 struct samr_SetUserInfo2 s2;
191 struct samr_QueryUserInfo q;
192 struct samr_QueryUserInfo q0;
193 union samr_UserInfo u;
195 const char *test_account_name;
197 uint32_t user_extra_flags = 0;
198 if (base_acct_flags == ACB_NORMAL) {
199 /* When created, accounts are expired by default */
200 user_extra_flags = ACB_PW_EXPIRED;
203 s.in.user_handle = handle;
206 s2.in.user_handle = handle;
209 q.in.user_handle = handle;
213 #define TESTCALL(call, r) \
214 status = dcerpc_samr_ ##call(p, tctx, &r); \
215 if (!NT_STATUS_IS_OK(status)) { \
216 printf(#call " level %u failed - %s (%s)\n", \
217 r.in.level, nt_errstr(status), __location__); \
222 #define STRING_EQUAL(s1, s2, field) \
223 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
224 printf("Failed to set %s to '%s' (%s)\n", \
225 #field, s2, __location__); \
230 #define INT_EQUAL(i1, i2, field) \
232 printf("Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
233 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
238 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
239 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
241 TESTCALL(QueryUserInfo, q) \
243 s2.in.level = lvl1; \
246 ZERO_STRUCT(u.info21); \
247 u.info21.fields_present = fpval; \
249 init_lsa_String(&u.info ## lvl1.field1, value); \
250 TESTCALL(SetUserInfo, s) \
251 TESTCALL(SetUserInfo2, s2) \
252 init_lsa_String(&u.info ## lvl1.field1, ""); \
253 TESTCALL(QueryUserInfo, q); \
255 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
257 TESTCALL(QueryUserInfo, q) \
259 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
262 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
263 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
265 TESTCALL(QueryUserInfo, q) \
267 s2.in.level = lvl1; \
270 uint8_t *bits = u.info21.logon_hours.bits; \
271 ZERO_STRUCT(u.info21); \
272 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
273 u.info21.logon_hours.units_per_week = 168; \
274 u.info21.logon_hours.bits = bits; \
276 u.info21.fields_present = fpval; \
278 u.info ## lvl1.field1 = value; \
279 TESTCALL(SetUserInfo, s) \
280 TESTCALL(SetUserInfo2, s2) \
281 u.info ## lvl1.field1 = 0; \
282 TESTCALL(QueryUserInfo, q); \
284 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
286 TESTCALL(QueryUserInfo, q) \
288 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
291 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
292 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
296 do { TESTCALL(QueryUserInfo, q0) } while (0);
298 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
299 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
300 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
303 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
304 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
305 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
306 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
307 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
308 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
309 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
310 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
311 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
312 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
313 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
314 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
315 test_account_name = base_account_name;
316 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
317 SAMR_FIELD_ACCOUNT_NAME);
319 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
323 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
324 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
325 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
326 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
327 SAMR_FIELD_FULL_NAME);
329 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
333 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
334 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
335 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
336 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
337 SAMR_FIELD_FULL_NAME);
339 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
340 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
341 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
342 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
343 SAMR_FIELD_LOGON_SCRIPT);
345 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
346 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
347 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
348 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
349 SAMR_FIELD_PROFILE_PATH);
351 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
352 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
353 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
354 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
355 SAMR_FIELD_HOME_DIRECTORY);
356 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
357 SAMR_FIELD_HOME_DIRECTORY);
359 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
360 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
361 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
362 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
363 SAMR_FIELD_HOME_DRIVE);
364 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
365 SAMR_FIELD_HOME_DRIVE);
367 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
368 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
369 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
370 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
371 SAMR_FIELD_DESCRIPTION);
373 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
374 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
375 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
376 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
377 SAMR_FIELD_WORKSTATIONS);
378 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
379 SAMR_FIELD_WORKSTATIONS);
380 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
381 SAMR_FIELD_WORKSTATIONS);
382 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
383 SAMR_FIELD_WORKSTATIONS);
385 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
386 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
387 SAMR_FIELD_PARAMETERS);
388 TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
389 SAMR_FIELD_PARAMETERS);
391 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
392 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
393 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
394 SAMR_FIELD_COUNTRY_CODE);
395 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
396 SAMR_FIELD_COUNTRY_CODE);
398 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
399 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
400 SAMR_FIELD_CODE_PAGE);
401 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
402 SAMR_FIELD_CODE_PAGE);
404 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
405 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
406 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
407 SAMR_FIELD_ACCT_EXPIRY);
408 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
409 SAMR_FIELD_ACCT_EXPIRY);
410 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
411 SAMR_FIELD_ACCT_EXPIRY);
413 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
414 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
415 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
416 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
417 SAMR_FIELD_LOGON_HOURS);
419 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
420 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
421 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
423 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
424 (base_acct_flags | ACB_DISABLED),
425 (base_acct_flags | ACB_DISABLED | user_extra_flags),
428 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
429 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
430 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
431 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
433 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
434 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
435 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
439 /* The 'autolock' flag doesn't stick - check this */
440 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
441 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
442 (base_acct_flags | ACB_DISABLED | user_extra_flags),
445 /* Removing the 'disabled' flag doesn't stick - check this */
446 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
448 (base_acct_flags | ACB_DISABLED | user_extra_flags),
451 /* The 'store plaintext' flag does stick */
452 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
453 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
454 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
456 /* The 'use DES' flag does stick */
457 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
458 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
459 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
461 /* The 'don't require kerberos pre-authentication flag does stick */
462 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
463 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
464 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
466 /* The 'no kerberos PAC required' flag sticks */
467 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
468 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
469 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
472 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
473 (base_acct_flags | ACB_DISABLED),
474 (base_acct_flags | ACB_DISABLED | user_extra_flags),
475 SAMR_FIELD_ACCT_FLAGS);
478 /* these fail with win2003 - it appears you can't set the primary gid?
479 the set succeeds, but the gid isn't changed. Very weird! */
480 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
481 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
482 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
483 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
490 generate a random password for password change tests
492 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
494 size_t len = MAX(8, min_len) + (random() % 6);
495 char *s = generate_random_str(mem_ctx, len);
496 printf("Generated password '%s'\n", s);
501 generate a random password for password change tests
503 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
506 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
507 generate_random_buffer(password.data, password.length);
509 for (i=0; i < len; i++) {
510 if (((uint16_t *)password.data)[i] == 0) {
511 ((uint16_t *)password.data)[i] = 1;
519 generate a random password for password change tests (fixed length)
521 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
523 char *s = generate_random_str(mem_ctx, len);
524 printf("Generated password '%s'\n", s);
528 static bool test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
529 struct policy_handle *handle, char **password)
532 struct samr_SetUserInfo s;
533 union samr_UserInfo u;
535 DATA_BLOB session_key;
537 struct samr_GetUserPwInfo pwp;
538 int policy_min_pw_len = 0;
539 pwp.in.user_handle = handle;
541 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
542 if (NT_STATUS_IS_OK(status)) {
543 policy_min_pw_len = pwp.out.info.min_password_length;
545 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
547 s.in.user_handle = handle;
551 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
552 /* w2k3 ignores this length */
553 u.info24.pw_len = strlen_m(newpass) * 2;
555 status = dcerpc_fetch_session_key(p, &session_key);
556 if (!NT_STATUS_IS_OK(status)) {
557 printf("SetUserInfo level %u - no session key - %s\n",
558 s.in.level, nt_errstr(status));
562 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
564 printf("Testing SetUserInfo level 24 (set password)\n");
566 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
567 if (!NT_STATUS_IS_OK(status)) {
568 printf("SetUserInfo level %u failed - %s\n",
569 s.in.level, nt_errstr(status));
579 static bool test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
580 struct policy_handle *handle, uint32_t fields_present,
584 struct samr_SetUserInfo s;
585 union samr_UserInfo u;
587 DATA_BLOB session_key;
589 struct samr_GetUserPwInfo pwp;
590 int policy_min_pw_len = 0;
591 pwp.in.user_handle = handle;
593 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
594 if (NT_STATUS_IS_OK(status)) {
595 policy_min_pw_len = pwp.out.info.min_password_length;
597 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
599 s.in.user_handle = handle;
605 u.info23.info.fields_present = fields_present;
607 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
609 status = dcerpc_fetch_session_key(p, &session_key);
610 if (!NT_STATUS_IS_OK(status)) {
611 printf("SetUserInfo level %u - no session key - %s\n",
612 s.in.level, nt_errstr(status));
616 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
618 printf("Testing SetUserInfo level 23 (set password)\n");
620 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
621 if (!NT_STATUS_IS_OK(status)) {
622 printf("SetUserInfo level %u failed - %s\n",
623 s.in.level, nt_errstr(status));
629 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
631 status = dcerpc_fetch_session_key(p, &session_key);
632 if (!NT_STATUS_IS_OK(status)) {
633 printf("SetUserInfo level %u - no session key - %s\n",
634 s.in.level, nt_errstr(status));
638 /* This should break the key nicely */
639 session_key.length--;
640 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
642 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
644 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
645 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
646 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
647 s.in.level, nt_errstr(status));
655 static bool test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
656 struct policy_handle *handle, bool makeshort,
660 struct samr_SetUserInfo s;
661 union samr_UserInfo u;
663 DATA_BLOB session_key;
664 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
665 uint8_t confounder[16];
667 struct MD5Context ctx;
668 struct samr_GetUserPwInfo pwp;
669 int policy_min_pw_len = 0;
670 pwp.in.user_handle = handle;
672 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
673 if (NT_STATUS_IS_OK(status)) {
674 policy_min_pw_len = pwp.out.info.min_password_length;
676 if (makeshort && policy_min_pw_len) {
677 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
679 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
682 s.in.user_handle = handle;
686 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
687 u.info26.pw_len = strlen(newpass);
689 status = dcerpc_fetch_session_key(p, &session_key);
690 if (!NT_STATUS_IS_OK(status)) {
691 printf("SetUserInfo level %u - no session key - %s\n",
692 s.in.level, nt_errstr(status));
696 generate_random_buffer((uint8_t *)confounder, 16);
699 MD5Update(&ctx, confounder, 16);
700 MD5Update(&ctx, session_key.data, session_key.length);
701 MD5Final(confounded_session_key.data, &ctx);
703 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
704 memcpy(&u.info26.password.data[516], confounder, 16);
706 printf("Testing SetUserInfo level 26 (set password ex)\n");
708 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
709 if (!NT_STATUS_IS_OK(status)) {
710 printf("SetUserInfo level %u failed - %s\n",
711 s.in.level, nt_errstr(status));
717 /* This should break the key nicely */
718 confounded_session_key.data[0]++;
720 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
721 memcpy(&u.info26.password.data[516], confounder, 16);
723 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
725 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
726 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
727 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
728 s.in.level, nt_errstr(status));
737 static bool test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
738 struct policy_handle *handle, uint32_t fields_present,
742 struct samr_SetUserInfo s;
743 union samr_UserInfo u;
745 DATA_BLOB session_key;
746 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
747 struct MD5Context ctx;
748 uint8_t confounder[16];
750 struct samr_GetUserPwInfo pwp;
751 int policy_min_pw_len = 0;
752 pwp.in.user_handle = handle;
754 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
755 if (NT_STATUS_IS_OK(status)) {
756 policy_min_pw_len = pwp.out.info.min_password_length;
758 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
760 s.in.user_handle = handle;
766 u.info25.info.fields_present = fields_present;
768 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
770 status = dcerpc_fetch_session_key(p, &session_key);
771 if (!NT_STATUS_IS_OK(status)) {
772 printf("SetUserInfo level %u - no session key - %s\n",
773 s.in.level, nt_errstr(status));
777 generate_random_buffer((uint8_t *)confounder, 16);
780 MD5Update(&ctx, confounder, 16);
781 MD5Update(&ctx, session_key.data, session_key.length);
782 MD5Final(confounded_session_key.data, &ctx);
784 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
785 memcpy(&u.info25.password.data[516], confounder, 16);
787 printf("Testing SetUserInfo level 25 (set password ex)\n");
789 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
790 if (!NT_STATUS_IS_OK(status)) {
791 printf("SetUserInfo level %u failed - %s\n",
792 s.in.level, nt_errstr(status));
798 /* This should break the key nicely */
799 confounded_session_key.data[0]++;
801 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
802 memcpy(&u.info25.password.data[516], confounder, 16);
804 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
806 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
807 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
808 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
809 s.in.level, nt_errstr(status));
816 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
817 struct policy_handle *handle)
820 struct samr_SetAliasInfo r;
821 struct samr_QueryAliasInfo q;
822 uint16_t levels[] = {2, 3};
826 /* Ignoring switch level 1, as that includes the number of members for the alias
827 * and setting this to a wrong value might have negative consequences
830 for (i=0;i<ARRAY_SIZE(levels);i++) {
831 printf("Testing SetAliasInfo level %u\n", levels[i]);
833 r.in.alias_handle = handle;
834 r.in.level = levels[i];
835 r.in.info = talloc(tctx, union samr_AliasInfo);
836 switch (r.in.level) {
837 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
838 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
839 "Test Description, should test I18N as well"); break;
840 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
843 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
844 if (!NT_STATUS_IS_OK(status)) {
845 printf("SetAliasInfo level %u failed - %s\n",
846 levels[i], nt_errstr(status));
850 q.in.alias_handle = handle;
851 q.in.level = levels[i];
853 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
854 if (!NT_STATUS_IS_OK(status)) {
855 printf("QueryAliasInfo level %u failed - %s\n",
856 levels[i], nt_errstr(status));
864 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
865 struct policy_handle *user_handle)
867 struct samr_GetGroupsForUser r;
871 printf("testing GetGroupsForUser\n");
873 r.in.user_handle = user_handle;
875 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
876 if (!NT_STATUS_IS_OK(status)) {
877 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
885 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
886 struct lsa_String *domain_name)
889 struct samr_GetDomPwInfo r;
892 r.in.domain_name = domain_name;
893 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
895 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
896 if (!NT_STATUS_IS_OK(status)) {
897 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
901 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
902 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
904 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
905 if (!NT_STATUS_IS_OK(status)) {
906 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
910 r.in.domain_name->string = "\\\\__NONAME__";
911 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
913 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
914 if (!NT_STATUS_IS_OK(status)) {
915 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
919 r.in.domain_name->string = "\\\\Builtin";
920 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
922 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
923 if (!NT_STATUS_IS_OK(status)) {
924 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
932 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
933 struct policy_handle *handle)
936 struct samr_GetUserPwInfo r;
939 printf("Testing GetUserPwInfo\n");
941 r.in.user_handle = handle;
943 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
944 if (!NT_STATUS_IS_OK(status)) {
945 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
952 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
953 struct policy_handle *domain_handle, const char *name,
957 struct samr_LookupNames n;
958 struct lsa_String sname[2];
960 init_lsa_String(&sname[0], name);
962 n.in.domain_handle = domain_handle;
965 status = dcerpc_samr_LookupNames(p, tctx, &n);
966 if (NT_STATUS_IS_OK(status)) {
967 *rid = n.out.rids.ids[0];
972 init_lsa_String(&sname[1], "xxNONAMExx");
974 status = dcerpc_samr_LookupNames(p, tctx, &n);
975 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
976 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
977 if (NT_STATUS_IS_OK(status)) {
978 return NT_STATUS_UNSUCCESSFUL;
984 status = dcerpc_samr_LookupNames(p, tctx, &n);
985 if (!NT_STATUS_IS_OK(status)) {
986 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
990 init_lsa_String(&sname[0], "xxNONAMExx");
992 status = dcerpc_samr_LookupNames(p, tctx, &n);
993 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
994 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
995 if (NT_STATUS_IS_OK(status)) {
996 return NT_STATUS_UNSUCCESSFUL;
1001 init_lsa_String(&sname[0], "xxNONAMExx");
1002 init_lsa_String(&sname[1], "xxNONAME2xx");
1004 status = dcerpc_samr_LookupNames(p, tctx, &n);
1005 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1006 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1007 if (NT_STATUS_IS_OK(status)) {
1008 return NT_STATUS_UNSUCCESSFUL;
1013 return NT_STATUS_OK;
1016 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1017 struct policy_handle *domain_handle,
1018 const char *name, struct policy_handle *user_handle)
1021 struct samr_OpenUser r;
1024 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1025 if (!NT_STATUS_IS_OK(status)) {
1029 r.in.domain_handle = domain_handle;
1030 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1032 r.out.user_handle = user_handle;
1033 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1034 if (!NT_STATUS_IS_OK(status)) {
1035 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1042 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1043 struct policy_handle *handle)
1046 struct samr_ChangePasswordUser r;
1048 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1049 struct policy_handle user_handle;
1050 char *oldpass = "test";
1051 char *newpass = "test2";
1052 uint8_t old_nt_hash[16], new_nt_hash[16];
1053 uint8_t old_lm_hash[16], new_lm_hash[16];
1055 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1056 if (!NT_STATUS_IS_OK(status)) {
1060 printf("Testing ChangePasswordUser for user 'testuser'\n");
1062 printf("old password: %s\n", oldpass);
1063 printf("new password: %s\n", newpass);
1065 E_md4hash(oldpass, old_nt_hash);
1066 E_md4hash(newpass, new_nt_hash);
1067 E_deshash(oldpass, old_lm_hash);
1068 E_deshash(newpass, new_lm_hash);
1070 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1071 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1072 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1073 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1074 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1075 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1077 r.in.handle = &user_handle;
1078 r.in.lm_present = 1;
1079 r.in.old_lm_crypted = &hash1;
1080 r.in.new_lm_crypted = &hash2;
1081 r.in.nt_present = 1;
1082 r.in.old_nt_crypted = &hash3;
1083 r.in.new_nt_crypted = &hash4;
1084 r.in.cross1_present = 1;
1085 r.in.nt_cross = &hash5;
1086 r.in.cross2_present = 1;
1087 r.in.lm_cross = &hash6;
1089 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1090 if (!NT_STATUS_IS_OK(status)) {
1091 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1095 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1103 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1104 const char *acct_name,
1105 struct policy_handle *handle, char **password)
1108 struct samr_ChangePasswordUser r;
1110 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1111 struct policy_handle user_handle;
1113 uint8_t old_nt_hash[16], new_nt_hash[16];
1114 uint8_t old_lm_hash[16], new_lm_hash[16];
1115 bool changed = true;
1118 struct samr_GetUserPwInfo pwp;
1119 int policy_min_pw_len = 0;
1121 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1122 if (!NT_STATUS_IS_OK(status)) {
1125 pwp.in.user_handle = &user_handle;
1127 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1128 if (NT_STATUS_IS_OK(status)) {
1129 policy_min_pw_len = pwp.out.info.min_password_length;
1131 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1133 printf("Testing ChangePasswordUser\n");
1136 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1140 oldpass = *password;
1142 E_md4hash(oldpass, old_nt_hash);
1143 E_md4hash(newpass, new_nt_hash);
1144 E_deshash(oldpass, old_lm_hash);
1145 E_deshash(newpass, new_lm_hash);
1147 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1148 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1149 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1150 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1151 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1152 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1154 r.in.user_handle = &user_handle;
1155 r.in.lm_present = 1;
1156 /* Break the LM hash */
1158 r.in.old_lm_crypted = &hash1;
1159 r.in.new_lm_crypted = &hash2;
1160 r.in.nt_present = 1;
1161 r.in.old_nt_crypted = &hash3;
1162 r.in.new_nt_crypted = &hash4;
1163 r.in.cross1_present = 1;
1164 r.in.nt_cross = &hash5;
1165 r.in.cross2_present = 1;
1166 r.in.lm_cross = &hash6;
1168 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1169 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1170 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1174 /* Unbreak the LM hash */
1177 r.in.user_handle = &user_handle;
1178 r.in.lm_present = 1;
1179 r.in.old_lm_crypted = &hash1;
1180 r.in.new_lm_crypted = &hash2;
1181 /* Break the NT hash */
1183 r.in.nt_present = 1;
1184 r.in.old_nt_crypted = &hash3;
1185 r.in.new_nt_crypted = &hash4;
1186 r.in.cross1_present = 1;
1187 r.in.nt_cross = &hash5;
1188 r.in.cross2_present = 1;
1189 r.in.lm_cross = &hash6;
1191 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1192 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1193 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1197 /* Unbreak the NT hash */
1200 r.in.user_handle = &user_handle;
1201 r.in.lm_present = 1;
1202 r.in.old_lm_crypted = &hash1;
1203 r.in.new_lm_crypted = &hash2;
1204 r.in.nt_present = 1;
1205 r.in.old_nt_crypted = &hash3;
1206 r.in.new_nt_crypted = &hash4;
1207 r.in.cross1_present = 1;
1208 r.in.nt_cross = &hash5;
1209 r.in.cross2_present = 1;
1210 /* Break the LM cross */
1212 r.in.lm_cross = &hash6;
1214 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1215 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1216 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1220 /* Unbreak the LM cross */
1223 r.in.user_handle = &user_handle;
1224 r.in.lm_present = 1;
1225 r.in.old_lm_crypted = &hash1;
1226 r.in.new_lm_crypted = &hash2;
1227 r.in.nt_present = 1;
1228 r.in.old_nt_crypted = &hash3;
1229 r.in.new_nt_crypted = &hash4;
1230 r.in.cross1_present = 1;
1231 /* Break the NT cross */
1233 r.in.nt_cross = &hash5;
1234 r.in.cross2_present = 1;
1235 r.in.lm_cross = &hash6;
1237 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1238 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1239 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1243 /* Unbreak the NT cross */
1247 /* Reset the hashes to not broken values */
1248 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1249 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1250 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1251 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1252 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1253 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1255 r.in.user_handle = &user_handle;
1256 r.in.lm_present = 1;
1257 r.in.old_lm_crypted = &hash1;
1258 r.in.new_lm_crypted = &hash2;
1259 r.in.nt_present = 1;
1260 r.in.old_nt_crypted = &hash3;
1261 r.in.new_nt_crypted = &hash4;
1262 r.in.cross1_present = 1;
1263 r.in.nt_cross = &hash5;
1264 r.in.cross2_present = 0;
1265 r.in.lm_cross = NULL;
1267 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1268 if (NT_STATUS_IS_OK(status)) {
1270 *password = newpass;
1271 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1272 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1277 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1279 E_md4hash(oldpass, old_nt_hash);
1280 E_md4hash(newpass, new_nt_hash);
1281 E_deshash(oldpass, old_lm_hash);
1282 E_deshash(newpass, new_lm_hash);
1285 /* Reset the hashes to not broken values */
1286 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1287 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1288 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1289 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1290 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1291 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1293 r.in.user_handle = &user_handle;
1294 r.in.lm_present = 1;
1295 r.in.old_lm_crypted = &hash1;
1296 r.in.new_lm_crypted = &hash2;
1297 r.in.nt_present = 1;
1298 r.in.old_nt_crypted = &hash3;
1299 r.in.new_nt_crypted = &hash4;
1300 r.in.cross1_present = 0;
1301 r.in.nt_cross = NULL;
1302 r.in.cross2_present = 1;
1303 r.in.lm_cross = &hash6;
1305 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1306 if (NT_STATUS_IS_OK(status)) {
1308 *password = newpass;
1309 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1310 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1315 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1317 E_md4hash(oldpass, old_nt_hash);
1318 E_md4hash(newpass, new_nt_hash);
1319 E_deshash(oldpass, old_lm_hash);
1320 E_deshash(newpass, new_lm_hash);
1323 /* Reset the hashes to not broken values */
1324 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1325 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1326 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1327 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1328 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1329 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1331 r.in.user_handle = &user_handle;
1332 r.in.lm_present = 1;
1333 r.in.old_lm_crypted = &hash1;
1334 r.in.new_lm_crypted = &hash2;
1335 r.in.nt_present = 1;
1336 r.in.old_nt_crypted = &hash3;
1337 r.in.new_nt_crypted = &hash4;
1338 r.in.cross1_present = 1;
1339 r.in.nt_cross = &hash5;
1340 r.in.cross2_present = 1;
1341 r.in.lm_cross = &hash6;
1343 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1344 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1345 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1346 } else if (!NT_STATUS_IS_OK(status)) {
1347 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1351 *password = newpass;
1354 r.in.user_handle = &user_handle;
1355 r.in.lm_present = 1;
1356 r.in.old_lm_crypted = &hash1;
1357 r.in.new_lm_crypted = &hash2;
1358 r.in.nt_present = 1;
1359 r.in.old_nt_crypted = &hash3;
1360 r.in.new_nt_crypted = &hash4;
1361 r.in.cross1_present = 1;
1362 r.in.nt_cross = &hash5;
1363 r.in.cross2_present = 1;
1364 r.in.lm_cross = &hash6;
1367 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1368 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1369 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1370 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1371 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1377 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1385 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1386 const char *acct_name,
1387 struct policy_handle *handle, char **password)
1390 struct samr_OemChangePasswordUser2 r;
1392 struct samr_Password lm_verifier;
1393 struct samr_CryptPassword lm_pass;
1394 struct lsa_AsciiString server, account, account_bad;
1397 uint8_t old_lm_hash[16], new_lm_hash[16];
1399 struct samr_GetDomPwInfo dom_pw_info;
1400 int policy_min_pw_len = 0;
1402 struct lsa_String domain_name;
1404 domain_name.string = "";
1405 dom_pw_info.in.domain_name = &domain_name;
1407 printf("Testing OemChangePasswordUser2\n");
1410 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1414 oldpass = *password;
1416 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1417 if (NT_STATUS_IS_OK(status)) {
1418 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1421 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1423 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1424 account.string = acct_name;
1426 E_deshash(oldpass, old_lm_hash);
1427 E_deshash(newpass, new_lm_hash);
1429 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1430 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1431 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1433 r.in.server = &server;
1434 r.in.account = &account;
1435 r.in.password = &lm_pass;
1436 r.in.hash = &lm_verifier;
1438 /* Break the verification */
1439 lm_verifier.hash[0]++;
1441 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1443 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1444 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1445 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1450 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1451 /* Break the old password */
1453 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1454 /* unbreak it for the next operation */
1456 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1458 r.in.server = &server;
1459 r.in.account = &account;
1460 r.in.password = &lm_pass;
1461 r.in.hash = &lm_verifier;
1463 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1465 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1466 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1467 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1472 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1473 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1475 r.in.server = &server;
1476 r.in.account = &account;
1477 r.in.password = &lm_pass;
1480 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1482 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1483 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1484 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1489 /* This shouldn't be a valid name */
1490 account_bad.string = TEST_ACCOUNT_NAME "XX";
1491 r.in.account = &account_bad;
1493 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1495 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1496 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1501 /* This shouldn't be a valid name */
1502 account_bad.string = TEST_ACCOUNT_NAME "XX";
1503 r.in.account = &account_bad;
1504 r.in.password = &lm_pass;
1505 r.in.hash = &lm_verifier;
1507 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1509 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1510 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1515 /* This shouldn't be a valid name */
1516 account_bad.string = TEST_ACCOUNT_NAME "XX";
1517 r.in.account = &account_bad;
1518 r.in.password = NULL;
1519 r.in.hash = &lm_verifier;
1521 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1523 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1524 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1529 E_deshash(oldpass, old_lm_hash);
1530 E_deshash(newpass, new_lm_hash);
1532 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1533 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1534 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1536 r.in.server = &server;
1537 r.in.account = &account;
1538 r.in.password = &lm_pass;
1539 r.in.hash = &lm_verifier;
1541 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1542 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1543 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1544 } else if (!NT_STATUS_IS_OK(status)) {
1545 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1548 *password = newpass;
1555 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1556 const char *acct_name,
1558 char *newpass, bool allow_password_restriction)
1561 struct samr_ChangePasswordUser2 r;
1563 struct lsa_String server, account;
1564 struct samr_CryptPassword nt_pass, lm_pass;
1565 struct samr_Password nt_verifier, lm_verifier;
1567 uint8_t old_nt_hash[16], new_nt_hash[16];
1568 uint8_t old_lm_hash[16], new_lm_hash[16];
1570 struct samr_GetDomPwInfo dom_pw_info;
1572 struct lsa_String domain_name;
1574 domain_name.string = "";
1575 dom_pw_info.in.domain_name = &domain_name;
1577 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1580 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1583 oldpass = *password;
1586 int policy_min_pw_len = 0;
1587 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1588 if (NT_STATUS_IS_OK(status)) {
1589 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1592 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1595 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1596 init_lsa_String(&account, acct_name);
1598 E_md4hash(oldpass, old_nt_hash);
1599 E_md4hash(newpass, new_nt_hash);
1601 E_deshash(oldpass, old_lm_hash);
1602 E_deshash(newpass, new_lm_hash);
1604 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1605 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1606 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1608 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1609 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1610 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1612 r.in.server = &server;
1613 r.in.account = &account;
1614 r.in.nt_password = &nt_pass;
1615 r.in.nt_verifier = &nt_verifier;
1617 r.in.lm_password = &lm_pass;
1618 r.in.lm_verifier = &lm_verifier;
1620 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1621 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1622 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1623 } else if (!NT_STATUS_IS_OK(status)) {
1624 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1627 *password = newpass;
1634 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1635 const char *account_string,
1636 int policy_min_pw_len,
1638 const char *newpass,
1639 NTTIME last_password_change,
1640 bool handle_reject_reason)
1643 struct samr_ChangePasswordUser3 r;
1645 struct lsa_String server, account, account_bad;
1646 struct samr_CryptPassword nt_pass, lm_pass;
1647 struct samr_Password nt_verifier, lm_verifier;
1649 uint8_t old_nt_hash[16], new_nt_hash[16];
1650 uint8_t old_lm_hash[16], new_lm_hash[16];
1653 printf("Testing ChangePasswordUser3\n");
1655 if (newpass == NULL) {
1657 if (policy_min_pw_len == 0) {
1658 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1660 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1662 } while (check_password_quality(newpass) == false);
1664 printf("Using password '%s'\n", newpass);
1668 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1672 oldpass = *password;
1673 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1674 init_lsa_String(&account, account_string);
1676 E_md4hash(oldpass, old_nt_hash);
1677 E_md4hash(newpass, new_nt_hash);
1679 E_deshash(oldpass, old_lm_hash);
1680 E_deshash(newpass, new_lm_hash);
1682 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1683 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1684 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1686 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1687 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1688 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1690 /* Break the verification */
1691 nt_verifier.hash[0]++;
1693 r.in.server = &server;
1694 r.in.account = &account;
1695 r.in.nt_password = &nt_pass;
1696 r.in.nt_verifier = &nt_verifier;
1698 r.in.lm_password = &lm_pass;
1699 r.in.lm_verifier = &lm_verifier;
1700 r.in.password3 = NULL;
1702 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1703 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1704 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1705 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1710 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1711 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1712 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1714 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1715 /* Break the NT hash */
1717 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1718 /* Unbreak it again */
1720 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1722 r.in.server = &server;
1723 r.in.account = &account;
1724 r.in.nt_password = &nt_pass;
1725 r.in.nt_verifier = &nt_verifier;
1727 r.in.lm_password = &lm_pass;
1728 r.in.lm_verifier = &lm_verifier;
1729 r.in.password3 = NULL;
1731 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1732 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1733 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1734 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1739 /* This shouldn't be a valid name */
1740 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1742 r.in.account = &account_bad;
1743 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1744 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1745 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1750 E_md4hash(oldpass, old_nt_hash);
1751 E_md4hash(newpass, new_nt_hash);
1753 E_deshash(oldpass, old_lm_hash);
1754 E_deshash(newpass, new_lm_hash);
1756 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1757 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1758 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1760 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1761 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1762 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1764 r.in.server = &server;
1765 r.in.account = &account;
1766 r.in.nt_password = &nt_pass;
1767 r.in.nt_verifier = &nt_verifier;
1769 r.in.lm_password = &lm_pass;
1770 r.in.lm_verifier = &lm_verifier;
1771 r.in.password3 = NULL;
1773 unix_to_nt_time(&t, time(NULL));
1775 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1777 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1780 && handle_reject_reason
1781 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1782 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1784 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1785 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1786 SAMR_REJECT_OTHER, r.out.reject->reason);
1791 /* We tested the order of precendence which is as follows:
1800 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1801 (last_password_change + r.out.dominfo->min_password_age > t)) {
1803 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1804 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1805 SAMR_REJECT_OTHER, r.out.reject->reason);
1809 } else if ((r.out.dominfo->min_password_length > 0) &&
1810 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1812 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1813 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1814 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1818 } else if ((r.out.dominfo->password_history_length > 0) &&
1819 strequal(oldpass, newpass)) {
1821 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1822 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1823 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1826 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1828 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1829 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1830 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1836 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1837 /* retry with adjusted size */
1838 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1839 r.out.dominfo->min_password_length,
1840 password, NULL, 0, false);
1844 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1845 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1846 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1847 SAMR_REJECT_OTHER, r.out.reject->reason);
1850 /* Perhaps the server has a 'min password age' set? */
1852 } else if (!NT_STATUS_IS_OK(status)) {
1853 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1856 *password = talloc_strdup(mem_ctx, newpass);
1862 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1863 const char *account_string,
1864 struct policy_handle *handle,
1868 struct samr_ChangePasswordUser3 r;
1869 struct samr_SetUserInfo s;
1870 union samr_UserInfo u;
1871 DATA_BLOB session_key;
1872 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
1873 uint8_t confounder[16];
1874 struct MD5Context ctx;
1877 struct lsa_String server, account;
1878 struct samr_CryptPassword nt_pass;
1879 struct samr_Password nt_verifier;
1880 DATA_BLOB new_random_pass;
1883 uint8_t old_nt_hash[16], new_nt_hash[16];
1886 new_random_pass = samr_very_rand_pass(mem_ctx, 128);
1889 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1893 oldpass = *password;
1894 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1895 init_lsa_String(&account, account_string);
1897 s.in.user_handle = handle;
1903 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1905 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1907 status = dcerpc_fetch_session_key(p, &session_key);
1908 if (!NT_STATUS_IS_OK(status)) {
1909 printf("SetUserInfo level %u - no session key - %s\n",
1910 s.in.level, nt_errstr(status));
1914 generate_random_buffer((uint8_t *)confounder, 16);
1917 MD5Update(&ctx, confounder, 16);
1918 MD5Update(&ctx, session_key.data, session_key.length);
1919 MD5Final(confounded_session_key.data, &ctx);
1921 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1922 memcpy(&u.info25.password.data[516], confounder, 16);
1924 printf("Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1926 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
1927 if (!NT_STATUS_IS_OK(status)) {
1928 printf("SetUserInfo level %u failed - %s\n",
1929 s.in.level, nt_errstr(status));
1933 printf("Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1935 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1937 new_random_pass = samr_very_rand_pass(mem_ctx, 128);
1939 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1941 set_pw_in_buffer(nt_pass.data, &new_random_pass);
1942 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1943 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1945 r.in.server = &server;
1946 r.in.account = &account;
1947 r.in.nt_password = &nt_pass;
1948 r.in.nt_verifier = &nt_verifier;
1950 r.in.lm_password = NULL;
1951 r.in.lm_verifier = NULL;
1952 r.in.password3 = NULL;
1954 unix_to_nt_time(&t, time(NULL));
1956 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1958 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1959 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1960 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1961 SAMR_REJECT_OTHER, r.out.reject->reason);
1964 /* Perhaps the server has a 'min password age' set? */
1966 } else if (!NT_STATUS_IS_OK(status)) {
1967 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1971 newpass = samr_rand_pass(mem_ctx, 128);
1973 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1975 E_md4hash(newpass, new_nt_hash);
1977 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1978 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1979 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1981 r.in.server = &server;
1982 r.in.account = &account;
1983 r.in.nt_password = &nt_pass;
1984 r.in.nt_verifier = &nt_verifier;
1986 r.in.lm_password = NULL;
1987 r.in.lm_verifier = NULL;
1988 r.in.password3 = NULL;
1990 unix_to_nt_time(&t, time(NULL));
1992 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1994 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1995 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1996 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1997 SAMR_REJECT_OTHER, r.out.reject->reason);
2000 /* Perhaps the server has a 'min password age' set? */
2002 } else if (!NT_STATUS_IS_OK(status)) {
2003 printf("ChangePasswordUser3 (on second random password) failed - %s\n", nt_errstr(status));
2006 *password = talloc_strdup(mem_ctx, newpass);
2013 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2014 struct policy_handle *alias_handle)
2016 struct samr_GetMembersInAlias r;
2017 struct lsa_SidArray sids;
2021 printf("Testing GetMembersInAlias\n");
2023 r.in.alias_handle = alias_handle;
2026 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
2027 if (!NT_STATUS_IS_OK(status)) {
2028 printf("GetMembersInAlias failed - %s\n",
2036 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2037 struct policy_handle *alias_handle,
2038 const struct dom_sid *domain_sid)
2040 struct samr_AddAliasMember r;
2041 struct samr_DeleteAliasMember d;
2044 struct dom_sid *sid;
2046 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
2048 printf("testing AddAliasMember\n");
2049 r.in.alias_handle = alias_handle;
2052 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
2053 if (!NT_STATUS_IS_OK(status)) {
2054 printf("AddAliasMember failed - %s\n", nt_errstr(status));
2058 d.in.alias_handle = alias_handle;
2061 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
2062 if (!NT_STATUS_IS_OK(status)) {
2063 printf("DelAliasMember failed - %s\n", nt_errstr(status));
2070 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2071 struct policy_handle *alias_handle)
2073 struct samr_AddMultipleMembersToAlias a;
2074 struct samr_RemoveMultipleMembersFromAlias r;
2077 struct lsa_SidArray sids;
2079 printf("testing AddMultipleMembersToAlias\n");
2080 a.in.alias_handle = alias_handle;
2084 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
2086 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
2087 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
2088 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
2090 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
2091 if (!NT_STATUS_IS_OK(status)) {
2092 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
2097 printf("testing RemoveMultipleMembersFromAlias\n");
2098 r.in.alias_handle = alias_handle;
2101 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2102 if (!NT_STATUS_IS_OK(status)) {
2103 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2107 /* strange! removing twice doesn't give any error */
2108 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2109 if (!NT_STATUS_IS_OK(status)) {
2110 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2114 /* but removing an alias that isn't there does */
2115 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
2117 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2118 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
2119 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2126 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2127 struct policy_handle *user_handle)
2129 struct samr_TestPrivateFunctionsUser r;
2133 printf("Testing TestPrivateFunctionsUser\n");
2135 r.in.user_handle = user_handle;
2137 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
2138 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2139 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
2147 static bool test_user_ops(struct dcerpc_pipe *p,
2148 struct torture_context *tctx,
2149 struct policy_handle *user_handle,
2150 struct policy_handle *domain_handle,
2151 uint32_t base_acct_flags,
2152 const char *base_acct_name, enum torture_samr_choice which_ops)
2154 char *password = NULL;
2155 struct samr_QueryUserInfo q;
2161 const uint32_t password_fields[] = {
2162 SAMR_FIELD_PASSWORD,
2163 SAMR_FIELD_PASSWORD2,
2164 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2168 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2169 if (!NT_STATUS_IS_OK(status)) {
2173 switch (which_ops) {
2174 case TORTURE_SAMR_USER_ATTRIBUTES:
2175 if (!test_QuerySecurity(p, tctx, user_handle)) {
2179 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2183 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2187 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2192 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2196 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2200 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2204 case TORTURE_SAMR_PASSWORDS:
2205 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2206 char simple_pass[9];
2207 char *v = generate_random_str(tctx, 1);
2209 ZERO_STRUCT(simple_pass);
2210 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2212 printf("Testing machine account password policy rules\n");
2214 /* Workstation trust accounts don't seem to need to honour password quality policy */
2215 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2219 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2223 /* reset again, to allow another 'user' password change */
2224 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2228 /* Try a 'short' password */
2229 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2233 /* Try a compleatly random password */
2234 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2239 for (i = 0; password_fields[i]; i++) {
2240 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2244 /* check it was set right */
2245 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2250 for (i = 0; password_fields[i]; i++) {
2251 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2255 /* check it was set right */
2256 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2261 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2265 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2269 q.in.user_handle = user_handle;
2272 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2273 if (!NT_STATUS_IS_OK(status)) {
2274 printf("QueryUserInfo level %u failed - %s\n",
2275 q.in.level, nt_errstr(status));
2278 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2279 if ((q.out.info->info5.acct_flags) != expected_flags) {
2280 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2281 q.out.info->info5.acct_flags,
2285 if (q.out.info->info5.rid != rid) {
2286 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2287 q.out.info->info5.rid, rid);
2293 case TORTURE_SAMR_OTHER:
2294 /* We just need the account to exist */
2300 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2301 struct policy_handle *alias_handle,
2302 const struct dom_sid *domain_sid)
2306 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2310 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2314 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2318 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2322 if (torture_setting_bool(tctx, "samba4", false)) {
2323 printf("skipping MultipleMembers Alias tests against Samba4\n");
2327 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2335 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2336 struct policy_handle *user_handle)
2338 struct samr_DeleteUser d;
2341 printf("Testing DeleteUser\n");
2343 d.in.user_handle = user_handle;
2344 d.out.user_handle = user_handle;
2346 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2347 if (!NT_STATUS_IS_OK(status)) {
2348 printf("DeleteUser failed - %s\n", nt_errstr(status));
2355 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2356 struct policy_handle *handle, const char *name)
2359 struct samr_DeleteUser d;
2360 struct policy_handle user_handle;
2363 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2364 if (!NT_STATUS_IS_OK(status)) {
2368 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2369 if (!NT_STATUS_IS_OK(status)) {
2373 d.in.user_handle = &user_handle;
2374 d.out.user_handle = &user_handle;
2375 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2376 if (!NT_STATUS_IS_OK(status)) {
2383 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2388 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2389 struct policy_handle *handle, const char *name)
2392 struct samr_OpenGroup r;
2393 struct samr_DeleteDomainGroup d;
2394 struct policy_handle group_handle;
2397 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2398 if (!NT_STATUS_IS_OK(status)) {
2402 r.in.domain_handle = handle;
2403 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2405 r.out.group_handle = &group_handle;
2406 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2407 if (!NT_STATUS_IS_OK(status)) {
2411 d.in.group_handle = &group_handle;
2412 d.out.group_handle = &group_handle;
2413 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2414 if (!NT_STATUS_IS_OK(status)) {
2421 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2426 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2427 struct policy_handle *domain_handle, const char *name)
2430 struct samr_OpenAlias r;
2431 struct samr_DeleteDomAlias d;
2432 struct policy_handle alias_handle;
2435 printf("testing DeleteAlias_byname\n");
2437 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2438 if (!NT_STATUS_IS_OK(status)) {
2442 r.in.domain_handle = domain_handle;
2443 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2445 r.out.alias_handle = &alias_handle;
2446 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2447 if (!NT_STATUS_IS_OK(status)) {
2451 d.in.alias_handle = &alias_handle;
2452 d.out.alias_handle = &alias_handle;
2453 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2454 if (!NT_STATUS_IS_OK(status)) {
2461 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2465 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2466 struct policy_handle *alias_handle)
2468 struct samr_DeleteDomAlias d;
2471 printf("Testing DeleteAlias\n");
2473 d.in.alias_handle = alias_handle;
2474 d.out.alias_handle = alias_handle;
2476 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2477 if (!NT_STATUS_IS_OK(status)) {
2478 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2485 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2486 struct policy_handle *domain_handle,
2487 struct policy_handle *alias_handle,
2488 const struct dom_sid *domain_sid)
2491 struct samr_CreateDomAlias r;
2492 struct lsa_String name;
2496 init_lsa_String(&name, TEST_ALIASNAME);
2497 r.in.domain_handle = domain_handle;
2498 r.in.alias_name = &name;
2499 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2500 r.out.alias_handle = alias_handle;
2503 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2505 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2507 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2508 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2509 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2512 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2518 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2519 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2522 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2525 if (!NT_STATUS_IS_OK(status)) {
2526 printf("CreateAlias failed - %s\n", nt_errstr(status));
2530 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2537 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2538 const char *acct_name,
2539 struct policy_handle *domain_handle, char **password)
2547 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2551 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2555 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2559 /* test what happens when setting the old password again */
2560 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2565 char simple_pass[9];
2566 char *v = generate_random_str(mem_ctx, 1);
2568 ZERO_STRUCT(simple_pass);
2569 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2571 /* test what happens when picking a simple password */
2572 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2577 /* set samr_SetDomainInfo level 1 with min_length 5 */
2579 struct samr_QueryDomainInfo r;
2580 struct samr_SetDomainInfo s;
2581 uint16_t len_old, len;
2582 uint32_t pwd_prop_old;
2583 int64_t min_pwd_age_old;
2588 r.in.domain_handle = domain_handle;
2591 printf("testing samr_QueryDomainInfo level 1\n");
2592 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2593 if (!NT_STATUS_IS_OK(status)) {
2597 s.in.domain_handle = domain_handle;
2599 s.in.info = r.out.info;
2601 /* remember the old min length, so we can reset it */
2602 len_old = s.in.info->info1.min_password_length;
2603 s.in.info->info1.min_password_length = len;
2604 pwd_prop_old = s.in.info->info1.password_properties;
2605 /* turn off password complexity checks for this test */
2606 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2608 min_pwd_age_old = s.in.info->info1.min_password_age;
2609 s.in.info->info1.min_password_age = 0;
2611 printf("testing samr_SetDomainInfo level 1\n");
2612 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2613 if (!NT_STATUS_IS_OK(status)) {
2617 printf("calling test_ChangePasswordUser3 with too short password\n");
2619 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2623 s.in.info->info1.min_password_length = len_old;
2624 s.in.info->info1.password_properties = pwd_prop_old;
2625 s.in.info->info1.min_password_age = min_pwd_age_old;
2627 printf("testing samr_SetDomainInfo level 1\n");
2628 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2629 if (!NT_STATUS_IS_OK(status)) {
2637 struct samr_OpenUser r;
2638 struct samr_QueryUserInfo q;
2639 struct samr_LookupNames n;
2640 struct policy_handle user_handle;
2642 n.in.domain_handle = domain_handle;
2644 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2645 n.in.names[0].string = acct_name;
2647 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2648 if (!NT_STATUS_IS_OK(status)) {
2649 printf("LookupNames failed - %s\n", nt_errstr(status));
2653 r.in.domain_handle = domain_handle;
2654 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2655 r.in.rid = n.out.rids.ids[0];
2656 r.out.user_handle = &user_handle;
2658 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2659 if (!NT_STATUS_IS_OK(status)) {
2660 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2664 q.in.user_handle = &user_handle;
2667 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2668 if (!NT_STATUS_IS_OK(status)) {
2669 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2673 printf("calling test_ChangePasswordUser3 with too early password change\n");
2675 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2676 q.out.info->info5.last_password_change, true)) {
2681 /* we change passwords twice - this has the effect of verifying
2682 they were changed correctly for the final call */
2683 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2687 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2694 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2695 struct policy_handle *domain_handle,
2696 struct policy_handle *user_handle_out,
2697 struct dom_sid *domain_sid,
2698 enum torture_samr_choice which_ops)
2701 TALLOC_CTX *user_ctx;
2704 struct samr_CreateUser r;
2705 struct samr_QueryUserInfo q;
2706 struct samr_DeleteUser d;
2709 /* This call creates a 'normal' account - check that it really does */
2710 const uint32_t acct_flags = ACB_NORMAL;
2711 struct lsa_String name;
2714 struct policy_handle user_handle;
2715 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2716 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2718 r.in.domain_handle = domain_handle;
2719 r.in.account_name = &name;
2720 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2721 r.out.user_handle = &user_handle;
2724 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2726 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2728 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2729 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2730 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2733 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2739 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2740 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2741 talloc_free(user_ctx);
2744 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2746 if (!NT_STATUS_IS_OK(status)) {
2747 talloc_free(user_ctx);
2748 printf("CreateUser failed - %s\n", nt_errstr(status));
2751 q.in.user_handle = &user_handle;
2754 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2755 if (!NT_STATUS_IS_OK(status)) {
2756 printf("QueryUserInfo level %u failed - %s\n",
2757 q.in.level, nt_errstr(status));
2760 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2761 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2762 q.out.info->info16.acct_flags,
2768 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2769 acct_flags, name.string, which_ops)) {
2773 if (user_handle_out) {
2774 *user_handle_out = user_handle;
2776 printf("Testing DeleteUser (createuser test)\n");
2778 d.in.user_handle = &user_handle;
2779 d.out.user_handle = &user_handle;
2781 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2782 if (!NT_STATUS_IS_OK(status)) {
2783 printf("DeleteUser failed - %s\n", nt_errstr(status));
2790 talloc_free(user_ctx);
2796 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2797 struct policy_handle *domain_handle,
2798 struct dom_sid *domain_sid,
2799 enum torture_samr_choice which_ops)
2802 struct samr_CreateUser2 r;
2803 struct samr_QueryUserInfo q;
2804 struct samr_DeleteUser d;
2805 struct policy_handle user_handle;
2807 struct lsa_String name;
2812 uint32_t acct_flags;
2813 const char *account_name;
2815 } account_types[] = {
2816 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2817 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2818 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2819 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2820 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2821 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2822 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2823 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2824 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2825 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2826 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2827 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2828 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2829 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2830 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2833 for (i = 0; account_types[i].account_name; i++) {
2834 TALLOC_CTX *user_ctx;
2835 uint32_t acct_flags = account_types[i].acct_flags;
2836 uint32_t access_granted;
2837 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2838 init_lsa_String(&name, account_types[i].account_name);
2840 r.in.domain_handle = domain_handle;
2841 r.in.account_name = &name;
2842 r.in.acct_flags = acct_flags;
2843 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2844 r.out.user_handle = &user_handle;
2845 r.out.access_granted = &access_granted;
2848 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2850 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2852 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2853 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2854 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2857 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2864 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2865 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2866 talloc_free(user_ctx);
2870 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2873 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2874 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2875 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2879 if (NT_STATUS_IS_OK(status)) {
2880 q.in.user_handle = &user_handle;
2883 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2884 if (!NT_STATUS_IS_OK(status)) {
2885 printf("QueryUserInfo level %u failed - %s\n",
2886 q.in.level, nt_errstr(status));
2889 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2890 if (acct_flags == ACB_NORMAL) {
2891 expected_flags |= ACB_PW_EXPIRED;
2893 if ((q.out.info->info5.acct_flags) != expected_flags) {
2894 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2895 q.out.info->info5.acct_flags,
2899 switch (acct_flags) {
2901 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2902 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2903 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2908 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2909 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2910 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2915 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2916 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2917 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2924 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2925 acct_flags, name.string, which_ops)) {
2929 printf("Testing DeleteUser (createuser2 test)\n");
2931 d.in.user_handle = &user_handle;
2932 d.out.user_handle = &user_handle;
2934 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2935 if (!NT_STATUS_IS_OK(status)) {
2936 printf("DeleteUser failed - %s\n", nt_errstr(status));
2940 talloc_free(user_ctx);
2946 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2947 struct policy_handle *handle)
2950 struct samr_QueryAliasInfo r;
2951 uint16_t levels[] = {1, 2, 3};
2955 for (i=0;i<ARRAY_SIZE(levels);i++) {
2956 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2958 r.in.alias_handle = handle;
2959 r.in.level = levels[i];
2961 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2962 if (!NT_STATUS_IS_OK(status)) {
2963 printf("QueryAliasInfo level %u failed - %s\n",
2964 levels[i], nt_errstr(status));
2972 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2973 struct policy_handle *handle)
2976 struct samr_QueryGroupInfo r;
2977 uint16_t levels[] = {1, 2, 3, 4, 5};
2981 for (i=0;i<ARRAY_SIZE(levels);i++) {
2982 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2984 r.in.group_handle = handle;
2985 r.in.level = levels[i];
2987 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2988 if (!NT_STATUS_IS_OK(status)) {
2989 printf("QueryGroupInfo level %u failed - %s\n",
2990 levels[i], nt_errstr(status));
2998 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2999 struct policy_handle *handle)
3002 struct samr_QueryGroupMember r;
3005 printf("Testing QueryGroupMember\n");
3007 r.in.group_handle = handle;
3009 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3010 if (!NT_STATUS_IS_OK(status)) {
3011 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3019 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3020 struct policy_handle *handle)
3023 struct samr_QueryGroupInfo r;
3024 struct samr_SetGroupInfo s;
3025 uint16_t levels[] = {1, 2, 3, 4};
3026 uint16_t set_ok[] = {0, 1, 1, 1};
3030 for (i=0;i<ARRAY_SIZE(levels);i++) {
3031 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3033 r.in.group_handle = handle;
3034 r.in.level = levels[i];
3036 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3037 if (!NT_STATUS_IS_OK(status)) {
3038 printf("QueryGroupInfo level %u failed - %s\n",
3039 levels[i], nt_errstr(status));
3043 printf("Testing SetGroupInfo level %u\n", levels[i]);
3045 s.in.group_handle = handle;
3046 s.in.level = levels[i];
3047 s.in.info = r.out.info;
3050 /* disabled this, as it changes the name only from the point of view of samr,
3051 but leaves the name from the point of view of w2k3 internals (and ldap). This means
3052 the name is still reserved, so creating the old name fails, but deleting by the old name
3054 if (s.in.level == 2) {
3055 init_lsa_String(&s.in.info->string, "NewName");
3059 if (s.in.level == 4) {
3060 init_lsa_String(&s.in.info->description, "test description");
3063 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3065 if (!NT_STATUS_IS_OK(status)) {
3066 printf("SetGroupInfo level %u failed - %s\n",
3067 r.in.level, nt_errstr(status));
3072 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3073 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3074 r.in.level, nt_errstr(status));
3084 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3085 struct policy_handle *handle)
3088 struct samr_QueryUserInfo r;
3089 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3090 11, 12, 13, 14, 16, 17, 20, 21};
3094 for (i=0;i<ARRAY_SIZE(levels);i++) {
3095 printf("Testing QueryUserInfo level %u\n", levels[i]);
3097 r.in.user_handle = handle;
3098 r.in.level = levels[i];
3100 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3101 if (!NT_STATUS_IS_OK(status)) {
3102 printf("QueryUserInfo level %u failed - %s\n",
3103 levels[i], nt_errstr(status));
3111 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3112 struct policy_handle *handle)
3115 struct samr_QueryUserInfo2 r;
3116 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3117 11, 12, 13, 14, 16, 17, 20, 21};
3121 for (i=0;i<ARRAY_SIZE(levels);i++) {
3122 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3124 r.in.user_handle = handle;
3125 r.in.level = levels[i];
3127 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 printf("QueryUserInfo2 level %u failed - %s\n",
3130 levels[i], nt_errstr(status));
3138 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3139 struct policy_handle *handle, uint32_t rid)
3142 struct samr_OpenUser r;
3143 struct policy_handle user_handle;
3146 printf("Testing OpenUser(%u)\n", rid);
3148 r.in.domain_handle = handle;
3149 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3151 r.out.user_handle = &user_handle;
3153 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3154 if (!NT_STATUS_IS_OK(status)) {
3155 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3159 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3163 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3167 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3171 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3175 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3179 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3186 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3187 struct policy_handle *handle, uint32_t rid)
3190 struct samr_OpenGroup r;
3191 struct policy_handle group_handle;
3194 printf("Testing OpenGroup(%u)\n", rid);
3196 r.in.domain_handle = handle;
3197 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3199 r.out.group_handle = &group_handle;
3201 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3202 if (!NT_STATUS_IS_OK(status)) {
3203 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3207 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3211 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3215 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3219 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3226 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3227 struct policy_handle *handle, uint32_t rid)
3230 struct samr_OpenAlias r;
3231 struct policy_handle alias_handle;
3234 printf("Testing OpenAlias(%u)\n", rid);
3236 r.in.domain_handle = handle;
3237 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3239 r.out.alias_handle = &alias_handle;
3241 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3242 if (!NT_STATUS_IS_OK(status)) {
3243 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3247 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3251 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3255 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3259 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3266 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3267 struct policy_handle *handle, uint32_t rid,
3268 uint32_t acct_flag_mask)
3271 struct samr_OpenUser r;
3272 struct samr_QueryUserInfo q;
3273 struct policy_handle user_handle;
3276 printf("Testing OpenUser(%u)\n", rid);
3278 r.in.domain_handle = handle;
3279 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3281 r.out.user_handle = &user_handle;
3283 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3284 if (!NT_STATUS_IS_OK(status)) {
3285 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3289 q.in.user_handle = &user_handle;
3292 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3293 if (!NT_STATUS_IS_OK(status)) {
3294 printf("QueryUserInfo level 16 failed - %s\n",
3298 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3299 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3300 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3305 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3312 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3313 struct policy_handle *handle)
3315 NTSTATUS status = STATUS_MORE_ENTRIES;
3316 struct samr_EnumDomainUsers r;
3317 uint32_t mask, resume_handle=0;
3320 struct samr_LookupNames n;
3321 struct samr_LookupRids lr ;
3322 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3323 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3324 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3327 printf("Testing EnumDomainUsers\n");
3329 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3330 r.in.domain_handle = handle;
3331 r.in.resume_handle = &resume_handle;
3332 r.in.acct_flags = mask = masks[mask_idx];
3333 r.in.max_size = (uint32_t)-1;
3334 r.out.resume_handle = &resume_handle;
3336 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3337 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3338 !NT_STATUS_IS_OK(status)) {
3339 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3344 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3348 if (r.out.sam->count == 0) {
3352 for (i=0;i<r.out.sam->count;i++) {
3354 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3357 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3363 printf("Testing LookupNames\n");
3364 n.in.domain_handle = handle;
3365 n.in.num_names = r.out.sam->count;
3366 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3367 for (i=0;i<r.out.sam->count;i++) {
3368 n.in.names[i].string = r.out.sam->entries[i].name.string;
3370 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3371 if (!NT_STATUS_IS_OK(status)) {
3372 printf("LookupNames failed - %s\n", nt_errstr(status));
3377 printf("Testing LookupRids\n");
3378 lr.in.domain_handle = handle;
3379 lr.in.num_rids = r.out.sam->count;
3380 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3381 for (i=0;i<r.out.sam->count;i++) {
3382 lr.in.rids[i] = r.out.sam->entries[i].idx;
3384 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3385 if (!NT_STATUS_IS_OK(status)) {
3386 printf("LookupRids failed - %s\n", nt_errstr(status));
3394 try blasting the server with a bunch of sync requests
3396 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx,
3397 struct policy_handle *handle)
3400 struct samr_EnumDomainUsers r;
3401 uint32_t resume_handle=0;
3403 #define ASYNC_COUNT 100
3404 struct rpc_request *req[ASYNC_COUNT];
3406 if (!torture_setting_bool(tctx, "dangerous", false)) {
3407 printf("samr async test disabled - enable dangerous tests to use\n");
3411 printf("Testing EnumDomainUsers_async\n");
3413 r.in.domain_handle = handle;
3414 r.in.resume_handle = &resume_handle;
3415 r.in.acct_flags = 0;
3416 r.in.max_size = (uint32_t)-1;
3417 r.out.resume_handle = &resume_handle;
3419 for (i=0;i<ASYNC_COUNT;i++) {
3420 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3423 for (i=0;i<ASYNC_COUNT;i++) {
3424 status = dcerpc_ndr_request_recv(req[i]);
3425 if (!NT_STATUS_IS_OK(status)) {
3426 printf("EnumDomainUsers[%d] failed - %s\n",
3427 i, nt_errstr(status));
3432 printf("%d async requests OK\n", i);
3437 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3438 struct policy_handle *handle)
3441 struct samr_EnumDomainGroups r;
3442 uint32_t resume_handle=0;
3446 printf("Testing EnumDomainGroups\n");
3448 r.in.domain_handle = handle;
3449 r.in.resume_handle = &resume_handle;
3450 r.in.max_size = (uint32_t)-1;
3451 r.out.resume_handle = &resume_handle;
3453 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3454 if (!NT_STATUS_IS_OK(status)) {
3455 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3463 for (i=0;i<r.out.sam->count;i++) {
3464 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3472 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3473 struct policy_handle *handle)
3476 struct samr_EnumDomainAliases r;
3477 uint32_t resume_handle=0;
3481 printf("Testing EnumDomainAliases\n");
3483 r.in.domain_handle = handle;
3484 r.in.resume_handle = &resume_handle;
3485 r.in.acct_flags = (uint32_t)-1;
3486 r.out.resume_handle = &resume_handle;
3488 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3489 if (!NT_STATUS_IS_OK(status)) {
3490 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3498 for (i=0;i<r.out.sam->count;i++) {
3499 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3507 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3508 struct policy_handle *handle)
3511 struct samr_GetDisplayEnumerationIndex r;
3513 uint16_t levels[] = {1, 2, 3, 4, 5};
3514 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3517 for (i=0;i<ARRAY_SIZE(levels);i++) {
3518 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3520 r.in.domain_handle = handle;
3521 r.in.level = levels[i];
3522 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3524 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3527 !NT_STATUS_IS_OK(status) &&
3528 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3529 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3530 levels[i], nt_errstr(status));
3534 init_lsa_String(&r.in.name, "zzzzzzzz");
3536 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3538 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3539 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3540 levels[i], nt_errstr(status));
3548 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3549 struct policy_handle *handle)
3552 struct samr_GetDisplayEnumerationIndex2 r;
3554 uint16_t levels[] = {1, 2, 3, 4, 5};
3555 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3558 for (i=0;i<ARRAY_SIZE(levels);i++) {
3559 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3561 r.in.domain_handle = handle;
3562 r.in.level = levels[i];
3563 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3565 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3567 !NT_STATUS_IS_OK(status) &&
3568 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3569 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3570 levels[i], nt_errstr(status));
3574 init_lsa_String(&r.in.name, "zzzzzzzz");
3576 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3577 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3578 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3579 levels[i], nt_errstr(status));
3587 #define STRING_EQUAL_QUERY(s1, s2, user) \
3588 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3589 /* odd, but valid */ \
3590 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3591 printf("%s mismatch for %s: %s != %s (%s)\n", \
3592 #s1, user.string, s1.string, s2.string, __location__); \
3595 #define INT_EQUAL_QUERY(s1, s2, user) \
3597 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3598 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3602 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3603 struct samr_QueryDisplayInfo *querydisplayinfo,
3604 bool *seen_testuser)
3606 struct samr_OpenUser r;
3607 struct samr_QueryUserInfo q;
3608 struct policy_handle user_handle;
3611 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3612 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3613 for (i = 0; ; i++) {
3614 switch (querydisplayinfo->in.level) {
3616 if (i >= querydisplayinfo->out.info.info1.count) {
3619 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3622 if (i >= querydisplayinfo->out.info.info2.count) {
3625 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3631 /* Not interested in validating just the account name */
3635 r.out.user_handle = &user_handle;
3637 switch (querydisplayinfo->in.level) {
3640 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3641 if (!NT_STATUS_IS_OK(status)) {
3642 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3647 q.in.user_handle = &user_handle;
3649 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3650 if (!NT_STATUS_IS_OK(status)) {
3651 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3655 switch (querydisplayinfo->in.level) {
3657 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3658 *seen_testuser = true;
3660 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3661 q.out.info->info21.full_name, q.out.info->info21.account_name);
3662 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3663 q.out.info->info21.account_name, q.out.info->info21.account_name);
3664 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3665 q.out.info->info21.description, q.out.info->info21.account_name);
3666 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3667 q.out.info->info21.rid, q.out.info->info21.account_name);
3668 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3669 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3673 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3674 q.out.info->info21.account_name, q.out.info->info21.account_name);
3675 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3676 q.out.info->info21.description, q.out.info->info21.account_name);
3677 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3678 q.out.info->info21.rid, q.out.info->info21.account_name);
3679 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3680 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3682 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3683 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3684 q.out.info->info21.account_name.string);
3687 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3688 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3689 q.out.info->info21.account_name.string,
3690 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3691 q.out.info->info21.acct_flags);
3698 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3705 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3706 struct policy_handle *handle)
3709 struct samr_QueryDisplayInfo r;
3710 struct samr_QueryDomainInfo dom_info;
3712 uint16_t levels[] = {1, 2, 3, 4, 5};
3714 bool seen_testuser = false;
3716 for (i=0;i<ARRAY_SIZE(levels);i++) {
3717 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3720 status = STATUS_MORE_ENTRIES;
3721 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3722 r.in.domain_handle = handle;
3723 r.in.level = levels[i];
3724 r.in.max_entries = 2;
3725 r.in.buf_size = (uint32_t)-1;
3727 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3728 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3729 printf("QueryDisplayInfo level %u failed - %s\n",
3730 levels[i], nt_errstr(status));
3733 switch (r.in.level) {
3735 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3738 r.in.start_idx += r.out.info.info1.count;
3741 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3744 r.in.start_idx += r.out.info.info2.count;
3747 r.in.start_idx += r.out.info.info3.count;
3750 r.in.start_idx += r.out.info.info4.count;
3753 r.in.start_idx += r.out.info.info5.count;
3757 dom_info.in.domain_handle = handle;
3758 dom_info.in.level = 2;
3759 /* Check number of users returned is correct */
3760 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3761 if (!NT_STATUS_IS_OK(status)) {
3762 printf("QueryDomainInfo level %u failed - %s\n",
3763 r.in.level, nt_errstr(status));
3767 switch (r.in.level) {
3770 if (dom_info.out.info->general.num_users < r.in.start_idx) {
3771 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3772 r.in.start_idx, dom_info.out.info->general.num_groups,
3773 dom_info.out.info->general.domain_name.string);
3776 if (!seen_testuser) {
3777 struct policy_handle user_handle;
3778 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3779 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3780 dom_info.out.info->general.domain_name.string);
3782 test_samr_handle_Close(p, mem_ctx, &user_handle);
3788 if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3789 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3790 r.in.start_idx, dom_info.out.info->general.num_groups,
3791 dom_info.out.info->general.domain_name.string);
3803 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3804 struct policy_handle *handle)
3807 struct samr_QueryDisplayInfo2 r;
3809 uint16_t levels[] = {1, 2, 3, 4, 5};
3812 for (i=0;i<ARRAY_SIZE(levels);i++) {
3813 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3815 r.in.domain_handle = handle;
3816 r.in.level = levels[i];
3818 r.in.max_entries = 1000;
3819 r.in.buf_size = (uint32_t)-1;
3821 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3822 if (!NT_STATUS_IS_OK(status)) {
3823 printf("QueryDisplayInfo2 level %u failed - %s\n",
3824 levels[i], nt_errstr(status));
3832 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3833 struct policy_handle *handle)
3836 struct samr_QueryDisplayInfo3 r;
3838 uint16_t levels[] = {1, 2, 3, 4, 5};
3841 for (i=0;i<ARRAY_SIZE(levels);i++) {
3842 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3844 r.in.domain_handle = handle;
3845 r.in.level = levels[i];
3847 r.in.max_entries = 1000;
3848 r.in.buf_size = (uint32_t)-1;
3850 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3851 if (!NT_STATUS_IS_OK(status)) {
3852 printf("QueryDisplayInfo3 level %u failed - %s\n",
3853 levels[i], nt_errstr(status));
3862 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3863 struct policy_handle *handle)
3866 struct samr_QueryDisplayInfo r;
3869 printf("Testing QueryDisplayInfo continuation\n");
3871 r.in.domain_handle = handle;
3874 r.in.max_entries = 1;
3875 r.in.buf_size = (uint32_t)-1;
3878 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3879 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3880 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3881 printf("expected idx %d but got %d\n",
3883 r.out.info.info1.entries[0].idx);
3887 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3888 !NT_STATUS_IS_OK(status)) {
3889 printf("QueryDisplayInfo level %u failed - %s\n",
3890 r.in.level, nt_errstr(status));
3895 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3896 NT_STATUS_IS_OK(status)) &&
3897 r.out.returned_size != 0);
3902 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3903 struct policy_handle *handle)
3906 struct samr_QueryDomainInfo r;
3907 struct samr_SetDomainInfo s;
3908 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3909 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3912 const char *domain_comment = talloc_asprintf(mem_ctx,
3913 "Tortured by Samba4 RPC-SAMR: %s",
3914 timestring(mem_ctx, time(NULL)));
3916 s.in.domain_handle = handle;
3918 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3920 s.in.info->oem.oem_information.string = domain_comment;
3921 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3922 if (!NT_STATUS_IS_OK(status)) {
3923 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3924 r.in.level, nt_errstr(status));
3928 for (i=0;i<ARRAY_SIZE(levels);i++) {
3929 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3931 r.in.domain_handle = handle;
3932 r.in.level = levels[i];
3934 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3935 if (!NT_STATUS_IS_OK(status)) {
3936 printf("QueryDomainInfo level %u failed - %s\n",
3937 r.in.level, nt_errstr(status));
3942 switch (levels[i]) {
3944 if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3945 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3946 levels[i], r.out.info->general.oem_information.string, domain_comment);
3949 if (!r.out.info->general.primary.string) {
3950 printf("QueryDomainInfo level %u returned no PDC name\n",
3953 } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3954 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3955 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3956 levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3961 if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3962 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3963 levels[i], r.out.info->oem.oem_information.string, domain_comment);
3968 if (!r.out.info->info6.primary.string) {
3969 printf("QueryDomainInfo level %u returned no PDC name\n",
3975 if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3976 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3977 levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3983 printf("Testing SetDomainInfo level %u\n", levels[i]);
3985 s.in.domain_handle = handle;
3986 s.in.level = levels[i];
3987 s.in.info = r.out.info;
3989 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3991 if (!NT_STATUS_IS_OK(status)) {
3992 printf("SetDomainInfo level %u failed - %s\n",
3993 r.in.level, nt_errstr(status));
3998 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3999 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4000 r.in.level, nt_errstr(status));
4006 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
4007 if (!NT_STATUS_IS_OK(status)) {
4008 printf("QueryDomainInfo level %u failed - %s\n",
4009 r.in.level, nt_errstr(status));
4019 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4020 struct policy_handle *handle)
4023 struct samr_QueryDomainInfo2 r;
4024 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4028 for (i=0;i<ARRAY_SIZE(levels);i++) {
4029 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4031 r.in.domain_handle = handle;
4032 r.in.level = levels[i];
4034 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
4035 if (!NT_STATUS_IS_OK(status)) {
4036 printf("QueryDomainInfo2 level %u failed - %s\n",
4037 r.in.level, nt_errstr(status));
4046 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4047 set of group names. */
4048 static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4049 struct policy_handle *handle)
4051 struct samr_EnumDomainGroups q1;
4052 struct samr_QueryDisplayInfo q2;
4054 uint32_t resume_handle=0;
4059 const char **names = NULL;
4061 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
4063 q1.in.domain_handle = handle;
4064 q1.in.resume_handle = &resume_handle;
4066 q1.out.resume_handle = &resume_handle;
4068 status = STATUS_MORE_ENTRIES;
4069 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4070 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
4072 if (!NT_STATUS_IS_OK(status) &&
4073 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4076 for (i=0; i<q1.out.num_entries; i++) {
4077 add_string_to_array(mem_ctx,
4078 q1.out.sam->entries[i].name.string,
4079 &names, &num_names);
4083 if (!NT_STATUS_IS_OK(status)) {
4084 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4089 printf("EnumDomainGroups failed to return q1.out.sam\n");
4093 q2.in.domain_handle = handle;
4095 q2.in.start_idx = 0;
4096 q2.in.max_entries = 5;
4097 q2.in.buf_size = (uint32_t)-1;
4099 status = STATUS_MORE_ENTRIES;
4100 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4101 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
4103 if (!NT_STATUS_IS_OK(status) &&
4104 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4107 for (i=0; i<q2.out.info.info5.count; i++) {
4109 const char *name = q2.out.info.info5.entries[i].account_name.string;
4111 for (j=0; j<num_names; j++) {
4112 if (names[j] == NULL)
4114 if (strequal(names[j], name)) {
4122 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4127 q2.in.start_idx += q2.out.info.info5.count;
4130 if (!NT_STATUS_IS_OK(status)) {
4131 printf("QueryDisplayInfo level 5 failed - %s\n",
4136 for (i=0; i<num_names; i++) {
4137 if (names[i] != NULL) {
4138 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4147 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4148 struct policy_handle *group_handle)
4150 struct samr_DeleteDomainGroup d;
4154 printf("Testing DeleteDomainGroup\n");
4156 d.in.group_handle = group_handle;
4157 d.out.group_handle = group_handle;
4159 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
4160 if (!NT_STATUS_IS_OK(status)) {
4161 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
4168 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4169 struct policy_handle *domain_handle)
4171 struct samr_TestPrivateFunctionsDomain r;
4175 printf("Testing TestPrivateFunctionsDomain\n");
4177 r.in.domain_handle = domain_handle;
4179 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
4180 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
4181 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
4188 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4189 struct dom_sid *domain_sid,
4190 struct policy_handle *domain_handle)
4192 struct samr_RidToSid r;
4195 struct dom_sid *calc_sid;
4196 int rids[] = { 0, 42, 512, 10200 };
4199 for (i=0;i<ARRAY_SIZE(rids);i++) {
4201 printf("Testing RidToSid\n");
4203 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
4204 r.in.domain_handle = domain_handle;
4207 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
4208 if (!NT_STATUS_IS_OK(status)) {
4209 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4212 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4214 if (!dom_sid_equal(calc_sid, r.out.sid)) {
4215 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4216 dom_sid_string(mem_ctx, r.out.sid),
4217 dom_sid_string(mem_ctx, calc_sid));
4226 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4227 struct policy_handle *domain_handle)
4229 struct samr_GetBootKeyInformation r;
4233 printf("Testing GetBootKeyInformation\n");
4235 r.in.domain_handle = domain_handle;
4237 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4238 if (!NT_STATUS_IS_OK(status)) {
4239 /* w2k3 seems to fail this sometimes and pass it sometimes */
4240 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4246 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4247 struct policy_handle *domain_handle,
4248 struct policy_handle *group_handle)
4251 struct samr_AddGroupMember r;
4252 struct samr_DeleteGroupMember d;
4253 struct samr_QueryGroupMember q;
4254 struct samr_SetMemberAttributesOfGroup s;
4258 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4259 if (!NT_STATUS_IS_OK(status)) {
4260 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4264 r.in.group_handle = group_handle;
4266 r.in.flags = 0; /* ??? */
4268 printf("Testing AddGroupMember and DeleteGroupMember\n");
4270 d.in.group_handle = group_handle;
4273 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4274 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4275 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4280 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4281 if (!NT_STATUS_IS_OK(status)) {
4282 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4286 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4287 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4288 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4293 if (torture_setting_bool(tctx, "samba4", false)) {
4294 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4296 /* this one is quite strange. I am using random inputs in the
4297 hope of triggering an error that might give us a clue */
4299 s.in.group_handle = group_handle;
4300 s.in.unknown1 = random();
4301 s.in.unknown2 = random();
4303 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4304 if (!NT_STATUS_IS_OK(status)) {
4305 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4310 q.in.group_handle = group_handle;
4312 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4313 if (!NT_STATUS_IS_OK(status)) {
4314 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4318 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4319 if (!NT_STATUS_IS_OK(status)) {
4320 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4324 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4325 if (!NT_STATUS_IS_OK(status)) {
4326 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4334 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4335 struct policy_handle *domain_handle,
4336 struct policy_handle *group_handle,
4337 struct dom_sid *domain_sid)
4340 struct samr_CreateDomainGroup r;
4342 struct lsa_String name;
4345 init_lsa_String(&name, TEST_GROUPNAME);
4347 r.in.domain_handle = domain_handle;
4349 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4350 r.out.group_handle = group_handle;
4353 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4355 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4357 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
4358 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4359 printf("Server correctly refused create of '%s'\n", r.in.name->string);
4362 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4368 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4369 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4370 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4374 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4376 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4377 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4379 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4383 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4385 if (!NT_STATUS_IS_OK(status)) {
4386 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4390 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4391 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4395 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4404 its not totally clear what this does. It seems to accept any sid you like.
4406 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4407 TALLOC_CTX *mem_ctx,
4408 struct policy_handle *domain_handle)
4411 struct samr_RemoveMemberFromForeignDomain r;
4413 r.in.domain_handle = domain_handle;
4414 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4416 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4417 if (!NT_STATUS_IS_OK(status)) {
4418 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4427 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4428 struct policy_handle *handle);
4430 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4431 struct policy_handle *handle, struct dom_sid *sid,
4432 enum torture_samr_choice which_ops)
4435 struct samr_OpenDomain r;
4436 struct policy_handle domain_handle;
4437 struct policy_handle alias_handle;
4438 struct policy_handle user_handle;
4439 struct policy_handle group_handle;
4442 ZERO_STRUCT(alias_handle);
4443 ZERO_STRUCT(user_handle);
4444 ZERO_STRUCT(group_handle);
4445 ZERO_STRUCT(domain_handle);
4447 printf("Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4449 r.in.connect_handle = handle;
4450 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4452 r.out.domain_handle = &domain_handle;
4454 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4455 if (!NT_STATUS_IS_OK(status)) {
4456 printf("OpenDomain failed - %s\n", nt_errstr(status));
4460 /* run the domain tests with the main handle closed - this tests
4461 the servers reference counting */
4462 ret &= test_samr_handle_Close(p, tctx, handle);
4464 switch (which_ops) {
4465 case TORTURE_SAMR_USER_ATTRIBUTES:
4466 case TORTURE_SAMR_PASSWORDS:
4467 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4468 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4469 /* This test needs 'complex' users to validate */
4470 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4472 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4475 case TORTURE_SAMR_OTHER:
4476 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4478 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4480 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4481 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4482 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4483 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4484 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4485 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4486 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4487 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4488 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4489 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4490 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4491 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4492 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4494 if (torture_setting_bool(tctx, "samba4", false)) {
4495 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4497 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4498 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4500 ret &= test_GroupList(p, tctx, &domain_handle);
4501 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4502 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4503 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4505 printf("Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4510 if (!policy_handle_empty(&user_handle) &&
4511 !test_DeleteUser(p, tctx, &user_handle)) {
4515 if (!policy_handle_empty(&alias_handle) &&
4516 !test_DeleteAlias(p, tctx, &alias_handle)) {
4520 if (!policy_handle_empty(&group_handle) &&
4521 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4525 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4527 /* reconnect the main handle */
4528 ret &= test_Connect(p, tctx, handle);
4531 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4537 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4538 struct policy_handle *handle, const char *domain,
4539 enum torture_samr_choice which_ops)
4542 struct samr_LookupDomain r;
4543 struct lsa_String n1;
4544 struct lsa_String n2;
4547 printf("Testing LookupDomain(%s)\n", domain);
4549 /* check for correct error codes */
4550 r.in.connect_handle = handle;
4551 r.in.domain_name = &n2;
4554 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4555 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4556 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4560 init_lsa_String(&n2, "xxNODOMAINxx");
4562 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4563 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4564 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4568 r.in.connect_handle = handle;
4570 init_lsa_String(&n1, domain);
4571 r.in.domain_name = &n1;
4573 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4574 if (!NT_STATUS_IS_OK(status)) {
4575 printf("LookupDomain failed - %s\n", nt_errstr(status));
4579 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4583 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4591 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4592 struct policy_handle *handle, enum torture_samr_choice which_ops)
4595 struct samr_EnumDomains r;
4596 uint32_t resume_handle = 0;
4600 r.in.connect_handle = handle;
4601 r.in.resume_handle = &resume_handle;
4602 r.in.buf_size = (uint32_t)-1;
4603 r.out.resume_handle = &resume_handle;
4605 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 printf("EnumDomains failed - %s\n", nt_errstr(status));
4615 for (i=0;i<r.out.sam->count;i++) {
4616 if (!test_LookupDomain(p, tctx, handle,
4617 r.out.sam->entries[i].name.string, which_ops)) {
4622 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4623 if (!NT_STATUS_IS_OK(status)) {
4624 printf("EnumDomains failed - %s\n", nt_errstr(status));
4632 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4633 struct policy_handle *handle)
4636 struct samr_Connect r;
4637 struct samr_Connect2 r2;
4638 struct samr_Connect3 r3;
4639 struct samr_Connect4 r4;
4640 struct samr_Connect5 r5;
4641 union samr_ConnectInfo info;
4642 struct policy_handle h;
4643 bool ret = true, got_handle = false;
4645 printf("testing samr_Connect\n");
4647 r.in.system_name = 0;
4648 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4649 r.out.connect_handle = &h;
4651 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4652 if (!NT_STATUS_IS_OK(status)) {
4653 printf("Connect failed - %s\n", nt_errstr(status));
4660 printf("testing samr_Connect2\n");
4662 r2.in.system_name = NULL;
4663 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4664 r2.out.connect_handle = &h;
4666 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4667 if (!NT_STATUS_IS_OK(status)) {
4668 printf("Connect2 failed - %s\n", nt_errstr(status));
4672 test_samr_handle_Close(p, mem_ctx, handle);
4678 printf("testing samr_Connect3\n");
4680 r3.in.system_name = NULL;
4682 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4683 r3.out.connect_handle = &h;
4685 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4686 if (!NT_STATUS_IS_OK(status)) {
4687 printf("Connect3 failed - %s\n", nt_errstr(status));
4691 test_samr_handle_Close(p, mem_ctx, handle);
4697 printf("testing samr_Connect4\n");
4699 r4.in.system_name = "";
4700 r4.in.client_version = 0;
4701 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4702 r4.out.connect_handle = &h;
4704 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4705 if (!NT_STATUS_IS_OK(status)) {
4706 printf("Connect4 failed - %s\n", nt_errstr(status));
4710 test_samr_handle_Close(p, mem_ctx, handle);
4716 printf("testing samr_Connect5\n");
4718 info.info1.client_version = 0;
4719 info.info1.unknown2 = 0;
4721 r5.in.system_name = "";
4722 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4725 r5.out.info = &info;
4726 r5.out.connect_handle = &h;
4728 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4729 if (!NT_STATUS_IS_OK(status)) {
4730 printf("Connect5 failed - %s\n", nt_errstr(status));
4734 test_samr_handle_Close(p, mem_ctx, handle);
4744 bool torture_rpc_samr(struct torture_context *torture)
4747 struct dcerpc_pipe *p;
4749 struct policy_handle handle;
4751 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4752 if (!NT_STATUS_IS_OK(status)) {
4756 ret &= test_Connect(p, torture, &handle);
4758 ret &= test_QuerySecurity(p, torture, &handle);
4760 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4762 ret &= test_SetDsrmPassword(p, torture, &handle);
4764 ret &= test_Shutdown(p, torture, &handle);
4766 ret &= test_samr_handle_Close(p, torture, &handle);
4772 bool torture_rpc_samr_users(struct torture_context *torture)
4775 struct dcerpc_pipe *p;
4777 struct policy_handle handle;
4779 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4780 if (!NT_STATUS_IS_OK(status)) {
4784 ret &= test_Connect(p, torture, &handle);
4786 ret &= test_QuerySecurity(p, torture, &handle);
4788 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4790 ret &= test_SetDsrmPassword(p, torture, &handle);
4792 ret &= test_Shutdown(p, torture, &handle);
4794 ret &= test_samr_handle_Close(p, torture, &handle);
4800 bool torture_rpc_samr_passwords(struct torture_context *torture)
4803 struct dcerpc_pipe *p;
4805 struct policy_handle handle;
4807 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4808 if (!NT_STATUS_IS_OK(status)) {
4812 ret &= test_Connect(p, torture, &handle);
4814 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4816 ret &= test_samr_handle_Close(p, torture, &handle);