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, struct torture_context *tctx,
139 struct policy_handle *handle)
142 struct samr_QuerySecurity r;
143 struct samr_SetSecurity s;
145 r.in.handle = handle;
148 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
149 if (!NT_STATUS_IS_OK(status)) {
150 printf("QuerySecurity failed - %s\n", nt_errstr(status));
154 if (r.out.sdbuf == NULL) {
158 s.in.handle = handle;
160 s.in.sdbuf = r.out.sdbuf;
162 if (torture_setting_bool(tctx, "samba4", false)) {
163 printf("skipping SetSecurity test against Samba4\n");
167 status = dcerpc_samr_SetSecurity(p, tctx, &s);
168 if (!NT_STATUS_IS_OK(status)) {
169 printf("SetSecurity failed - %s\n", nt_errstr(status));
173 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
174 if (!NT_STATUS_IS_OK(status)) {
175 printf("QuerySecurity failed - %s\n", nt_errstr(status));
183 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
184 struct policy_handle *handle, uint32_t base_acct_flags,
185 const char *base_account_name)
188 struct samr_SetUserInfo s;
189 struct samr_SetUserInfo2 s2;
190 struct samr_QueryUserInfo q;
191 struct samr_QueryUserInfo q0;
192 union samr_UserInfo u;
194 const char *test_account_name;
196 uint32_t user_extra_flags = 0;
197 if (base_acct_flags == ACB_NORMAL) {
198 /* When created, accounts are expired by default */
199 user_extra_flags = ACB_PW_EXPIRED;
202 s.in.user_handle = handle;
205 s2.in.user_handle = handle;
208 q.in.user_handle = handle;
212 #define TESTCALL(call, r) \
213 status = dcerpc_samr_ ##call(p, tctx, &r); \
214 if (!NT_STATUS_IS_OK(status)) { \
215 printf(#call " level %u failed - %s (%s)\n", \
216 r.in.level, nt_errstr(status), __location__); \
221 #define STRING_EQUAL(s1, s2, field) \
222 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
223 printf("Failed to set %s to '%s' (%s)\n", \
224 #field, s2, __location__); \
229 #define INT_EQUAL(i1, i2, field) \
231 printf("Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
232 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
237 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
238 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
240 TESTCALL(QueryUserInfo, q) \
242 s2.in.level = lvl1; \
245 ZERO_STRUCT(u.info21); \
246 u.info21.fields_present = fpval; \
248 init_lsa_String(&u.info ## lvl1.field1, value); \
249 TESTCALL(SetUserInfo, s) \
250 TESTCALL(SetUserInfo2, s2) \
251 init_lsa_String(&u.info ## lvl1.field1, ""); \
252 TESTCALL(QueryUserInfo, q); \
254 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
256 TESTCALL(QueryUserInfo, q) \
258 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
261 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
262 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
264 TESTCALL(QueryUserInfo, q) \
266 s2.in.level = lvl1; \
269 uint8_t *bits = u.info21.logon_hours.bits; \
270 ZERO_STRUCT(u.info21); \
271 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
272 u.info21.logon_hours.units_per_week = 168; \
273 u.info21.logon_hours.bits = bits; \
275 u.info21.fields_present = fpval; \
277 u.info ## lvl1.field1 = value; \
278 TESTCALL(SetUserInfo, s) \
279 TESTCALL(SetUserInfo2, s2) \
280 u.info ## lvl1.field1 = 0; \
281 TESTCALL(QueryUserInfo, q); \
283 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
285 TESTCALL(QueryUserInfo, q) \
287 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
290 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
291 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
295 do { TESTCALL(QueryUserInfo, q0) } while (0);
297 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
298 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
299 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
302 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
303 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
304 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
305 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
306 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
307 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
308 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
309 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
310 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
311 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
312 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
313 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
314 test_account_name = base_account_name;
315 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
316 SAMR_FIELD_ACCOUNT_NAME);
318 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
319 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
323 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
324 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
325 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
326 SAMR_FIELD_FULL_NAME);
328 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
329 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
333 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
334 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
335 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
336 SAMR_FIELD_FULL_NAME);
338 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
339 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
340 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
341 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
342 SAMR_FIELD_LOGON_SCRIPT);
344 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
345 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
346 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
347 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
348 SAMR_FIELD_PROFILE_PATH);
350 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
351 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
352 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
353 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
354 SAMR_FIELD_HOME_DIRECTORY);
355 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
356 SAMR_FIELD_HOME_DIRECTORY);
358 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
359 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
360 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
361 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
362 SAMR_FIELD_HOME_DRIVE);
363 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
364 SAMR_FIELD_HOME_DRIVE);
366 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
367 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
368 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
369 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
370 SAMR_FIELD_DESCRIPTION);
372 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
373 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
374 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
375 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
376 SAMR_FIELD_WORKSTATIONS);
377 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
378 SAMR_FIELD_WORKSTATIONS);
379 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
380 SAMR_FIELD_WORKSTATIONS);
381 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
382 SAMR_FIELD_WORKSTATIONS);
384 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
385 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
386 SAMR_FIELD_PARAMETERS);
387 TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
388 SAMR_FIELD_PARAMETERS);
390 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
391 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
392 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
393 SAMR_FIELD_COUNTRY_CODE);
394 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
395 SAMR_FIELD_COUNTRY_CODE);
397 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
398 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
399 SAMR_FIELD_CODE_PAGE);
400 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
401 SAMR_FIELD_CODE_PAGE);
403 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
404 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
405 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
406 SAMR_FIELD_ACCT_EXPIRY);
407 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
408 SAMR_FIELD_ACCT_EXPIRY);
409 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
410 SAMR_FIELD_ACCT_EXPIRY);
412 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
413 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
414 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
415 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
416 SAMR_FIELD_LOGON_HOURS);
418 if (torture_setting_bool(tctx, "samba4", false)) {
419 printf("skipping Set Account Flag tests against Samba4\n");
423 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
424 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
425 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
427 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
428 (base_acct_flags | ACB_DISABLED),
429 (base_acct_flags | ACB_DISABLED | user_extra_flags),
432 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
433 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
434 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
435 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
437 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
438 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
439 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
443 /* The 'autolock' flag doesn't stick - check this */
444 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
445 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
446 (base_acct_flags | ACB_DISABLED | user_extra_flags),
449 /* Removing the 'disabled' flag doesn't stick - check this */
450 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
452 (base_acct_flags | ACB_DISABLED | user_extra_flags),
455 /* The 'store plaintext' flag does stick */
456 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
457 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
458 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
460 /* The 'use DES' flag does stick */
461 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
462 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
463 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
465 /* The 'don't require kerberos pre-authentication flag does stick */
466 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
467 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
468 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
470 /* The 'no kerberos PAC required' flag sticks */
471 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
472 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
473 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
476 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
477 (base_acct_flags | ACB_DISABLED),
478 (base_acct_flags | ACB_DISABLED | user_extra_flags),
479 SAMR_FIELD_ACCT_FLAGS);
482 /* these fail with win2003 - it appears you can't set the primary gid?
483 the set succeeds, but the gid isn't changed. Very weird! */
484 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
485 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
486 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
487 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
494 generate a random password for password change tests
496 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
498 size_t len = MAX(8, min_len) + (random() % 6);
499 char *s = generate_random_str(mem_ctx, len);
500 printf("Generated password '%s'\n", s);
505 generate a random password for password change tests (fixed length)
507 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
509 char *s = generate_random_str(mem_ctx, len);
510 printf("Generated password '%s'\n", s);
514 static bool test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
515 struct policy_handle *handle, char **password)
518 struct samr_SetUserInfo s;
519 union samr_UserInfo u;
521 DATA_BLOB session_key;
523 struct samr_GetUserPwInfo pwp;
524 int policy_min_pw_len = 0;
525 pwp.in.user_handle = handle;
527 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
528 if (NT_STATUS_IS_OK(status)) {
529 policy_min_pw_len = pwp.out.info.min_password_length;
531 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
533 s.in.user_handle = handle;
537 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
538 /* w2k3 ignores this length */
539 u.info24.pw_len = strlen_m(newpass) * 2;
541 status = dcerpc_fetch_session_key(p, &session_key);
542 if (!NT_STATUS_IS_OK(status)) {
543 printf("SetUserInfo level %u - no session key - %s\n",
544 s.in.level, nt_errstr(status));
548 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
550 printf("Testing SetUserInfo level 24 (set password)\n");
552 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
553 if (!NT_STATUS_IS_OK(status)) {
554 printf("SetUserInfo level %u failed - %s\n",
555 s.in.level, nt_errstr(status));
565 static bool test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
566 struct policy_handle *handle, uint32_t fields_present,
570 struct samr_SetUserInfo s;
571 union samr_UserInfo u;
573 DATA_BLOB session_key;
575 struct samr_GetUserPwInfo pwp;
576 int policy_min_pw_len = 0;
577 pwp.in.user_handle = handle;
579 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
580 if (NT_STATUS_IS_OK(status)) {
581 policy_min_pw_len = pwp.out.info.min_password_length;
583 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
585 s.in.user_handle = handle;
591 u.info23.info.fields_present = fields_present;
593 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
595 status = dcerpc_fetch_session_key(p, &session_key);
596 if (!NT_STATUS_IS_OK(status)) {
597 printf("SetUserInfo level %u - no session key - %s\n",
598 s.in.level, nt_errstr(status));
602 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
604 printf("Testing SetUserInfo level 23 (set password)\n");
606 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
607 if (!NT_STATUS_IS_OK(status)) {
608 printf("SetUserInfo level %u failed - %s\n",
609 s.in.level, nt_errstr(status));
615 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
617 status = dcerpc_fetch_session_key(p, &session_key);
618 if (!NT_STATUS_IS_OK(status)) {
619 printf("SetUserInfo level %u - no session key - %s\n",
620 s.in.level, nt_errstr(status));
624 /* This should break the key nicely */
625 session_key.length--;
626 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
628 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
630 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
631 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
632 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
633 s.in.level, nt_errstr(status));
641 static bool test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
642 struct policy_handle *handle, bool makeshort,
646 struct samr_SetUserInfo s;
647 union samr_UserInfo u;
649 DATA_BLOB session_key;
650 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
651 uint8_t confounder[16];
653 struct MD5Context ctx;
654 struct samr_GetUserPwInfo pwp;
655 int policy_min_pw_len = 0;
656 pwp.in.user_handle = handle;
658 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
659 if (NT_STATUS_IS_OK(status)) {
660 policy_min_pw_len = pwp.out.info.min_password_length;
662 if (makeshort && policy_min_pw_len) {
663 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
665 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
668 s.in.user_handle = handle;
672 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
673 u.info26.pw_len = strlen(newpass);
675 status = dcerpc_fetch_session_key(p, &session_key);
676 if (!NT_STATUS_IS_OK(status)) {
677 printf("SetUserInfo level %u - no session key - %s\n",
678 s.in.level, nt_errstr(status));
682 generate_random_buffer((uint8_t *)confounder, 16);
685 MD5Update(&ctx, confounder, 16);
686 MD5Update(&ctx, session_key.data, session_key.length);
687 MD5Final(confounded_session_key.data, &ctx);
689 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
690 memcpy(&u.info26.password.data[516], confounder, 16);
692 printf("Testing SetUserInfo level 26 (set password ex)\n");
694 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
695 if (!NT_STATUS_IS_OK(status)) {
696 printf("SetUserInfo level %u failed - %s\n",
697 s.in.level, nt_errstr(status));
703 /* This should break the key nicely */
704 confounded_session_key.data[0]++;
706 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
707 memcpy(&u.info26.password.data[516], confounder, 16);
709 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
711 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
712 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
713 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
714 s.in.level, nt_errstr(status));
723 static bool test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
724 struct policy_handle *handle, uint32_t fields_present,
728 struct samr_SetUserInfo s;
729 union samr_UserInfo u;
731 DATA_BLOB session_key;
732 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
733 struct MD5Context ctx;
734 uint8_t confounder[16];
736 struct samr_GetUserPwInfo pwp;
737 int policy_min_pw_len = 0;
738 pwp.in.user_handle = handle;
740 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
741 if (NT_STATUS_IS_OK(status)) {
742 policy_min_pw_len = pwp.out.info.min_password_length;
744 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
746 s.in.user_handle = handle;
752 u.info25.info.fields_present = fields_present;
754 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
756 status = dcerpc_fetch_session_key(p, &session_key);
757 if (!NT_STATUS_IS_OK(status)) {
758 printf("SetUserInfo level %u - no session key - %s\n",
759 s.in.level, nt_errstr(status));
763 generate_random_buffer((uint8_t *)confounder, 16);
766 MD5Update(&ctx, confounder, 16);
767 MD5Update(&ctx, session_key.data, session_key.length);
768 MD5Final(confounded_session_key.data, &ctx);
770 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
771 memcpy(&u.info25.password.data[516], confounder, 16);
773 printf("Testing SetUserInfo level 25 (set password ex)\n");
775 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
776 if (!NT_STATUS_IS_OK(status)) {
777 printf("SetUserInfo level %u failed - %s\n",
778 s.in.level, nt_errstr(status));
784 /* This should break the key nicely */
785 confounded_session_key.data[0]++;
787 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
788 memcpy(&u.info25.password.data[516], confounder, 16);
790 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
792 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
793 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
794 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
795 s.in.level, nt_errstr(status));
802 static bool test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
803 struct policy_handle *handle)
806 struct samr_SetAliasInfo r;
807 struct samr_QueryAliasInfo q;
808 uint16_t levels[] = {2, 3};
812 /* Ignoring switch level 1, as that includes the number of members for the alias
813 * and setting this to a wrong value might have negative consequences
816 for (i=0;i<ARRAY_SIZE(levels);i++) {
817 printf("Testing SetAliasInfo level %u\n", levels[i]);
819 r.in.alias_handle = handle;
820 r.in.level = levels[i];
821 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
822 switch (r.in.level) {
823 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
824 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
825 "Test Description, should test I18N as well"); break;
828 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
829 if (!NT_STATUS_IS_OK(status)) {
830 printf("SetAliasInfo level %u failed - %s\n",
831 levels[i], nt_errstr(status));
835 q.in.alias_handle = handle;
836 q.in.level = levels[i];
838 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
839 if (!NT_STATUS_IS_OK(status)) {
840 printf("QueryAliasInfo level %u failed - %s\n",
841 levels[i], nt_errstr(status));
849 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
850 struct policy_handle *user_handle)
852 struct samr_GetGroupsForUser r;
856 printf("testing GetGroupsForUser\n");
858 r.in.user_handle = user_handle;
860 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
861 if (!NT_STATUS_IS_OK(status)) {
862 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
870 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
871 struct lsa_String *domain_name)
874 struct samr_GetDomPwInfo r;
877 r.in.domain_name = domain_name;
878 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
880 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
881 if (!NT_STATUS_IS_OK(status)) {
882 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
886 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
887 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
889 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
890 if (!NT_STATUS_IS_OK(status)) {
891 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
895 r.in.domain_name->string = "\\\\__NONAME__";
896 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
898 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
899 if (!NT_STATUS_IS_OK(status)) {
900 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
904 r.in.domain_name->string = "\\\\Builtin";
905 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
907 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
908 if (!NT_STATUS_IS_OK(status)) {
909 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
917 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
918 struct policy_handle *handle)
921 struct samr_GetUserPwInfo r;
924 printf("Testing GetUserPwInfo\n");
926 r.in.user_handle = handle;
928 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
929 if (!NT_STATUS_IS_OK(status)) {
930 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
937 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
938 struct policy_handle *domain_handle, const char *name,
942 struct samr_LookupNames n;
943 struct lsa_String sname[2];
945 init_lsa_String(&sname[0], name);
947 n.in.domain_handle = domain_handle;
950 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
951 if (NT_STATUS_IS_OK(status)) {
952 *rid = n.out.rids.ids[0];
957 init_lsa_String(&sname[1], "xxNONAMExx");
959 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
960 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
961 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
962 if (NT_STATUS_IS_OK(status)) {
963 return NT_STATUS_UNSUCCESSFUL;
969 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
970 if (!NT_STATUS_IS_OK(status)) {
971 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
975 init_lsa_String(&sname[0], "xxNONAMExx");
977 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
978 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
979 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
980 if (NT_STATUS_IS_OK(status)) {
981 return NT_STATUS_UNSUCCESSFUL;
986 init_lsa_String(&sname[0], "xxNONAMExx");
987 init_lsa_String(&sname[1], "xxNONAME2xx");
989 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
990 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
991 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
992 if (NT_STATUS_IS_OK(status)) {
993 return NT_STATUS_UNSUCCESSFUL;
1001 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1002 struct policy_handle *domain_handle,
1003 const char *name, struct policy_handle *user_handle)
1006 struct samr_OpenUser r;
1009 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1010 if (!NT_STATUS_IS_OK(status)) {
1014 r.in.domain_handle = domain_handle;
1015 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1017 r.out.user_handle = user_handle;
1018 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1019 if (!NT_STATUS_IS_OK(status)) {
1020 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1027 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1028 struct policy_handle *handle)
1031 struct samr_ChangePasswordUser r;
1033 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1034 struct policy_handle user_handle;
1035 char *oldpass = "test";
1036 char *newpass = "test2";
1037 uint8_t old_nt_hash[16], new_nt_hash[16];
1038 uint8_t old_lm_hash[16], new_lm_hash[16];
1040 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1041 if (!NT_STATUS_IS_OK(status)) {
1045 printf("Testing ChangePasswordUser for user 'testuser'\n");
1047 printf("old password: %s\n", oldpass);
1048 printf("new password: %s\n", newpass);
1050 E_md4hash(oldpass, old_nt_hash);
1051 E_md4hash(newpass, new_nt_hash);
1052 E_deshash(oldpass, old_lm_hash);
1053 E_deshash(newpass, new_lm_hash);
1055 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1056 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1057 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1058 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1059 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1060 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1062 r.in.handle = &user_handle;
1063 r.in.lm_present = 1;
1064 r.in.old_lm_crypted = &hash1;
1065 r.in.new_lm_crypted = &hash2;
1066 r.in.nt_present = 1;
1067 r.in.old_nt_crypted = &hash3;
1068 r.in.new_nt_crypted = &hash4;
1069 r.in.cross1_present = 1;
1070 r.in.nt_cross = &hash5;
1071 r.in.cross2_present = 1;
1072 r.in.lm_cross = &hash6;
1074 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1075 if (!NT_STATUS_IS_OK(status)) {
1076 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1080 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1088 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1089 const char *acct_name,
1090 struct policy_handle *handle, char **password)
1093 struct samr_ChangePasswordUser r;
1095 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1096 struct policy_handle user_handle;
1098 uint8_t old_nt_hash[16], new_nt_hash[16];
1099 uint8_t old_lm_hash[16], new_lm_hash[16];
1100 bool changed = true;
1103 struct samr_GetUserPwInfo pwp;
1104 int policy_min_pw_len = 0;
1106 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1107 if (!NT_STATUS_IS_OK(status)) {
1110 pwp.in.user_handle = &user_handle;
1112 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1113 if (NT_STATUS_IS_OK(status)) {
1114 policy_min_pw_len = pwp.out.info.min_password_length;
1116 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1118 printf("Testing ChangePasswordUser\n");
1121 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1125 oldpass = *password;
1127 E_md4hash(oldpass, old_nt_hash);
1128 E_md4hash(newpass, new_nt_hash);
1129 E_deshash(oldpass, old_lm_hash);
1130 E_deshash(newpass, new_lm_hash);
1132 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1133 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1134 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1135 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1136 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1137 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1139 r.in.user_handle = &user_handle;
1140 r.in.lm_present = 1;
1141 /* Break the LM hash */
1143 r.in.old_lm_crypted = &hash1;
1144 r.in.new_lm_crypted = &hash2;
1145 r.in.nt_present = 1;
1146 r.in.old_nt_crypted = &hash3;
1147 r.in.new_nt_crypted = &hash4;
1148 r.in.cross1_present = 1;
1149 r.in.nt_cross = &hash5;
1150 r.in.cross2_present = 1;
1151 r.in.lm_cross = &hash6;
1153 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1154 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1155 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1159 /* Unbreak the LM hash */
1162 r.in.user_handle = &user_handle;
1163 r.in.lm_present = 1;
1164 r.in.old_lm_crypted = &hash1;
1165 r.in.new_lm_crypted = &hash2;
1166 /* Break the NT hash */
1168 r.in.nt_present = 1;
1169 r.in.old_nt_crypted = &hash3;
1170 r.in.new_nt_crypted = &hash4;
1171 r.in.cross1_present = 1;
1172 r.in.nt_cross = &hash5;
1173 r.in.cross2_present = 1;
1174 r.in.lm_cross = &hash6;
1176 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1177 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1178 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1182 /* Unbreak the NT hash */
1185 r.in.user_handle = &user_handle;
1186 r.in.lm_present = 1;
1187 r.in.old_lm_crypted = &hash1;
1188 r.in.new_lm_crypted = &hash2;
1189 r.in.nt_present = 1;
1190 r.in.old_nt_crypted = &hash3;
1191 r.in.new_nt_crypted = &hash4;
1192 r.in.cross1_present = 1;
1193 r.in.nt_cross = &hash5;
1194 r.in.cross2_present = 1;
1195 /* Break the LM cross */
1197 r.in.lm_cross = &hash6;
1199 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1200 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1201 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1205 /* Unbreak the LM cross */
1208 r.in.user_handle = &user_handle;
1209 r.in.lm_present = 1;
1210 r.in.old_lm_crypted = &hash1;
1211 r.in.new_lm_crypted = &hash2;
1212 r.in.nt_present = 1;
1213 r.in.old_nt_crypted = &hash3;
1214 r.in.new_nt_crypted = &hash4;
1215 r.in.cross1_present = 1;
1216 /* Break the NT cross */
1218 r.in.nt_cross = &hash5;
1219 r.in.cross2_present = 1;
1220 r.in.lm_cross = &hash6;
1222 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1223 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1224 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1228 /* Unbreak the NT cross */
1232 /* Reset the hashes to not broken values */
1233 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1234 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1235 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1236 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1237 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1238 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1240 r.in.user_handle = &user_handle;
1241 r.in.lm_present = 1;
1242 r.in.old_lm_crypted = &hash1;
1243 r.in.new_lm_crypted = &hash2;
1244 r.in.nt_present = 1;
1245 r.in.old_nt_crypted = &hash3;
1246 r.in.new_nt_crypted = &hash4;
1247 r.in.cross1_present = 1;
1248 r.in.nt_cross = &hash5;
1249 r.in.cross2_present = 0;
1250 r.in.lm_cross = NULL;
1252 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1253 if (NT_STATUS_IS_OK(status)) {
1255 *password = newpass;
1256 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1257 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1262 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1264 E_md4hash(oldpass, old_nt_hash);
1265 E_md4hash(newpass, new_nt_hash);
1266 E_deshash(oldpass, old_lm_hash);
1267 E_deshash(newpass, new_lm_hash);
1270 /* Reset the hashes to not broken values */
1271 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1272 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1273 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1274 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1275 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1276 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1278 r.in.user_handle = &user_handle;
1279 r.in.lm_present = 1;
1280 r.in.old_lm_crypted = &hash1;
1281 r.in.new_lm_crypted = &hash2;
1282 r.in.nt_present = 1;
1283 r.in.old_nt_crypted = &hash3;
1284 r.in.new_nt_crypted = &hash4;
1285 r.in.cross1_present = 0;
1286 r.in.nt_cross = NULL;
1287 r.in.cross2_present = 1;
1288 r.in.lm_cross = &hash6;
1290 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1291 if (NT_STATUS_IS_OK(status)) {
1293 *password = newpass;
1294 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1295 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1300 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1302 E_md4hash(oldpass, old_nt_hash);
1303 E_md4hash(newpass, new_nt_hash);
1304 E_deshash(oldpass, old_lm_hash);
1305 E_deshash(newpass, new_lm_hash);
1308 /* Reset the hashes to not broken values */
1309 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1310 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1311 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1312 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1313 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1314 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1316 r.in.user_handle = &user_handle;
1317 r.in.lm_present = 1;
1318 r.in.old_lm_crypted = &hash1;
1319 r.in.new_lm_crypted = &hash2;
1320 r.in.nt_present = 1;
1321 r.in.old_nt_crypted = &hash3;
1322 r.in.new_nt_crypted = &hash4;
1323 r.in.cross1_present = 1;
1324 r.in.nt_cross = &hash5;
1325 r.in.cross2_present = 1;
1326 r.in.lm_cross = &hash6;
1328 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1329 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1330 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1331 } else if (!NT_STATUS_IS_OK(status)) {
1332 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1336 *password = newpass;
1339 r.in.user_handle = &user_handle;
1340 r.in.lm_present = 1;
1341 r.in.old_lm_crypted = &hash1;
1342 r.in.new_lm_crypted = &hash2;
1343 r.in.nt_present = 1;
1344 r.in.old_nt_crypted = &hash3;
1345 r.in.new_nt_crypted = &hash4;
1346 r.in.cross1_present = 1;
1347 r.in.nt_cross = &hash5;
1348 r.in.cross2_present = 1;
1349 r.in.lm_cross = &hash6;
1352 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1353 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1354 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1355 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1356 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1362 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1370 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1371 const char *acct_name,
1372 struct policy_handle *handle, char **password)
1375 struct samr_OemChangePasswordUser2 r;
1377 struct samr_Password lm_verifier;
1378 struct samr_CryptPassword lm_pass;
1379 struct lsa_AsciiString server, account, account_bad;
1382 uint8_t old_lm_hash[16], new_lm_hash[16];
1384 struct samr_GetDomPwInfo dom_pw_info;
1385 int policy_min_pw_len = 0;
1387 struct lsa_String domain_name;
1389 domain_name.string = "";
1390 dom_pw_info.in.domain_name = &domain_name;
1392 printf("Testing OemChangePasswordUser2\n");
1395 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1399 oldpass = *password;
1401 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1402 if (NT_STATUS_IS_OK(status)) {
1403 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1406 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1408 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1409 account.string = acct_name;
1411 E_deshash(oldpass, old_lm_hash);
1412 E_deshash(newpass, new_lm_hash);
1414 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1415 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1416 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1418 r.in.server = &server;
1419 r.in.account = &account;
1420 r.in.password = &lm_pass;
1421 r.in.hash = &lm_verifier;
1423 /* Break the verification */
1424 lm_verifier.hash[0]++;
1426 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1428 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1429 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1430 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1435 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1436 /* Break the old password */
1438 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1439 /* unbreak it for the next operation */
1441 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1443 r.in.server = &server;
1444 r.in.account = &account;
1445 r.in.password = &lm_pass;
1446 r.in.hash = &lm_verifier;
1448 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1450 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1451 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1452 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1457 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1458 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1460 r.in.server = &server;
1461 r.in.account = &account;
1462 r.in.password = &lm_pass;
1465 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1467 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1468 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1469 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1474 /* This shouldn't be a valid name */
1475 account_bad.string = TEST_ACCOUNT_NAME "XX";
1476 r.in.account = &account_bad;
1478 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1480 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1481 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1486 /* This shouldn't be a valid name */
1487 account_bad.string = TEST_ACCOUNT_NAME "XX";
1488 r.in.account = &account_bad;
1489 r.in.password = &lm_pass;
1490 r.in.hash = &lm_verifier;
1492 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1494 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1495 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1500 /* This shouldn't be a valid name */
1501 account_bad.string = TEST_ACCOUNT_NAME "XX";
1502 r.in.account = &account_bad;
1503 r.in.password = NULL;
1504 r.in.hash = &lm_verifier;
1506 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1508 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1509 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1514 E_deshash(oldpass, old_lm_hash);
1515 E_deshash(newpass, new_lm_hash);
1517 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1518 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1519 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1521 r.in.server = &server;
1522 r.in.account = &account;
1523 r.in.password = &lm_pass;
1524 r.in.hash = &lm_verifier;
1526 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1527 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1528 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1529 } else if (!NT_STATUS_IS_OK(status)) {
1530 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1533 *password = newpass;
1540 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1541 const char *acct_name,
1543 char *newpass, bool allow_password_restriction)
1546 struct samr_ChangePasswordUser2 r;
1548 struct lsa_String server, account;
1549 struct samr_CryptPassword nt_pass, lm_pass;
1550 struct samr_Password nt_verifier, lm_verifier;
1552 uint8_t old_nt_hash[16], new_nt_hash[16];
1553 uint8_t old_lm_hash[16], new_lm_hash[16];
1555 struct samr_GetDomPwInfo dom_pw_info;
1557 struct lsa_String domain_name;
1559 domain_name.string = "";
1560 dom_pw_info.in.domain_name = &domain_name;
1562 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1565 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1568 oldpass = *password;
1571 int policy_min_pw_len = 0;
1572 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1573 if (NT_STATUS_IS_OK(status)) {
1574 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1577 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1580 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1581 init_lsa_String(&account, acct_name);
1583 E_md4hash(oldpass, old_nt_hash);
1584 E_md4hash(newpass, new_nt_hash);
1586 E_deshash(oldpass, old_lm_hash);
1587 E_deshash(newpass, new_lm_hash);
1589 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1590 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1591 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1593 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1594 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1595 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1597 r.in.server = &server;
1598 r.in.account = &account;
1599 r.in.nt_password = &nt_pass;
1600 r.in.nt_verifier = &nt_verifier;
1602 r.in.lm_password = &lm_pass;
1603 r.in.lm_verifier = &lm_verifier;
1605 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1606 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1607 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1608 } else if (!NT_STATUS_IS_OK(status)) {
1609 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1612 *password = newpass;
1619 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1620 const char *account_string,
1621 int policy_min_pw_len,
1623 const char *newpass,
1624 NTTIME last_password_change,
1625 bool handle_reject_reason)
1628 struct samr_ChangePasswordUser3 r;
1630 struct lsa_String server, account, account_bad;
1631 struct samr_CryptPassword nt_pass, lm_pass;
1632 struct samr_Password nt_verifier, lm_verifier;
1634 uint8_t old_nt_hash[16], new_nt_hash[16];
1635 uint8_t old_lm_hash[16], new_lm_hash[16];
1638 printf("Testing ChangePasswordUser3\n");
1640 if (newpass == NULL) {
1642 if (policy_min_pw_len == 0) {
1643 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1645 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1647 } while (check_password_quality(newpass) == false);
1649 printf("Using password '%s'\n", newpass);
1653 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1657 oldpass = *password;
1658 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1659 init_lsa_String(&account, account_string);
1661 E_md4hash(oldpass, old_nt_hash);
1662 E_md4hash(newpass, new_nt_hash);
1664 E_deshash(oldpass, old_lm_hash);
1665 E_deshash(newpass, new_lm_hash);
1667 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1668 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1669 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1671 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1672 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1673 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1675 /* Break the verification */
1676 nt_verifier.hash[0]++;
1678 r.in.server = &server;
1679 r.in.account = &account;
1680 r.in.nt_password = &nt_pass;
1681 r.in.nt_verifier = &nt_verifier;
1683 r.in.lm_password = &lm_pass;
1684 r.in.lm_verifier = &lm_verifier;
1685 r.in.password3 = NULL;
1687 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1688 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1689 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1690 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1695 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1696 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1697 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1699 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1700 /* Break the NT hash */
1702 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1703 /* Unbreak it again */
1705 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1707 r.in.server = &server;
1708 r.in.account = &account;
1709 r.in.nt_password = &nt_pass;
1710 r.in.nt_verifier = &nt_verifier;
1712 r.in.lm_password = &lm_pass;
1713 r.in.lm_verifier = &lm_verifier;
1714 r.in.password3 = NULL;
1716 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1717 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1718 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1719 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1724 /* This shouldn't be a valid name */
1725 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1727 r.in.account = &account_bad;
1728 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1729 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1730 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1735 E_md4hash(oldpass, old_nt_hash);
1736 E_md4hash(newpass, new_nt_hash);
1738 E_deshash(oldpass, old_lm_hash);
1739 E_deshash(newpass, new_lm_hash);
1741 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1742 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1743 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1745 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1746 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1747 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1749 r.in.server = &server;
1750 r.in.account = &account;
1751 r.in.nt_password = &nt_pass;
1752 r.in.nt_verifier = &nt_verifier;
1754 r.in.lm_password = &lm_pass;
1755 r.in.lm_verifier = &lm_verifier;
1756 r.in.password3 = NULL;
1758 unix_to_nt_time(&t, time(NULL));
1760 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1762 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1765 && handle_reject_reason
1766 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1767 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1769 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1770 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1771 SAMR_REJECT_OTHER, r.out.reject->reason);
1776 /* We tested the order of precendence which is as follows:
1785 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1786 (last_password_change + r.out.dominfo->min_password_age > t)) {
1788 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1789 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1790 SAMR_REJECT_OTHER, r.out.reject->reason);
1794 } else if ((r.out.dominfo->min_password_length > 0) &&
1795 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1797 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1798 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1799 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1803 } else if ((r.out.dominfo->password_history_length > 0) &&
1804 strequal(oldpass, newpass)) {
1806 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1807 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1808 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1811 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1813 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1814 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1815 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1821 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1822 /* retry with adjusted size */
1823 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1824 r.out.dominfo->min_password_length,
1825 password, NULL, 0, false);
1829 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1830 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1831 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1832 SAMR_REJECT_OTHER, r.out.reject->reason);
1835 /* Perhaps the server has a 'min password age' set? */
1837 } else if (!NT_STATUS_IS_OK(status)) {
1838 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1841 *password = talloc_strdup(mem_ctx, newpass);
1848 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1849 struct policy_handle *alias_handle)
1851 struct samr_GetMembersInAlias r;
1852 struct lsa_SidArray sids;
1856 printf("Testing GetMembersInAlias\n");
1858 r.in.alias_handle = alias_handle;
1861 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1862 if (!NT_STATUS_IS_OK(status)) {
1863 printf("GetMembersInAlias failed - %s\n",
1871 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1872 struct policy_handle *alias_handle,
1873 const struct dom_sid *domain_sid)
1875 struct samr_AddAliasMember r;
1876 struct samr_DeleteAliasMember d;
1879 struct dom_sid *sid;
1881 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1883 printf("testing AddAliasMember\n");
1884 r.in.alias_handle = alias_handle;
1887 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1888 if (!NT_STATUS_IS_OK(status)) {
1889 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1893 d.in.alias_handle = alias_handle;
1896 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1905 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1906 struct policy_handle *alias_handle)
1908 struct samr_AddMultipleMembersToAlias a;
1909 struct samr_RemoveMultipleMembersFromAlias r;
1912 struct lsa_SidArray sids;
1914 printf("testing AddMultipleMembersToAlias\n");
1915 a.in.alias_handle = alias_handle;
1919 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1921 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1922 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1923 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1925 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1926 if (!NT_STATUS_IS_OK(status)) {
1927 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1932 printf("testing RemoveMultipleMembersFromAlias\n");
1933 r.in.alias_handle = alias_handle;
1936 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1937 if (!NT_STATUS_IS_OK(status)) {
1938 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1942 /* strange! removing twice doesn't give any error */
1943 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1944 if (!NT_STATUS_IS_OK(status)) {
1945 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1949 /* but removing an alias that isn't there does */
1950 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1952 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1953 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1954 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1961 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1962 struct policy_handle *user_handle)
1964 struct samr_TestPrivateFunctionsUser r;
1968 printf("Testing TestPrivateFunctionsUser\n");
1970 r.in.user_handle = user_handle;
1972 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1973 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1974 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1982 static bool test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1983 struct policy_handle *user_handle,
1984 struct policy_handle *domain_handle,
1985 uint32_t base_acct_flags,
1986 const char *base_acct_name, enum torture_samr_choice which_ops)
1988 TALLOC_CTX *user_ctx;
1989 char *password = NULL;
1993 const uint32_t password_fields[] = {
1994 SAMR_FIELD_PASSWORD,
1995 SAMR_FIELD_PASSWORD2,
1996 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2000 user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
2001 switch (which_ops) {
2002 case TORTURE_SAMR_USER_ATTRIBUTES:
2003 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
2007 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
2011 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
2015 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
2020 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
2024 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
2028 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
2032 case TORTURE_SAMR_PASSWORDS:
2033 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2034 char simple_pass[9];
2035 char *v = generate_random_str(mem_ctx, 1);
2037 ZERO_STRUCT(simple_pass);
2038 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2040 printf("Testing machine account password policy rules\n");
2042 /* Workstation trust accounts don't seem to need to honour password quality policy */
2043 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2047 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, simple_pass, false)) {
2051 /* reset again, to allow another 'user' password change */
2052 if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2056 /* Try a 'short' password */
2057 if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, samr_rand_pass(mem_ctx, 4), false)) {
2063 for (i = 0; password_fields[i]; i++) {
2064 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
2068 /* check it was set right */
2069 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, false)) {
2074 for (i = 0; password_fields[i]; i++) {
2075 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
2079 /* check it was set right */
2080 if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, false)) {
2085 if (!test_SetUserPassEx(p, user_ctx, user_handle, false, &password)) {
2089 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
2094 case TORTURE_SAMR_OTHER:
2095 /* We just need the account to exist */
2098 talloc_free(user_ctx);
2102 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2103 struct policy_handle *alias_handle,
2104 const struct dom_sid *domain_sid)
2108 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2112 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2116 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2120 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2124 if (torture_setting_bool(tctx, "samba4", false)) {
2125 printf("skipping MultipleMembers Alias tests against Samba4\n");
2129 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2137 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2138 struct policy_handle *user_handle)
2140 struct samr_DeleteUser d;
2143 printf("Testing DeleteUser\n");
2145 d.in.user_handle = user_handle;
2146 d.out.user_handle = user_handle;
2148 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2149 if (!NT_STATUS_IS_OK(status)) {
2150 printf("DeleteUser failed - %s\n", nt_errstr(status));
2157 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2158 struct policy_handle *handle, const char *name)
2161 struct samr_DeleteUser d;
2162 struct policy_handle user_handle;
2165 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2166 if (!NT_STATUS_IS_OK(status)) {
2170 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2171 if (!NT_STATUS_IS_OK(status)) {
2175 d.in.user_handle = &user_handle;
2176 d.out.user_handle = &user_handle;
2177 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2178 if (!NT_STATUS_IS_OK(status)) {
2185 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2190 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2191 struct policy_handle *handle, const char *name)
2194 struct samr_OpenGroup r;
2195 struct samr_DeleteDomainGroup d;
2196 struct policy_handle group_handle;
2199 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2200 if (!NT_STATUS_IS_OK(status)) {
2204 r.in.domain_handle = handle;
2205 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2207 r.out.group_handle = &group_handle;
2208 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2209 if (!NT_STATUS_IS_OK(status)) {
2213 d.in.group_handle = &group_handle;
2214 d.out.group_handle = &group_handle;
2215 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2216 if (!NT_STATUS_IS_OK(status)) {
2223 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2228 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2229 struct policy_handle *domain_handle, const char *name)
2232 struct samr_OpenAlias r;
2233 struct samr_DeleteDomAlias d;
2234 struct policy_handle alias_handle;
2237 printf("testing DeleteAlias_byname\n");
2239 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2240 if (!NT_STATUS_IS_OK(status)) {
2244 r.in.domain_handle = domain_handle;
2245 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2247 r.out.alias_handle = &alias_handle;
2248 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2249 if (!NT_STATUS_IS_OK(status)) {
2253 d.in.alias_handle = &alias_handle;
2254 d.out.alias_handle = &alias_handle;
2255 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2256 if (!NT_STATUS_IS_OK(status)) {
2263 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2267 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2268 struct policy_handle *alias_handle)
2270 struct samr_DeleteDomAlias d;
2273 printf("Testing DeleteAlias\n");
2275 d.in.alias_handle = alias_handle;
2276 d.out.alias_handle = alias_handle;
2278 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2279 if (!NT_STATUS_IS_OK(status)) {
2280 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2287 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2288 struct policy_handle *domain_handle,
2289 struct policy_handle *alias_handle,
2290 const struct dom_sid *domain_sid)
2293 struct samr_CreateDomAlias r;
2294 struct lsa_String name;
2298 init_lsa_String(&name, TEST_ALIASNAME);
2299 r.in.domain_handle = domain_handle;
2300 r.in.alias_name = &name;
2301 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2302 r.out.alias_handle = alias_handle;
2305 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2307 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2309 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2310 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2314 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2315 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2318 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2321 if (!NT_STATUS_IS_OK(status)) {
2322 printf("CreateAlias failed - %s\n", nt_errstr(status));
2326 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2333 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2334 const char *acct_name,
2335 struct policy_handle *domain_handle, char **password)
2343 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2347 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2351 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2355 /* test what happens when setting the old password again */
2356 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2361 char simple_pass[9];
2362 char *v = generate_random_str(mem_ctx, 1);
2364 ZERO_STRUCT(simple_pass);
2365 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2367 /* test what happens when picking a simple password */
2368 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2373 /* set samr_SetDomainInfo level 1 with min_length 5 */
2375 struct samr_QueryDomainInfo r;
2376 struct samr_SetDomainInfo s;
2377 uint16_t len_old, len;
2378 uint32_t pwd_prop_old;
2379 int64_t min_pwd_age_old;
2384 r.in.domain_handle = domain_handle;
2387 printf("testing samr_QueryDomainInfo level 1\n");
2388 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2389 if (!NT_STATUS_IS_OK(status)) {
2393 s.in.domain_handle = domain_handle;
2395 s.in.info = r.out.info;
2397 /* remember the old min length, so we can reset it */
2398 len_old = s.in.info->info1.min_password_length;
2399 s.in.info->info1.min_password_length = len;
2400 pwd_prop_old = s.in.info->info1.password_properties;
2401 /* turn off password complexity checks for this test */
2402 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2404 min_pwd_age_old = s.in.info->info1.min_password_age;
2405 s.in.info->info1.min_password_age = 0;
2407 printf("testing samr_SetDomainInfo level 1\n");
2408 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2409 if (!NT_STATUS_IS_OK(status)) {
2413 printf("calling test_ChangePasswordUser3 with too short password\n");
2415 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2419 s.in.info->info1.min_password_length = len_old;
2420 s.in.info->info1.password_properties = pwd_prop_old;
2421 s.in.info->info1.min_password_age = min_pwd_age_old;
2423 printf("testing samr_SetDomainInfo level 1\n");
2424 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2425 if (!NT_STATUS_IS_OK(status)) {
2433 struct samr_OpenUser r;
2434 struct samr_QueryUserInfo q;
2435 struct samr_LookupNames n;
2436 struct policy_handle user_handle;
2438 n.in.domain_handle = domain_handle;
2440 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2441 n.in.names[0].string = acct_name;
2443 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2444 if (!NT_STATUS_IS_OK(status)) {
2445 printf("LookupNames failed - %s\n", nt_errstr(status));
2449 r.in.domain_handle = domain_handle;
2450 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2451 r.in.rid = n.out.rids.ids[0];
2452 r.out.user_handle = &user_handle;
2454 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2455 if (!NT_STATUS_IS_OK(status)) {
2456 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2460 q.in.user_handle = &user_handle;
2463 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2464 if (!NT_STATUS_IS_OK(status)) {
2465 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2469 printf("calling test_ChangePasswordUser3 with too early password change\n");
2471 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2472 q.out.info->info5.last_password_change, true)) {
2477 /* we change passwords twice - this has the effect of verifying
2478 they were changed correctly for the final call */
2479 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2483 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2490 static bool test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2491 struct policy_handle *domain_handle,
2492 struct policy_handle *user_handle_out,
2493 enum torture_samr_choice which_ops)
2496 TALLOC_CTX *user_ctx;
2499 struct samr_CreateUser r;
2500 struct samr_QueryUserInfo q;
2501 struct samr_DeleteUser d;
2504 /* This call creates a 'normal' account - check that it really does */
2505 const uint32_t acct_flags = ACB_NORMAL;
2506 struct lsa_String name;
2509 struct policy_handle user_handle;
2510 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2511 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2513 r.in.domain_handle = domain_handle;
2514 r.in.account_name = &name;
2515 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2516 r.out.user_handle = &user_handle;
2519 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2521 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2523 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2524 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2525 talloc_free(user_ctx);
2529 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2530 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2531 talloc_free(user_ctx);
2534 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2536 if (!NT_STATUS_IS_OK(status)) {
2537 talloc_free(user_ctx);
2538 printf("CreateUser failed - %s\n", nt_errstr(status));
2541 q.in.user_handle = &user_handle;
2544 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2545 if (!NT_STATUS_IS_OK(status)) {
2546 printf("QueryUserInfo level %u failed - %s\n",
2547 q.in.level, nt_errstr(status));
2550 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2551 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2552 q.out.info->info16.acct_flags,
2558 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2559 acct_flags, name.string, which_ops)) {
2563 if (user_handle_out) {
2564 *user_handle_out = user_handle;
2566 printf("Testing DeleteUser (createuser test)\n");
2568 d.in.user_handle = &user_handle;
2569 d.out.user_handle = &user_handle;
2571 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2572 if (!NT_STATUS_IS_OK(status)) {
2573 printf("DeleteUser failed - %s\n", nt_errstr(status));
2580 talloc_free(user_ctx);
2586 static bool test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2587 struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2590 struct samr_CreateUser2 r;
2591 struct samr_QueryUserInfo q;
2592 struct samr_DeleteUser d;
2593 struct policy_handle user_handle;
2595 struct lsa_String name;
2600 uint32_t acct_flags;
2601 const char *account_name;
2603 } account_types[] = {
2604 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2605 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2606 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2607 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2608 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2609 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2610 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2611 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2612 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2613 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2614 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2615 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2616 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2617 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2618 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2621 for (i = 0; account_types[i].account_name; i++) {
2622 TALLOC_CTX *user_ctx;
2623 uint32_t acct_flags = account_types[i].acct_flags;
2624 uint32_t access_granted;
2625 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2626 init_lsa_String(&name, account_types[i].account_name);
2628 r.in.domain_handle = domain_handle;
2629 r.in.account_name = &name;
2630 r.in.acct_flags = acct_flags;
2631 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2632 r.out.user_handle = &user_handle;
2633 r.out.access_granted = &access_granted;
2636 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2638 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2640 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2641 talloc_free(user_ctx);
2642 printf("Server refused create of '%s'\n", r.in.account_name->string);
2645 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2646 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2647 talloc_free(user_ctx);
2651 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2654 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2655 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2656 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2660 if (NT_STATUS_IS_OK(status)) {
2661 q.in.user_handle = &user_handle;
2664 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2665 if (!NT_STATUS_IS_OK(status)) {
2666 printf("QueryUserInfo level %u failed - %s\n",
2667 q.in.level, nt_errstr(status));
2670 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2671 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2672 q.out.info->info5.acct_flags,
2676 switch (acct_flags) {
2678 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2679 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2680 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2685 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2686 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2687 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2692 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2693 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2694 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2701 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle,
2702 acct_flags, name.string, which_ops)) {
2706 printf("Testing DeleteUser (createuser2 test)\n");
2708 d.in.user_handle = &user_handle;
2709 d.out.user_handle = &user_handle;
2711 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2712 if (!NT_STATUS_IS_OK(status)) {
2713 printf("DeleteUser failed - %s\n", nt_errstr(status));
2717 talloc_free(user_ctx);
2723 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2724 struct policy_handle *handle)
2727 struct samr_QueryAliasInfo r;
2728 uint16_t levels[] = {1, 2, 3};
2732 for (i=0;i<ARRAY_SIZE(levels);i++) {
2733 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2735 r.in.alias_handle = handle;
2736 r.in.level = levels[i];
2738 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 printf("QueryAliasInfo level %u failed - %s\n",
2741 levels[i], nt_errstr(status));
2749 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2750 struct policy_handle *handle)
2753 struct samr_QueryGroupInfo r;
2754 uint16_t levels[] = {1, 2, 3, 4, 5};
2758 for (i=0;i<ARRAY_SIZE(levels);i++) {
2759 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2761 r.in.group_handle = handle;
2762 r.in.level = levels[i];
2764 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2765 if (!NT_STATUS_IS_OK(status)) {
2766 printf("QueryGroupInfo level %u failed - %s\n",
2767 levels[i], nt_errstr(status));
2775 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2776 struct policy_handle *handle)
2779 struct samr_QueryGroupMember r;
2782 printf("Testing QueryGroupMember\n");
2784 r.in.group_handle = handle;
2786 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2787 if (!NT_STATUS_IS_OK(status)) {
2788 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2796 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2797 struct policy_handle *handle)
2800 struct samr_QueryGroupInfo r;
2801 struct samr_SetGroupInfo s;
2802 uint16_t levels[] = {1, 2, 3, 4};
2803 uint16_t set_ok[] = {0, 1, 1, 1};
2807 for (i=0;i<ARRAY_SIZE(levels);i++) {
2808 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2810 r.in.group_handle = handle;
2811 r.in.level = levels[i];
2813 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2814 if (!NT_STATUS_IS_OK(status)) {
2815 printf("QueryGroupInfo level %u failed - %s\n",
2816 levels[i], nt_errstr(status));
2820 printf("Testing SetGroupInfo level %u\n", levels[i]);
2822 s.in.group_handle = handle;
2823 s.in.level = levels[i];
2824 s.in.info = r.out.info;
2827 /* disabled this, as it changes the name only from the point of view of samr,
2828 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2829 the name is still reserved, so creating the old name fails, but deleting by the old name
2831 if (s.in.level == 2) {
2832 init_lsa_String(&s.in.info->string, "NewName");
2836 if (s.in.level == 4) {
2837 init_lsa_String(&s.in.info->description, "test description");
2840 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 printf("SetGroupInfo level %u failed - %s\n",
2844 r.in.level, nt_errstr(status));
2849 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2850 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2851 r.in.level, nt_errstr(status));
2861 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2862 struct policy_handle *handle)
2865 struct samr_QueryUserInfo r;
2866 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2867 11, 12, 13, 14, 16, 17, 20, 21};
2871 for (i=0;i<ARRAY_SIZE(levels);i++) {
2872 printf("Testing QueryUserInfo level %u\n", levels[i]);
2874 r.in.user_handle = handle;
2875 r.in.level = levels[i];
2877 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2878 if (!NT_STATUS_IS_OK(status)) {
2879 printf("QueryUserInfo level %u failed - %s\n",
2880 levels[i], nt_errstr(status));
2888 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2889 struct policy_handle *handle)
2892 struct samr_QueryUserInfo2 r;
2893 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2894 11, 12, 13, 14, 16, 17, 20, 21};
2898 for (i=0;i<ARRAY_SIZE(levels);i++) {
2899 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2901 r.in.user_handle = handle;
2902 r.in.level = levels[i];
2904 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2905 if (!NT_STATUS_IS_OK(status)) {
2906 printf("QueryUserInfo2 level %u failed - %s\n",
2907 levels[i], nt_errstr(status));
2915 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2916 struct policy_handle *handle, uint32_t rid)
2919 struct samr_OpenUser r;
2920 struct policy_handle user_handle;
2923 printf("Testing OpenUser(%u)\n", rid);
2925 r.in.domain_handle = handle;
2926 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2928 r.out.user_handle = &user_handle;
2930 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2931 if (!NT_STATUS_IS_OK(status)) {
2932 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2936 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2940 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2944 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2948 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2952 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2956 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2963 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2964 struct policy_handle *handle, uint32_t rid)
2967 struct samr_OpenGroup r;
2968 struct policy_handle group_handle;
2971 printf("Testing OpenGroup(%u)\n", rid);
2973 r.in.domain_handle = handle;
2974 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2976 r.out.group_handle = &group_handle;
2978 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2979 if (!NT_STATUS_IS_OK(status)) {
2980 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2984 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2988 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2992 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2996 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3003 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3004 struct policy_handle *handle, uint32_t rid)
3007 struct samr_OpenAlias r;
3008 struct policy_handle alias_handle;
3011 printf("Testing OpenAlias(%u)\n", rid);
3013 r.in.domain_handle = handle;
3014 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3016 r.out.alias_handle = &alias_handle;
3018 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3019 if (!NT_STATUS_IS_OK(status)) {
3020 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3024 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3028 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3032 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3036 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3043 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3044 struct policy_handle *handle, uint32_t rid,
3045 uint32_t acct_flag_mask)
3048 struct samr_OpenUser r;
3049 struct samr_QueryUserInfo q;
3050 struct policy_handle user_handle;
3053 printf("Testing OpenUser(%u)\n", rid);
3055 r.in.domain_handle = handle;
3056 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3058 r.out.user_handle = &user_handle;
3060 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3061 if (!NT_STATUS_IS_OK(status)) {
3062 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3066 q.in.user_handle = &user_handle;
3069 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3070 if (!NT_STATUS_IS_OK(status)) {
3071 printf("QueryUserInfo level 16 failed - %s\n",
3075 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3076 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3077 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3082 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3089 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3090 struct policy_handle *handle)
3092 NTSTATUS status = STATUS_MORE_ENTRIES;
3093 struct samr_EnumDomainUsers r;
3094 uint32_t mask, resume_handle=0;
3097 struct samr_LookupNames n;
3098 struct samr_LookupRids lr ;
3099 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3100 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3101 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3104 printf("Testing EnumDomainUsers\n");
3106 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3107 r.in.domain_handle = handle;
3108 r.in.resume_handle = &resume_handle;
3109 r.in.acct_flags = mask = masks[mask_idx];
3110 r.in.max_size = (uint32_t)-1;
3111 r.out.resume_handle = &resume_handle;
3113 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3114 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3115 !NT_STATUS_IS_OK(status)) {
3116 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3121 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3125 if (r.out.sam->count == 0) {
3129 for (i=0;i<r.out.sam->count;i++) {
3131 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3134 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3140 printf("Testing LookupNames\n");
3141 n.in.domain_handle = handle;
3142 n.in.num_names = r.out.sam->count;
3143 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3144 for (i=0;i<r.out.sam->count;i++) {
3145 n.in.names[i].string = r.out.sam->entries[i].name.string;
3147 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3148 if (!NT_STATUS_IS_OK(status)) {
3149 printf("LookupNames failed - %s\n", nt_errstr(status));
3154 printf("Testing LookupRids\n");
3155 lr.in.domain_handle = handle;
3156 lr.in.num_rids = r.out.sam->count;
3157 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3158 for (i=0;i<r.out.sam->count;i++) {
3159 lr.in.rids[i] = r.out.sam->entries[i].idx;
3161 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3162 if (!NT_STATUS_IS_OK(status)) {
3163 printf("LookupRids failed - %s\n", nt_errstr(status));
3171 try blasting the server with a bunch of sync requests
3173 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx,
3174 struct policy_handle *handle)
3177 struct samr_EnumDomainUsers r;
3178 uint32_t resume_handle=0;
3180 #define ASYNC_COUNT 100
3181 struct rpc_request *req[ASYNC_COUNT];
3183 if (!torture_setting_bool(tctx, "dangerous", false)) {
3184 printf("samr async test disabled - enable dangerous tests to use\n");
3188 printf("Testing EnumDomainUsers_async\n");
3190 r.in.domain_handle = handle;
3191 r.in.resume_handle = &resume_handle;
3192 r.in.acct_flags = 0;
3193 r.in.max_size = (uint32_t)-1;
3194 r.out.resume_handle = &resume_handle;
3196 for (i=0;i<ASYNC_COUNT;i++) {
3197 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3200 for (i=0;i<ASYNC_COUNT;i++) {
3201 status = dcerpc_ndr_request_recv(req[i]);
3202 if (!NT_STATUS_IS_OK(status)) {
3203 printf("EnumDomainUsers[%d] failed - %s\n",
3204 i, nt_errstr(status));
3209 printf("%d async requests OK\n", i);
3214 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3215 struct policy_handle *handle)
3218 struct samr_EnumDomainGroups r;
3219 uint32_t resume_handle=0;
3223 printf("Testing EnumDomainGroups\n");
3225 r.in.domain_handle = handle;
3226 r.in.resume_handle = &resume_handle;
3227 r.in.max_size = (uint32_t)-1;
3228 r.out.resume_handle = &resume_handle;
3230 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3231 if (!NT_STATUS_IS_OK(status)) {
3232 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3240 for (i=0;i<r.out.sam->count;i++) {
3241 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3249 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3250 struct policy_handle *handle)
3253 struct samr_EnumDomainAliases r;
3254 uint32_t resume_handle=0;
3258 printf("Testing EnumDomainAliases\n");
3260 r.in.domain_handle = handle;
3261 r.in.resume_handle = &resume_handle;
3262 r.in.acct_flags = (uint32_t)-1;
3263 r.out.resume_handle = &resume_handle;
3265 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3266 if (!NT_STATUS_IS_OK(status)) {
3267 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3275 for (i=0;i<r.out.sam->count;i++) {
3276 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3284 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3285 struct policy_handle *handle)
3288 struct samr_GetDisplayEnumerationIndex r;
3290 uint16_t levels[] = {1, 2, 3, 4, 5};
3291 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3294 for (i=0;i<ARRAY_SIZE(levels);i++) {
3295 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3297 r.in.domain_handle = handle;
3298 r.in.level = levels[i];
3299 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3301 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3304 !NT_STATUS_IS_OK(status) &&
3305 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3306 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3307 levels[i], nt_errstr(status));
3311 init_lsa_String(&r.in.name, "zzzzzzzz");
3313 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3315 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3316 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3317 levels[i], nt_errstr(status));
3325 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3326 struct policy_handle *handle)
3329 struct samr_GetDisplayEnumerationIndex2 r;
3331 uint16_t levels[] = {1, 2, 3, 4, 5};
3332 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3335 for (i=0;i<ARRAY_SIZE(levels);i++) {
3336 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3338 r.in.domain_handle = handle;
3339 r.in.level = levels[i];
3340 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3342 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3344 !NT_STATUS_IS_OK(status) &&
3345 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3346 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3347 levels[i], nt_errstr(status));
3351 init_lsa_String(&r.in.name, "zzzzzzzz");
3353 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3354 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3355 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3356 levels[i], nt_errstr(status));
3364 #define STRING_EQUAL_QUERY(s1, s2, user) \
3365 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3366 /* odd, but valid */ \
3367 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3368 printf("%s mismatch for %s: %s != %s (%s)\n", \
3369 #s1, user.string, s1.string, s2.string, __location__); \
3372 #define INT_EQUAL_QUERY(s1, s2, user) \
3374 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3375 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3379 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3380 struct samr_QueryDisplayInfo *querydisplayinfo,
3381 bool *seen_testuser)
3383 struct samr_OpenUser r;
3384 struct samr_QueryUserInfo q;
3385 struct policy_handle user_handle;
3388 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3389 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3390 for (i = 0; ; i++) {
3391 switch (querydisplayinfo->in.level) {
3393 if (i >= querydisplayinfo->out.info.info1.count) {
3396 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3399 if (i >= querydisplayinfo->out.info.info2.count) {
3402 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3408 /* Not interested in validating just the account name */
3412 r.out.user_handle = &user_handle;
3414 switch (querydisplayinfo->in.level) {
3417 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3418 if (!NT_STATUS_IS_OK(status)) {
3419 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3424 q.in.user_handle = &user_handle;
3426 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3427 if (!NT_STATUS_IS_OK(status)) {
3428 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3432 switch (querydisplayinfo->in.level) {
3434 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3435 *seen_testuser = true;
3437 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3438 q.out.info->info21.full_name, q.out.info->info21.account_name);
3439 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3440 q.out.info->info21.account_name, q.out.info->info21.account_name);
3441 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3442 q.out.info->info21.description, q.out.info->info21.account_name);
3443 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3444 q.out.info->info21.rid, q.out.info->info21.account_name);
3445 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3446 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3450 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3451 q.out.info->info21.account_name, q.out.info->info21.account_name);
3452 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3453 q.out.info->info21.description, q.out.info->info21.account_name);
3454 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3455 q.out.info->info21.rid, q.out.info->info21.account_name);
3456 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3457 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3459 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3460 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3461 q.out.info->info21.account_name.string);
3464 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3465 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3466 q.out.info->info21.account_name.string,
3467 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3468 q.out.info->info21.acct_flags);
3475 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3482 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3483 struct policy_handle *handle)
3486 struct samr_QueryDisplayInfo r;
3487 struct samr_QueryDomainInfo dom_info;
3489 uint16_t levels[] = {1, 2, 3, 4, 5};
3491 bool seen_testuser = false;
3493 for (i=0;i<ARRAY_SIZE(levels);i++) {
3494 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3497 status = STATUS_MORE_ENTRIES;
3498 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3499 r.in.domain_handle = handle;
3500 r.in.level = levels[i];
3501 r.in.max_entries = 2;
3502 r.in.buf_size = (uint32_t)-1;
3504 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3505 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3506 printf("QueryDisplayInfo level %u failed - %s\n",
3507 levels[i], nt_errstr(status));
3510 switch (r.in.level) {
3512 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3515 r.in.start_idx += r.out.info.info1.count;
3518 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3521 r.in.start_idx += r.out.info.info2.count;
3524 r.in.start_idx += r.out.info.info3.count;
3527 r.in.start_idx += r.out.info.info4.count;
3530 r.in.start_idx += r.out.info.info5.count;
3534 dom_info.in.domain_handle = handle;
3535 dom_info.in.level = 2;
3536 /* Check number of users returned is correct */
3537 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3538 if (!NT_STATUS_IS_OK(status)) {
3539 printf("QueryDomainInfo level %u failed - %s\n",
3540 r.in.level, nt_errstr(status));
3544 switch (r.in.level) {
3547 if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3548 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3549 r.in.start_idx, dom_info.out.info->info2.num_groups,
3550 dom_info.out.info->info2.domain_name.string);
3553 if (!seen_testuser) {
3554 struct policy_handle user_handle;
3555 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3556 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3557 dom_info.out.info->info2.domain_name.string);
3559 test_samr_handle_Close(p, mem_ctx, &user_handle);
3565 if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3566 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3567 r.in.start_idx, dom_info.out.info->info2.num_groups,
3568 dom_info.out.info->info2.domain_name.string);
3580 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3581 struct policy_handle *handle)
3584 struct samr_QueryDisplayInfo2 r;
3586 uint16_t levels[] = {1, 2, 3, 4, 5};
3589 for (i=0;i<ARRAY_SIZE(levels);i++) {
3590 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3592 r.in.domain_handle = handle;
3593 r.in.level = levels[i];
3595 r.in.max_entries = 1000;
3596 r.in.buf_size = (uint32_t)-1;
3598 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3599 if (!NT_STATUS_IS_OK(status)) {
3600 printf("QueryDisplayInfo2 level %u failed - %s\n",
3601 levels[i], nt_errstr(status));
3609 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3610 struct policy_handle *handle)
3613 struct samr_QueryDisplayInfo3 r;
3615 uint16_t levels[] = {1, 2, 3, 4, 5};
3618 for (i=0;i<ARRAY_SIZE(levels);i++) {
3619 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3621 r.in.domain_handle = handle;
3622 r.in.level = levels[i];
3624 r.in.max_entries = 1000;
3625 r.in.buf_size = (uint32_t)-1;
3627 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3628 if (!NT_STATUS_IS_OK(status)) {
3629 printf("QueryDisplayInfo3 level %u failed - %s\n",
3630 levels[i], nt_errstr(status));
3639 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3640 struct policy_handle *handle)
3643 struct samr_QueryDisplayInfo r;
3646 printf("Testing QueryDisplayInfo continuation\n");
3648 r.in.domain_handle = handle;
3651 r.in.max_entries = 1;
3652 r.in.buf_size = (uint32_t)-1;
3655 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3656 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3657 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3658 printf("expected idx %d but got %d\n",
3660 r.out.info.info1.entries[0].idx);
3664 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3665 !NT_STATUS_IS_OK(status)) {
3666 printf("QueryDisplayInfo level %u failed - %s\n",
3667 r.in.level, nt_errstr(status));
3672 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3673 NT_STATUS_IS_OK(status)) &&
3674 r.out.returned_size != 0);
3679 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3680 struct policy_handle *handle)
3683 struct samr_QueryDomainInfo r;
3684 struct samr_SetDomainInfo s;
3685 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3686 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3689 const char *domain_comment = talloc_asprintf(mem_ctx,
3690 "Tortured by Samba4 RPC-SAMR: %s",
3691 timestring(mem_ctx, time(NULL)));
3693 s.in.domain_handle = handle;
3695 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3697 s.in.info->info4.comment.string = domain_comment;
3698 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3699 if (!NT_STATUS_IS_OK(status)) {
3700 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3701 r.in.level, nt_errstr(status));
3705 for (i=0;i<ARRAY_SIZE(levels);i++) {
3706 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3708 r.in.domain_handle = handle;
3709 r.in.level = levels[i];
3711 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3712 if (!NT_STATUS_IS_OK(status)) {
3713 printf("QueryDomainInfo level %u failed - %s\n",
3714 r.in.level, nt_errstr(status));
3719 switch (levels[i]) {
3721 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3722 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3723 levels[i], r.out.info->info2.comment.string, domain_comment);
3726 if (!r.out.info->info2.primary.string) {
3727 printf("QueryDomainInfo level %u returned no PDC name\n",
3730 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3731 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3732 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3733 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3738 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3739 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3740 levels[i], r.out.info->info4.comment.string, domain_comment);
3745 if (!r.out.info->info6.primary.string) {
3746 printf("QueryDomainInfo level %u returned no PDC name\n",
3752 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3753 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3754 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3760 printf("Testing SetDomainInfo level %u\n", levels[i]);
3762 s.in.domain_handle = handle;
3763 s.in.level = levels[i];
3764 s.in.info = r.out.info;
3766 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3768 if (!NT_STATUS_IS_OK(status)) {
3769 printf("SetDomainInfo level %u failed - %s\n",
3770 r.in.level, nt_errstr(status));
3775 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3776 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3777 r.in.level, nt_errstr(status));
3783 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3784 if (!NT_STATUS_IS_OK(status)) {
3785 printf("QueryDomainInfo level %u failed - %s\n",
3786 r.in.level, nt_errstr(status));
3796 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3797 struct policy_handle *handle)
3800 struct samr_QueryDomainInfo2 r;
3801 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3805 for (i=0;i<ARRAY_SIZE(levels);i++) {
3806 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3808 r.in.domain_handle = handle;
3809 r.in.level = levels[i];
3811 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3812 if (!NT_STATUS_IS_OK(status)) {
3813 printf("QueryDomainInfo2 level %u failed - %s\n",
3814 r.in.level, nt_errstr(status));
3823 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3824 set of group names. */
3825 static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3826 struct policy_handle *handle)
3828 struct samr_EnumDomainGroups q1;
3829 struct samr_QueryDisplayInfo q2;
3831 uint32_t resume_handle=0;
3836 const char **names = NULL;
3838 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3840 q1.in.domain_handle = handle;
3841 q1.in.resume_handle = &resume_handle;
3843 q1.out.resume_handle = &resume_handle;
3845 status = STATUS_MORE_ENTRIES;
3846 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3847 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3849 if (!NT_STATUS_IS_OK(status) &&
3850 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3853 for (i=0; i<q1.out.num_entries; i++) {
3854 add_string_to_array(mem_ctx,
3855 q1.out.sam->entries[i].name.string,
3856 &names, &num_names);
3860 if (!NT_STATUS_IS_OK(status)) {
3861 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3869 q2.in.domain_handle = handle;
3871 q2.in.start_idx = 0;
3872 q2.in.max_entries = 5;
3873 q2.in.buf_size = (uint32_t)-1;
3875 status = STATUS_MORE_ENTRIES;
3876 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3877 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3879 if (!NT_STATUS_IS_OK(status) &&
3880 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3883 for (i=0; i<q2.out.info.info5.count; i++) {
3885 const char *name = q2.out.info.info5.entries[i].account_name.string;
3887 for (j=0; j<num_names; j++) {
3888 if (names[j] == NULL)
3890 /* Hmm. No strequal in samba4 */
3891 if (strequal(names[j], name)) {
3899 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3904 q2.in.start_idx += q2.out.info.info5.count;
3907 if (!NT_STATUS_IS_OK(status)) {
3908 printf("QueryDisplayInfo level 5 failed - %s\n",
3913 for (i=0; i<num_names; i++) {
3914 if (names[i] != NULL) {
3915 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3924 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3925 struct policy_handle *group_handle)
3927 struct samr_DeleteDomainGroup d;
3931 printf("Testing DeleteDomainGroup\n");
3933 d.in.group_handle = group_handle;
3934 d.out.group_handle = group_handle;
3936 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3937 if (!NT_STATUS_IS_OK(status)) {
3938 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3945 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3946 struct policy_handle *domain_handle)
3948 struct samr_TestPrivateFunctionsDomain r;
3952 printf("Testing TestPrivateFunctionsDomain\n");
3954 r.in.domain_handle = domain_handle;
3956 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3957 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3958 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3965 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3966 struct dom_sid *domain_sid,
3967 struct policy_handle *domain_handle)
3969 struct samr_RidToSid r;
3972 struct dom_sid *calc_sid;
3973 int rids[] = { 0, 42, 512, 10200 };
3976 for (i=0;i<ARRAY_SIZE(rids);i++) {
3978 printf("Testing RidToSid\n");
3980 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
3981 r.in.domain_handle = domain_handle;
3984 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
3985 if (!NT_STATUS_IS_OK(status)) {
3986 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
3989 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
3991 if (!dom_sid_equal(calc_sid, r.out.sid)) {
3992 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
3993 dom_sid_string(mem_ctx, r.out.sid),
3994 dom_sid_string(mem_ctx, calc_sid));
4003 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4004 struct policy_handle *domain_handle)
4006 struct samr_GetBootKeyInformation r;
4010 printf("Testing GetBootKeyInformation\n");
4012 r.in.domain_handle = domain_handle;
4014 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4015 if (!NT_STATUS_IS_OK(status)) {
4016 /* w2k3 seems to fail this sometimes and pass it sometimes */
4017 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4023 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4024 struct policy_handle *domain_handle,
4025 struct policy_handle *group_handle)
4028 struct samr_AddGroupMember r;
4029 struct samr_DeleteGroupMember d;
4030 struct samr_QueryGroupMember q;
4031 struct samr_SetMemberAttributesOfGroup s;
4035 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4036 if (!NT_STATUS_IS_OK(status)) {
4037 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4041 r.in.group_handle = group_handle;
4043 r.in.flags = 0; /* ??? */
4045 printf("Testing AddGroupMember and DeleteGroupMember\n");
4047 d.in.group_handle = group_handle;
4050 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4051 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4052 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4057 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4058 if (!NT_STATUS_IS_OK(status)) {
4059 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4063 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4064 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4065 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4070 if (torture_setting_bool(tctx, "samba4", false)) {
4071 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4073 /* this one is quite strange. I am using random inputs in the
4074 hope of triggering an error that might give us a clue */
4076 s.in.group_handle = group_handle;
4077 s.in.unknown1 = random();
4078 s.in.unknown2 = random();
4080 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4081 if (!NT_STATUS_IS_OK(status)) {
4082 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4087 q.in.group_handle = group_handle;
4089 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4090 if (!NT_STATUS_IS_OK(status)) {
4091 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4095 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4096 if (!NT_STATUS_IS_OK(status)) {
4097 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4101 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4102 if (!NT_STATUS_IS_OK(status)) {
4103 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4111 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4112 struct policy_handle *domain_handle, struct policy_handle *group_handle)
4115 struct samr_CreateDomainGroup r;
4117 struct lsa_String name;
4120 init_lsa_String(&name, TEST_GROUPNAME);
4122 r.in.domain_handle = domain_handle;
4124 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4125 r.out.group_handle = group_handle;
4128 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4130 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4132 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4133 printf("Server refused create of '%s'\n", r.in.name->string);
4134 ZERO_STRUCTP(group_handle);
4138 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4139 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4141 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4145 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4147 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4148 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4150 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4154 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4156 if (!NT_STATUS_IS_OK(status)) {
4157 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4161 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4162 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4166 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4175 its not totally clear what this does. It seems to accept any sid you like.
4177 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4178 TALLOC_CTX *mem_ctx,
4179 struct policy_handle *domain_handle)
4182 struct samr_RemoveMemberFromForeignDomain r;
4184 r.in.domain_handle = domain_handle;
4185 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4187 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4188 if (!NT_STATUS_IS_OK(status)) {
4189 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4198 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4199 struct policy_handle *handle);
4201 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4202 struct policy_handle *handle, struct dom_sid *sid,
4203 enum torture_samr_choice which_ops)
4206 struct samr_OpenDomain r;
4207 struct policy_handle domain_handle;
4208 struct policy_handle alias_handle;
4209 struct policy_handle user_handle;
4210 struct policy_handle group_handle;
4213 ZERO_STRUCT(alias_handle);
4214 ZERO_STRUCT(user_handle);
4215 ZERO_STRUCT(group_handle);
4216 ZERO_STRUCT(domain_handle);
4218 printf("Testing OpenDomain\n");
4220 r.in.connect_handle = handle;
4221 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4223 r.out.domain_handle = &domain_handle;
4225 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4226 if (!NT_STATUS_IS_OK(status)) {
4227 printf("OpenDomain failed - %s\n", nt_errstr(status));
4231 /* run the domain tests with the main handle closed - this tests
4232 the servers reference counting */
4233 ret &= test_samr_handle_Close(p, tctx, handle);
4235 switch (which_ops) {
4236 case TORTURE_SAMR_USER_ATTRIBUTES:
4237 case TORTURE_SAMR_PASSWORDS:
4238 ret &= test_CreateUser2(p, tctx, &domain_handle, which_ops);
4239 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
4240 /* This test needs 'complex' users to validate */
4241 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4243 case TORTURE_SAMR_OTHER:
4244 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
4245 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4246 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4247 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4248 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle);
4249 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4250 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4251 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4252 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4253 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4254 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4255 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4256 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4257 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4259 if (torture_setting_bool(tctx, "samba4", false)) {
4260 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4262 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4263 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4265 ret &= test_GroupList(p, tctx, &domain_handle);
4266 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4267 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4268 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4272 if (!policy_handle_empty(&user_handle) &&
4273 !test_DeleteUser(p, tctx, &user_handle)) {
4277 if (!policy_handle_empty(&alias_handle) &&
4278 !test_DeleteAlias(p, tctx, &alias_handle)) {
4282 if (!policy_handle_empty(&group_handle) &&
4283 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4287 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4289 /* reconnect the main handle */
4290 ret &= test_Connect(p, tctx, handle);
4293 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4299 static bool test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4300 struct policy_handle *handle, const char *domain,
4301 enum torture_samr_choice which_ops)
4304 struct samr_LookupDomain r;
4305 struct lsa_String n1;
4306 struct lsa_String n2;
4309 printf("Testing LookupDomain(%s)\n", domain);
4311 /* check for correct error codes */
4312 r.in.connect_handle = handle;
4313 r.in.domain_name = &n2;
4316 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4317 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4318 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4322 init_lsa_String(&n2, "xxNODOMAINxx");
4324 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4325 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4326 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4330 r.in.connect_handle = handle;
4332 init_lsa_String(&n1, domain);
4333 r.in.domain_name = &n1;
4335 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
4336 if (!NT_STATUS_IS_OK(status)) {
4337 printf("LookupDomain failed - %s\n", nt_errstr(status));
4341 if (!test_GetDomPwInfo(p, mem_ctx, &n1)) {
4345 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid, which_ops)) {
4353 static bool test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4354 struct policy_handle *handle, enum torture_samr_choice which_ops)
4357 struct samr_EnumDomains r;
4358 uint32_t resume_handle = 0;
4362 r.in.connect_handle = handle;
4363 r.in.resume_handle = &resume_handle;
4364 r.in.buf_size = (uint32_t)-1;
4365 r.out.resume_handle = &resume_handle;
4367 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4368 if (!NT_STATUS_IS_OK(status)) {
4369 printf("EnumDomains failed - %s\n", nt_errstr(status));
4377 for (i=0;i<r.out.sam->count;i++) {
4378 if (!test_LookupDomain(p, mem_ctx, handle,
4379 r.out.sam->entries[i].name.string, which_ops)) {
4384 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
4385 if (!NT_STATUS_IS_OK(status)) {
4386 printf("EnumDomains failed - %s\n", nt_errstr(status));
4394 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4395 struct policy_handle *handle)
4398 struct samr_Connect r;
4399 struct samr_Connect2 r2;
4400 struct samr_Connect3 r3;
4401 struct samr_Connect4 r4;
4402 struct samr_Connect5 r5;
4403 union samr_ConnectInfo info;
4404 struct policy_handle h;
4405 bool ret = true, got_handle = false;
4407 printf("testing samr_Connect\n");
4409 r.in.system_name = 0;
4410 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4411 r.out.connect_handle = &h;
4413 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4414 if (!NT_STATUS_IS_OK(status)) {
4415 printf("Connect failed - %s\n", nt_errstr(status));
4422 printf("testing samr_Connect2\n");
4424 r2.in.system_name = NULL;
4425 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4426 r2.out.connect_handle = &h;
4428 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4429 if (!NT_STATUS_IS_OK(status)) {
4430 printf("Connect2 failed - %s\n", nt_errstr(status));
4434 test_samr_handle_Close(p, mem_ctx, handle);
4440 printf("testing samr_Connect3\n");
4442 r3.in.system_name = NULL;
4444 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4445 r3.out.connect_handle = &h;
4447 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4448 if (!NT_STATUS_IS_OK(status)) {
4449 printf("Connect3 failed - %s\n", nt_errstr(status));
4453 test_samr_handle_Close(p, mem_ctx, handle);
4459 printf("testing samr_Connect4\n");
4461 r4.in.system_name = "";
4463 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4464 r4.out.connect_handle = &h;
4466 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4467 if (!NT_STATUS_IS_OK(status)) {
4468 printf("Connect4 failed - %s\n", nt_errstr(status));
4472 test_samr_handle_Close(p, mem_ctx, handle);
4478 printf("testing samr_Connect5\n");
4480 info.info1.unknown1 = 0;
4481 info.info1.unknown2 = 0;
4483 r5.in.system_name = "";
4484 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4487 r5.out.info = &info;
4488 r5.out.connect_handle = &h;
4490 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4491 if (!NT_STATUS_IS_OK(status)) {
4492 printf("Connect5 failed - %s\n", nt_errstr(status));
4496 test_samr_handle_Close(p, mem_ctx, handle);
4506 bool torture_rpc_samr(struct torture_context *torture)
4509 struct dcerpc_pipe *p;
4511 struct policy_handle handle;
4513 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4514 if (!NT_STATUS_IS_OK(status)) {
4518 ret &= test_Connect(p, torture, &handle);
4520 ret &= test_QuerySecurity(p, torture, &handle);
4522 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4524 ret &= test_SetDsrmPassword(p, torture, &handle);
4526 ret &= test_Shutdown(p, torture, &handle);
4528 ret &= test_samr_handle_Close(p, torture, &handle);
4534 bool torture_rpc_samr_users(struct torture_context *torture)
4537 struct dcerpc_pipe *p;
4539 struct policy_handle handle;
4541 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4542 if (!NT_STATUS_IS_OK(status)) {
4546 ret &= test_Connect(p, torture, &handle);
4548 ret &= test_QuerySecurity(p, torture, &handle);
4550 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4552 ret &= test_SetDsrmPassword(p, torture, &handle);
4554 ret &= test_Shutdown(p, torture, &handle);
4556 ret &= test_samr_handle_Close(p, torture, &handle);
4562 bool torture_rpc_samr_passwords(struct torture_context *torture)
4565 struct dcerpc_pipe *p;
4567 struct policy_handle handle;
4569 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4570 if (!NT_STATUS_IS_OK(status)) {
4574 ret &= test_Connect(p, torture, &handle);
4576 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4578 ret &= test_samr_handle_Close(p, torture, &handle);