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"
34 #define TEST_ACCOUNT_NAME "samrtorturetest"
35 #define TEST_ALIASNAME "samrtorturetestalias"
36 #define TEST_GROUPNAME "samrtorturetestgroup"
37 #define TEST_MACHINENAME "samrtestmach$"
38 #define TEST_DOMAINNAME "samrtestdom$"
40 enum torture_samr_choice {
41 TORTURE_SAMR_PASSWORDS,
42 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
43 TORTURE_SAMR_USER_ATTRIBUTES,
47 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51 struct policy_handle *handle);
53 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
54 struct policy_handle *handle);
56 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
57 const char *acct_name,
58 struct policy_handle *domain_handle, char **password);
60 static void init_lsa_String(struct lsa_String *string, const char *s)
65 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
67 string->length = length;
68 string->size = length;
69 string->array = (uint16_t *)discard_const(s);
72 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
73 struct policy_handle *handle)
79 r.out.handle = handle;
81 status = dcerpc_samr_Close(p, tctx, &r);
82 torture_assert_ntstatus_ok(tctx, status, "Close");
87 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
88 struct policy_handle *handle)
91 struct samr_Shutdown r;
93 if (!torture_setting_bool(tctx, "dangerous", false)) {
94 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
98 r.in.connect_handle = handle;
100 torture_comment(tctx, "testing samr_Shutdown\n");
102 status = dcerpc_samr_Shutdown(p, tctx, &r);
103 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
108 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
109 struct policy_handle *handle)
112 struct samr_SetDsrmPassword r;
113 struct lsa_String string;
114 struct samr_Password hash;
116 if (!torture_setting_bool(tctx, "dangerous", false)) {
117 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
120 E_md4hash("TeSTDSRM123", hash.hash);
122 init_lsa_String(&string, "Administrator");
128 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
130 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
131 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
137 static bool test_QuerySecurity(struct dcerpc_pipe *p,
138 struct torture_context *tctx,
139 struct policy_handle *handle)
142 struct samr_QuerySecurity r;
143 struct samr_SetSecurity s;
144 struct sec_desc_buf *sdbuf = NULL;
146 r.in.handle = handle;
148 r.out.sdbuf = &sdbuf;
150 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
151 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
153 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
155 s.in.handle = handle;
159 if (torture_setting_bool(tctx, "samba4", false)) {
160 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
163 status = dcerpc_samr_SetSecurity(p, tctx, &s);
164 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
166 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
167 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
173 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
174 struct policy_handle *handle, uint32_t base_acct_flags,
175 const char *base_account_name)
178 struct samr_SetUserInfo s;
179 struct samr_SetUserInfo2 s2;
180 struct samr_QueryUserInfo q;
181 struct samr_QueryUserInfo q0;
182 union samr_UserInfo u;
183 union samr_UserInfo *info;
185 const char *test_account_name;
187 uint32_t user_extra_flags = 0;
188 if (base_acct_flags == ACB_NORMAL) {
189 /* When created, accounts are expired by default */
190 user_extra_flags = ACB_PW_EXPIRED;
193 s.in.user_handle = handle;
196 s2.in.user_handle = handle;
199 q.in.user_handle = handle;
203 #define TESTCALL(call, r) \
204 status = dcerpc_samr_ ##call(p, tctx, &r); \
205 if (!NT_STATUS_IS_OK(status)) { \
206 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
207 r.in.level, nt_errstr(status), __location__); \
212 #define STRING_EQUAL(s1, s2, field) \
213 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
214 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
215 #field, s2, __location__); \
220 #define MEM_EQUAL(s1, s2, length, field) \
221 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
222 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
223 #field, (const char *)s2, __location__); \
228 #define INT_EQUAL(i1, i2, field) \
230 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
231 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
236 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
237 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
239 TESTCALL(QueryUserInfo, q) \
241 s2.in.level = lvl1; \
244 ZERO_STRUCT(u.info21); \
245 u.info21.fields_present = fpval; \
247 init_lsa_String(&u.info ## lvl1.field1, value); \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 init_lsa_String(&u.info ## lvl1.field1, ""); \
251 TESTCALL(QueryUserInfo, q); \
253 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
255 TESTCALL(QueryUserInfo, q) \
257 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
261 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
263 TESTCALL(QueryUserInfo, q) \
265 s2.in.level = lvl1; \
268 ZERO_STRUCT(u.info21); \
269 u.info21.fields_present = fpval; \
271 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
272 TESTCALL(SetUserInfo, s) \
273 TESTCALL(SetUserInfo2, s2) \
274 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
275 TESTCALL(QueryUserInfo, q); \
277 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
279 TESTCALL(QueryUserInfo, q) \
281 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
284 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
285 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
287 TESTCALL(QueryUserInfo, q) \
289 s2.in.level = lvl1; \
292 uint8_t *bits = u.info21.logon_hours.bits; \
293 ZERO_STRUCT(u.info21); \
294 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
295 u.info21.logon_hours.units_per_week = 168; \
296 u.info21.logon_hours.bits = bits; \
298 u.info21.fields_present = fpval; \
300 u.info ## lvl1.field1 = value; \
301 TESTCALL(SetUserInfo, s) \
302 TESTCALL(SetUserInfo2, s2) \
303 u.info ## lvl1.field1 = 0; \
304 TESTCALL(QueryUserInfo, q); \
306 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
308 TESTCALL(QueryUserInfo, q) \
310 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
313 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
314 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
318 do { TESTCALL(QueryUserInfo, q0) } while (0);
320 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
321 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
322 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
325 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
326 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
327 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
328 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
329 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
330 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
331 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
332 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
333 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
334 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
335 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
336 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
337 test_account_name = base_account_name;
338 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
339 SAMR_FIELD_ACCOUNT_NAME);
341 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
342 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
343 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
344 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
345 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
346 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
347 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
348 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
349 SAMR_FIELD_FULL_NAME);
351 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
352 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
353 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
354 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
355 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
356 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
357 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
358 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
359 SAMR_FIELD_FULL_NAME);
361 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
362 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
363 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
364 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
365 SAMR_FIELD_LOGON_SCRIPT);
367 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
368 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
369 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
370 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
371 SAMR_FIELD_PROFILE_PATH);
373 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
374 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
375 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
376 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
377 SAMR_FIELD_HOME_DIRECTORY);
378 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
379 SAMR_FIELD_HOME_DIRECTORY);
381 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
382 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
383 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
384 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
385 SAMR_FIELD_HOME_DRIVE);
386 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
387 SAMR_FIELD_HOME_DRIVE);
389 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
390 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
391 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
392 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
393 SAMR_FIELD_DESCRIPTION);
395 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
396 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
397 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
398 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
399 SAMR_FIELD_WORKSTATIONS);
400 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
401 SAMR_FIELD_WORKSTATIONS);
402 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
403 SAMR_FIELD_WORKSTATIONS);
404 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
405 SAMR_FIELD_WORKSTATIONS);
407 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
408 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
409 SAMR_FIELD_PARAMETERS);
410 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
411 SAMR_FIELD_PARAMETERS);
413 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
414 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
415 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
416 SAMR_FIELD_COUNTRY_CODE);
417 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
418 SAMR_FIELD_COUNTRY_CODE);
420 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
421 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
422 SAMR_FIELD_CODE_PAGE);
423 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
424 SAMR_FIELD_CODE_PAGE);
426 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
427 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
428 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
429 SAMR_FIELD_ACCT_EXPIRY);
430 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
431 SAMR_FIELD_ACCT_EXPIRY);
432 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
433 SAMR_FIELD_ACCT_EXPIRY);
435 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
436 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
437 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
438 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
439 SAMR_FIELD_LOGON_HOURS);
441 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
442 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
443 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
445 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
446 (base_acct_flags | ACB_DISABLED),
447 (base_acct_flags | ACB_DISABLED | user_extra_flags),
450 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
451 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
452 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
453 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
455 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
456 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
457 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
461 /* The 'autolock' flag doesn't stick - check this */
462 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
463 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
464 (base_acct_flags | ACB_DISABLED | user_extra_flags),
467 /* Removing the 'disabled' flag doesn't stick - check this */
468 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
470 (base_acct_flags | ACB_DISABLED | user_extra_flags),
473 /* The 'store plaintext' flag does stick */
474 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
475 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
476 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
478 /* The 'use DES' flag does stick */
479 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
480 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
481 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
483 /* The 'don't require kerberos pre-authentication flag does stick */
484 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
485 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
486 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
488 /* The 'no kerberos PAC required' flag sticks */
489 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
490 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
491 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
494 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
495 (base_acct_flags | ACB_DISABLED),
496 (base_acct_flags | ACB_DISABLED | user_extra_flags),
497 SAMR_FIELD_ACCT_FLAGS);
500 /* these fail with win2003 - it appears you can't set the primary gid?
501 the set succeeds, but the gid isn't changed. Very weird! */
502 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
503 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
504 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
505 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
512 generate a random password for password change tests
514 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
516 size_t len = MAX(8, min_len) + (random() % 6);
517 char *s = generate_random_str(mem_ctx, len);
521 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
523 char *s = samr_rand_pass_silent(mem_ctx, min_len);
524 printf("Generated password '%s'\n", s);
530 generate a random password for password change tests
532 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
535 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
536 generate_random_buffer(password.data, password.length);
538 for (i=0; i < len; i++) {
539 if (((uint16_t *)password.data)[i] == 0) {
540 ((uint16_t *)password.data)[i] = 1;
548 generate a random password for password change tests (fixed length)
550 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
552 char *s = generate_random_str(mem_ctx, len);
553 printf("Generated password '%s'\n", s);
557 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
558 struct policy_handle *handle, char **password)
561 struct samr_SetUserInfo s;
562 union samr_UserInfo u;
564 DATA_BLOB session_key;
566 struct samr_GetUserPwInfo pwp;
567 struct samr_PwInfo info;
568 int policy_min_pw_len = 0;
569 pwp.in.user_handle = handle;
570 pwp.out.info = &info;
572 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
573 if (NT_STATUS_IS_OK(status)) {
574 policy_min_pw_len = pwp.out.info->min_password_length;
576 newpass = samr_rand_pass(tctx, policy_min_pw_len);
578 s.in.user_handle = handle;
582 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
583 u.info24.password_expired = 0;
585 status = dcerpc_fetch_session_key(p, &session_key);
586 if (!NT_STATUS_IS_OK(status)) {
587 printf("SetUserInfo level %u - no session key - %s\n",
588 s.in.level, nt_errstr(status));
592 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
594 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
596 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
597 if (!NT_STATUS_IS_OK(status)) {
598 printf("SetUserInfo level %u failed - %s\n",
599 s.in.level, nt_errstr(status));
609 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
610 struct policy_handle *handle, uint32_t fields_present,
614 struct samr_SetUserInfo s;
615 union samr_UserInfo u;
617 DATA_BLOB session_key;
619 struct samr_GetUserPwInfo pwp;
620 struct samr_PwInfo info;
621 int policy_min_pw_len = 0;
622 pwp.in.user_handle = handle;
623 pwp.out.info = &info;
625 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
626 if (NT_STATUS_IS_OK(status)) {
627 policy_min_pw_len = pwp.out.info->min_password_length;
629 newpass = samr_rand_pass(tctx, policy_min_pw_len);
631 s.in.user_handle = handle;
637 u.info23.info.fields_present = fields_present;
639 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
641 status = dcerpc_fetch_session_key(p, &session_key);
642 if (!NT_STATUS_IS_OK(status)) {
643 printf("SetUserInfo level %u - no session key - %s\n",
644 s.in.level, nt_errstr(status));
648 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
650 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
652 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
653 if (!NT_STATUS_IS_OK(status)) {
654 printf("SetUserInfo level %u failed - %s\n",
655 s.in.level, nt_errstr(status));
661 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
663 status = dcerpc_fetch_session_key(p, &session_key);
664 if (!NT_STATUS_IS_OK(status)) {
665 printf("SetUserInfo level %u - no session key - %s\n",
666 s.in.level, nt_errstr(status));
670 /* This should break the key nicely */
671 session_key.length--;
672 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
674 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
676 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
677 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
678 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
679 s.in.level, nt_errstr(status));
687 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
688 struct policy_handle *handle, bool makeshort,
692 struct samr_SetUserInfo s;
693 union samr_UserInfo u;
695 DATA_BLOB session_key;
696 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
697 uint8_t confounder[16];
699 struct MD5Context ctx;
700 struct samr_GetUserPwInfo pwp;
701 struct samr_PwInfo info;
702 int policy_min_pw_len = 0;
703 pwp.in.user_handle = handle;
704 pwp.out.info = &info;
706 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
707 if (NT_STATUS_IS_OK(status)) {
708 policy_min_pw_len = pwp.out.info->min_password_length;
710 if (makeshort && policy_min_pw_len) {
711 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
713 newpass = samr_rand_pass(tctx, policy_min_pw_len);
716 s.in.user_handle = handle;
720 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
721 u.info26.password_expired = 0;
723 status = dcerpc_fetch_session_key(p, &session_key);
724 if (!NT_STATUS_IS_OK(status)) {
725 printf("SetUserInfo level %u - no session key - %s\n",
726 s.in.level, nt_errstr(status));
730 generate_random_buffer((uint8_t *)confounder, 16);
733 MD5Update(&ctx, confounder, 16);
734 MD5Update(&ctx, session_key.data, session_key.length);
735 MD5Final(confounded_session_key.data, &ctx);
737 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
738 memcpy(&u.info26.password.data[516], confounder, 16);
740 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
742 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
743 if (!NT_STATUS_IS_OK(status)) {
744 printf("SetUserInfo level %u failed - %s\n",
745 s.in.level, nt_errstr(status));
751 /* This should break the key nicely */
752 confounded_session_key.data[0]++;
754 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
755 memcpy(&u.info26.password.data[516], confounder, 16);
757 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
759 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
760 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
761 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
762 s.in.level, nt_errstr(status));
771 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
772 struct policy_handle *handle, uint32_t fields_present,
776 struct samr_SetUserInfo s;
777 union samr_UserInfo u;
779 DATA_BLOB session_key;
780 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
781 struct MD5Context ctx;
782 uint8_t confounder[16];
784 struct samr_GetUserPwInfo pwp;
785 struct samr_PwInfo info;
786 int policy_min_pw_len = 0;
787 pwp.in.user_handle = handle;
788 pwp.out.info = &info;
790 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
791 if (NT_STATUS_IS_OK(status)) {
792 policy_min_pw_len = pwp.out.info->min_password_length;
794 newpass = samr_rand_pass(tctx, policy_min_pw_len);
796 s.in.user_handle = handle;
802 u.info25.info.fields_present = fields_present;
804 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
806 status = dcerpc_fetch_session_key(p, &session_key);
807 if (!NT_STATUS_IS_OK(status)) {
808 printf("SetUserInfo level %u - no session key - %s\n",
809 s.in.level, nt_errstr(status));
813 generate_random_buffer((uint8_t *)confounder, 16);
816 MD5Update(&ctx, confounder, 16);
817 MD5Update(&ctx, session_key.data, session_key.length);
818 MD5Final(confounded_session_key.data, &ctx);
820 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
821 memcpy(&u.info25.password.data[516], confounder, 16);
823 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
825 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
826 if (!NT_STATUS_IS_OK(status)) {
827 printf("SetUserInfo level %u failed - %s\n",
828 s.in.level, nt_errstr(status));
834 /* This should break the key nicely */
835 confounded_session_key.data[0]++;
837 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
838 memcpy(&u.info25.password.data[516], confounder, 16);
840 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
842 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
843 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
844 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
845 s.in.level, nt_errstr(status));
852 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
853 struct policy_handle *handle, char **password)
856 struct samr_SetUserInfo s;
857 union samr_UserInfo u;
859 DATA_BLOB session_key;
861 struct samr_GetUserPwInfo pwp;
862 struct samr_PwInfo info;
863 int policy_min_pw_len = 0;
864 uint8_t lm_hash[16], nt_hash[16];
866 pwp.in.user_handle = handle;
867 pwp.out.info = &info;
869 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
870 if (NT_STATUS_IS_OK(status)) {
871 policy_min_pw_len = pwp.out.info->min_password_length;
873 newpass = samr_rand_pass(tctx, policy_min_pw_len);
875 s.in.user_handle = handle;
881 u.info18.nt_pwd_active = true;
882 u.info18.lm_pwd_active = true;
884 E_md4hash(newpass, nt_hash);
885 E_deshash(newpass, lm_hash);
887 status = dcerpc_fetch_session_key(p, &session_key);
888 if (!NT_STATUS_IS_OK(status)) {
889 printf("SetUserInfo level %u - no session key - %s\n",
890 s.in.level, nt_errstr(status));
896 in = data_blob_const(nt_hash, 16);
897 out = data_blob_talloc_zero(tctx, 16);
898 sess_crypt_blob(&out, &in, &session_key, true);
899 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
903 in = data_blob_const(lm_hash, 16);
904 out = data_blob_talloc_zero(tctx, 16);
905 sess_crypt_blob(&out, &in, &session_key, true);
906 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
909 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
911 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
912 if (!NT_STATUS_IS_OK(status)) {
913 printf("SetUserInfo level %u failed - %s\n",
914 s.in.level, nt_errstr(status));
923 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
924 struct policy_handle *handle, uint32_t fields_present,
928 struct samr_SetUserInfo s;
929 union samr_UserInfo u;
931 DATA_BLOB session_key;
933 struct samr_GetUserPwInfo pwp;
934 struct samr_PwInfo info;
935 int policy_min_pw_len = 0;
936 uint8_t lm_hash[16], nt_hash[16];
938 pwp.in.user_handle = handle;
939 pwp.out.info = &info;
941 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
942 if (NT_STATUS_IS_OK(status)) {
943 policy_min_pw_len = pwp.out.info->min_password_length;
945 newpass = samr_rand_pass(tctx, policy_min_pw_len);
947 s.in.user_handle = handle;
951 E_md4hash(newpass, nt_hash);
952 E_deshash(newpass, lm_hash);
956 u.info21.fields_present = fields_present;
958 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
959 u.info21.lm_owf_password.length = 16;
960 u.info21.lm_owf_password.size = 16;
961 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
962 u.info21.lm_password_set = true;
965 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
966 u.info21.nt_owf_password.length = 16;
967 u.info21.nt_owf_password.size = 16;
968 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
969 u.info21.nt_password_set = true;
972 status = dcerpc_fetch_session_key(p, &session_key);
973 if (!NT_STATUS_IS_OK(status)) {
974 printf("SetUserInfo level %u - no session key - %s\n",
975 s.in.level, nt_errstr(status));
979 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
981 in = data_blob_const(u.info21.lm_owf_password.array,
982 u.info21.lm_owf_password.length);
983 out = data_blob_talloc_zero(tctx, 16);
984 sess_crypt_blob(&out, &in, &session_key, true);
985 u.info21.lm_owf_password.array = (uint16_t *)out.data;
988 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
990 in = data_blob_const(u.info21.nt_owf_password.array,
991 u.info21.nt_owf_password.length);
992 out = data_blob_talloc_zero(tctx, 16);
993 sess_crypt_blob(&out, &in, &session_key, true);
994 u.info21.nt_owf_password.array = (uint16_t *)out.data;
997 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
999 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 printf("SetUserInfo level %u failed - %s\n",
1002 s.in.level, nt_errstr(status));
1005 *password = newpass;
1008 /* try invalid length */
1009 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1011 u.info21.nt_owf_password.length++;
1013 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1015 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1016 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1017 s.in.level, nt_errstr(status));
1022 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1024 u.info21.lm_owf_password.length++;
1026 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1028 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1029 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1030 s.in.level, nt_errstr(status));
1038 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1039 struct torture_context *tctx,
1040 struct policy_handle *handle,
1042 uint32_t fields_present,
1043 char **password, uint8_t password_expired,
1045 bool *matched_expected_error)
1048 NTSTATUS expected_error = NT_STATUS_OK;
1049 struct samr_SetUserInfo s;
1050 struct samr_SetUserInfo2 s2;
1051 union samr_UserInfo u;
1053 DATA_BLOB session_key;
1054 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1055 struct MD5Context ctx;
1056 uint8_t confounder[16];
1058 struct samr_GetUserPwInfo pwp;
1059 struct samr_PwInfo info;
1060 int policy_min_pw_len = 0;
1061 const char *comment = NULL;
1062 uint8_t lm_hash[16], nt_hash[16];
1064 pwp.in.user_handle = handle;
1065 pwp.out.info = &info;
1067 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1068 if (NT_STATUS_IS_OK(status)) {
1069 policy_min_pw_len = pwp.out.info->min_password_length;
1071 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1074 s2.in.user_handle = handle;
1076 s2.in.level = level;
1078 s.in.user_handle = handle;
1083 if (fields_present & SAMR_FIELD_COMMENT) {
1084 comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
1091 E_md4hash(newpass, nt_hash);
1092 E_deshash(newpass, lm_hash);
1094 u.info18.nt_pwd_active = true;
1095 u.info18.lm_pwd_active = true;
1096 u.info18.password_expired = password_expired;
1098 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1099 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1103 E_md4hash(newpass, nt_hash);
1104 E_deshash(newpass, lm_hash);
1106 u.info21.fields_present = fields_present;
1107 u.info21.password_expired = password_expired;
1108 u.info21.comment.string = comment;
1110 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1111 u.info21.lm_owf_password.length = 16;
1112 u.info21.lm_owf_password.size = 16;
1113 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1114 u.info21.lm_password_set = true;
1117 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1118 u.info21.nt_owf_password.length = 16;
1119 u.info21.nt_owf_password.size = 16;
1120 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1121 u.info21.nt_password_set = true;
1126 u.info23.info.fields_present = fields_present;
1127 u.info23.info.password_expired = password_expired;
1128 u.info23.info.comment.string = comment;
1130 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1134 u.info24.password_expired = password_expired;
1136 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1140 u.info25.info.fields_present = fields_present;
1141 u.info25.info.password_expired = password_expired;
1142 u.info25.info.comment.string = comment;
1144 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1148 u.info26.password_expired = password_expired;
1150 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1155 status = dcerpc_fetch_session_key(p, &session_key);
1156 if (!NT_STATUS_IS_OK(status)) {
1157 printf("SetUserInfo level %u - no session key - %s\n",
1158 s.in.level, nt_errstr(status));
1162 generate_random_buffer((uint8_t *)confounder, 16);
1165 MD5Update(&ctx, confounder, 16);
1166 MD5Update(&ctx, session_key.data, session_key.length);
1167 MD5Final(confounded_session_key.data, &ctx);
1173 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1174 out = data_blob_talloc_zero(tctx, 16);
1175 sess_crypt_blob(&out, &in, &session_key, true);
1176 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1180 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1181 out = data_blob_talloc_zero(tctx, 16);
1182 sess_crypt_blob(&out, &in, &session_key, true);
1183 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1188 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1190 in = data_blob_const(u.info21.lm_owf_password.array,
1191 u.info21.lm_owf_password.length);
1192 out = data_blob_talloc_zero(tctx, 16);
1193 sess_crypt_blob(&out, &in, &session_key, true);
1194 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1196 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1198 in = data_blob_const(u.info21.nt_owf_password.array,
1199 u.info21.nt_owf_password.length);
1200 out = data_blob_talloc_zero(tctx, 16);
1201 sess_crypt_blob(&out, &in, &session_key, true);
1202 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1206 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1209 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1212 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1213 memcpy(&u.info25.password.data[516], confounder, 16);
1216 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1217 memcpy(&u.info26.password.data[516], confounder, 16);
1222 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1224 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1227 if (!NT_STATUS_IS_OK(status)) {
1228 if (fields_present == 0) {
1229 expected_error = NT_STATUS_INVALID_PARAMETER;
1231 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1232 expected_error = NT_STATUS_ACCESS_DENIED;
1236 if (!NT_STATUS_IS_OK(expected_error)) {
1238 torture_assert_ntstatus_equal(tctx,
1240 expected_error, "SetUserInfo2 failed");
1242 torture_assert_ntstatus_equal(tctx,
1244 expected_error, "SetUserInfo failed");
1246 *matched_expected_error = true;
1250 if (!NT_STATUS_IS_OK(status)) {
1251 printf("SetUserInfo%s level %u failed - %s\n",
1252 use_setinfo2 ? "2":"", level, nt_errstr(status));
1255 *password = newpass;
1261 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1262 struct policy_handle *handle)
1265 struct samr_SetAliasInfo r;
1266 struct samr_QueryAliasInfo q;
1267 union samr_AliasInfo *info;
1268 uint16_t levels[] = {2, 3};
1272 /* Ignoring switch level 1, as that includes the number of members for the alias
1273 * and setting this to a wrong value might have negative consequences
1276 for (i=0;i<ARRAY_SIZE(levels);i++) {
1277 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1279 r.in.alias_handle = handle;
1280 r.in.level = levels[i];
1281 r.in.info = talloc(tctx, union samr_AliasInfo);
1282 switch (r.in.level) {
1283 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1284 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1285 "Test Description, should test I18N as well"); break;
1286 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1289 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1290 if (!NT_STATUS_IS_OK(status)) {
1291 printf("SetAliasInfo level %u failed - %s\n",
1292 levels[i], nt_errstr(status));
1296 q.in.alias_handle = handle;
1297 q.in.level = levels[i];
1300 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1301 if (!NT_STATUS_IS_OK(status)) {
1302 printf("QueryAliasInfo level %u failed - %s\n",
1303 levels[i], nt_errstr(status));
1311 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1312 struct policy_handle *user_handle)
1314 struct samr_GetGroupsForUser r;
1315 struct samr_RidWithAttributeArray *rids = NULL;
1318 torture_comment(tctx, "testing GetGroupsForUser\n");
1320 r.in.user_handle = user_handle;
1323 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1324 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1330 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1331 struct lsa_String *domain_name)
1334 struct samr_GetDomPwInfo r;
1335 struct samr_PwInfo info;
1337 r.in.domain_name = domain_name;
1340 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1342 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1343 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1345 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1346 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1348 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1349 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1351 r.in.domain_name->string = "\\\\__NONAME__";
1352 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1354 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1355 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1357 r.in.domain_name->string = "\\\\Builtin";
1358 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1360 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1361 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1366 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1367 struct policy_handle *handle)
1370 struct samr_GetUserPwInfo r;
1371 struct samr_PwInfo info;
1373 torture_comment(tctx, "Testing GetUserPwInfo\n");
1375 r.in.user_handle = handle;
1378 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1379 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1384 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1385 struct policy_handle *domain_handle, const char *name,
1389 struct samr_LookupNames n;
1390 struct lsa_String sname[2];
1391 struct samr_Ids rids, types;
1393 init_lsa_String(&sname[0], name);
1395 n.in.domain_handle = domain_handle;
1399 n.out.types = &types;
1400 status = dcerpc_samr_LookupNames(p, tctx, &n);
1401 if (NT_STATUS_IS_OK(status)) {
1402 *rid = n.out.rids->ids[0];
1407 init_lsa_String(&sname[1], "xxNONAMExx");
1409 status = dcerpc_samr_LookupNames(p, tctx, &n);
1410 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1411 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1412 if (NT_STATUS_IS_OK(status)) {
1413 return NT_STATUS_UNSUCCESSFUL;
1419 status = dcerpc_samr_LookupNames(p, tctx, &n);
1420 if (!NT_STATUS_IS_OK(status)) {
1421 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1425 init_lsa_String(&sname[0], "xxNONAMExx");
1427 status = dcerpc_samr_LookupNames(p, tctx, &n);
1428 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1429 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1430 if (NT_STATUS_IS_OK(status)) {
1431 return NT_STATUS_UNSUCCESSFUL;
1436 init_lsa_String(&sname[0], "xxNONAMExx");
1437 init_lsa_String(&sname[1], "xxNONAME2xx");
1439 status = dcerpc_samr_LookupNames(p, tctx, &n);
1440 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1441 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1442 if (NT_STATUS_IS_OK(status)) {
1443 return NT_STATUS_UNSUCCESSFUL;
1448 return NT_STATUS_OK;
1451 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1452 struct policy_handle *domain_handle,
1453 const char *name, struct policy_handle *user_handle)
1456 struct samr_OpenUser r;
1459 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1460 if (!NT_STATUS_IS_OK(status)) {
1464 r.in.domain_handle = domain_handle;
1465 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1467 r.out.user_handle = user_handle;
1468 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1477 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1478 struct policy_handle *handle)
1481 struct samr_ChangePasswordUser r;
1483 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1484 struct policy_handle user_handle;
1485 char *oldpass = "test";
1486 char *newpass = "test2";
1487 uint8_t old_nt_hash[16], new_nt_hash[16];
1488 uint8_t old_lm_hash[16], new_lm_hash[16];
1490 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1491 if (!NT_STATUS_IS_OK(status)) {
1495 printf("Testing ChangePasswordUser for user 'testuser'\n");
1497 printf("old password: %s\n", oldpass);
1498 printf("new password: %s\n", newpass);
1500 E_md4hash(oldpass, old_nt_hash);
1501 E_md4hash(newpass, new_nt_hash);
1502 E_deshash(oldpass, old_lm_hash);
1503 E_deshash(newpass, new_lm_hash);
1505 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1506 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1507 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1508 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1509 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1510 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1512 r.in.handle = &user_handle;
1513 r.in.lm_present = 1;
1514 r.in.old_lm_crypted = &hash1;
1515 r.in.new_lm_crypted = &hash2;
1516 r.in.nt_present = 1;
1517 r.in.old_nt_crypted = &hash3;
1518 r.in.new_nt_crypted = &hash4;
1519 r.in.cross1_present = 1;
1520 r.in.nt_cross = &hash5;
1521 r.in.cross2_present = 1;
1522 r.in.lm_cross = &hash6;
1524 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1525 if (!NT_STATUS_IS_OK(status)) {
1526 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1530 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1538 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1539 const char *acct_name,
1540 struct policy_handle *handle, char **password)
1543 struct samr_ChangePasswordUser r;
1545 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1546 struct policy_handle user_handle;
1548 uint8_t old_nt_hash[16], new_nt_hash[16];
1549 uint8_t old_lm_hash[16], new_lm_hash[16];
1550 bool changed = true;
1553 struct samr_GetUserPwInfo pwp;
1554 struct samr_PwInfo info;
1555 int policy_min_pw_len = 0;
1557 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1558 if (!NT_STATUS_IS_OK(status)) {
1561 pwp.in.user_handle = &user_handle;
1562 pwp.out.info = &info;
1564 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1565 if (NT_STATUS_IS_OK(status)) {
1566 policy_min_pw_len = pwp.out.info->min_password_length;
1568 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1570 torture_comment(tctx, "Testing ChangePasswordUser\n");
1572 torture_assert(tctx, *password != NULL,
1573 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1575 oldpass = *password;
1577 E_md4hash(oldpass, old_nt_hash);
1578 E_md4hash(newpass, new_nt_hash);
1579 E_deshash(oldpass, old_lm_hash);
1580 E_deshash(newpass, new_lm_hash);
1582 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1583 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1584 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1585 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1586 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1587 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1589 r.in.user_handle = &user_handle;
1590 r.in.lm_present = 1;
1591 /* Break the LM hash */
1593 r.in.old_lm_crypted = &hash1;
1594 r.in.new_lm_crypted = &hash2;
1595 r.in.nt_present = 1;
1596 r.in.old_nt_crypted = &hash3;
1597 r.in.new_nt_crypted = &hash4;
1598 r.in.cross1_present = 1;
1599 r.in.nt_cross = &hash5;
1600 r.in.cross2_present = 1;
1601 r.in.lm_cross = &hash6;
1603 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1604 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1605 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1607 /* Unbreak the LM hash */
1610 r.in.user_handle = &user_handle;
1611 r.in.lm_present = 1;
1612 r.in.old_lm_crypted = &hash1;
1613 r.in.new_lm_crypted = &hash2;
1614 /* Break the NT hash */
1616 r.in.nt_present = 1;
1617 r.in.old_nt_crypted = &hash3;
1618 r.in.new_nt_crypted = &hash4;
1619 r.in.cross1_present = 1;
1620 r.in.nt_cross = &hash5;
1621 r.in.cross2_present = 1;
1622 r.in.lm_cross = &hash6;
1624 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1625 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1626 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1628 /* Unbreak the NT hash */
1631 r.in.user_handle = &user_handle;
1632 r.in.lm_present = 1;
1633 r.in.old_lm_crypted = &hash1;
1634 r.in.new_lm_crypted = &hash2;
1635 r.in.nt_present = 1;
1636 r.in.old_nt_crypted = &hash3;
1637 r.in.new_nt_crypted = &hash4;
1638 r.in.cross1_present = 1;
1639 r.in.nt_cross = &hash5;
1640 r.in.cross2_present = 1;
1641 /* Break the LM cross */
1643 r.in.lm_cross = &hash6;
1645 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1646 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1647 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1651 /* Unbreak the LM cross */
1654 r.in.user_handle = &user_handle;
1655 r.in.lm_present = 1;
1656 r.in.old_lm_crypted = &hash1;
1657 r.in.new_lm_crypted = &hash2;
1658 r.in.nt_present = 1;
1659 r.in.old_nt_crypted = &hash3;
1660 r.in.new_nt_crypted = &hash4;
1661 r.in.cross1_present = 1;
1662 /* Break the NT cross */
1664 r.in.nt_cross = &hash5;
1665 r.in.cross2_present = 1;
1666 r.in.lm_cross = &hash6;
1668 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1669 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1670 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1674 /* Unbreak the NT cross */
1678 /* Reset the hashes to not broken values */
1679 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1680 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1681 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1682 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1683 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1684 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1686 r.in.user_handle = &user_handle;
1687 r.in.lm_present = 1;
1688 r.in.old_lm_crypted = &hash1;
1689 r.in.new_lm_crypted = &hash2;
1690 r.in.nt_present = 1;
1691 r.in.old_nt_crypted = &hash3;
1692 r.in.new_nt_crypted = &hash4;
1693 r.in.cross1_present = 1;
1694 r.in.nt_cross = &hash5;
1695 r.in.cross2_present = 0;
1696 r.in.lm_cross = NULL;
1698 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1699 if (NT_STATUS_IS_OK(status)) {
1701 *password = newpass;
1702 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1703 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1708 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1710 E_md4hash(oldpass, old_nt_hash);
1711 E_md4hash(newpass, new_nt_hash);
1712 E_deshash(oldpass, old_lm_hash);
1713 E_deshash(newpass, new_lm_hash);
1716 /* Reset the hashes to not broken values */
1717 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1718 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1719 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1720 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1721 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1722 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1724 r.in.user_handle = &user_handle;
1725 r.in.lm_present = 1;
1726 r.in.old_lm_crypted = &hash1;
1727 r.in.new_lm_crypted = &hash2;
1728 r.in.nt_present = 1;
1729 r.in.old_nt_crypted = &hash3;
1730 r.in.new_nt_crypted = &hash4;
1731 r.in.cross1_present = 0;
1732 r.in.nt_cross = NULL;
1733 r.in.cross2_present = 1;
1734 r.in.lm_cross = &hash6;
1736 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1737 if (NT_STATUS_IS_OK(status)) {
1739 *password = newpass;
1740 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1741 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1746 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1748 E_md4hash(oldpass, old_nt_hash);
1749 E_md4hash(newpass, new_nt_hash);
1750 E_deshash(oldpass, old_lm_hash);
1751 E_deshash(newpass, new_lm_hash);
1754 /* Reset the hashes to not broken values */
1755 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1756 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1757 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1758 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1759 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1760 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1762 r.in.user_handle = &user_handle;
1763 r.in.lm_present = 1;
1764 r.in.old_lm_crypted = &hash1;
1765 r.in.new_lm_crypted = &hash2;
1766 r.in.nt_present = 1;
1767 r.in.old_nt_crypted = &hash3;
1768 r.in.new_nt_crypted = &hash4;
1769 r.in.cross1_present = 1;
1770 r.in.nt_cross = &hash5;
1771 r.in.cross2_present = 1;
1772 r.in.lm_cross = &hash6;
1774 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1775 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1776 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1777 } else if (!NT_STATUS_IS_OK(status)) {
1778 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1782 *password = newpass;
1785 r.in.user_handle = &user_handle;
1786 r.in.lm_present = 1;
1787 r.in.old_lm_crypted = &hash1;
1788 r.in.new_lm_crypted = &hash2;
1789 r.in.nt_present = 1;
1790 r.in.old_nt_crypted = &hash3;
1791 r.in.new_nt_crypted = &hash4;
1792 r.in.cross1_present = 1;
1793 r.in.nt_cross = &hash5;
1794 r.in.cross2_present = 1;
1795 r.in.lm_cross = &hash6;
1798 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1799 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1800 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1801 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1802 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1808 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1816 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1817 const char *acct_name,
1818 struct policy_handle *handle, char **password)
1821 struct samr_OemChangePasswordUser2 r;
1823 struct samr_Password lm_verifier;
1824 struct samr_CryptPassword lm_pass;
1825 struct lsa_AsciiString server, account, account_bad;
1828 uint8_t old_lm_hash[16], new_lm_hash[16];
1830 struct samr_GetDomPwInfo dom_pw_info;
1831 struct samr_PwInfo info;
1832 int policy_min_pw_len = 0;
1834 struct lsa_String domain_name;
1836 domain_name.string = "";
1837 dom_pw_info.in.domain_name = &domain_name;
1838 dom_pw_info.out.info = &info;
1840 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1842 torture_assert(tctx, *password != NULL,
1843 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1845 oldpass = *password;
1847 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1848 if (NT_STATUS_IS_OK(status)) {
1849 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1852 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1854 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1855 account.string = acct_name;
1857 E_deshash(oldpass, old_lm_hash);
1858 E_deshash(newpass, new_lm_hash);
1860 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1861 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1862 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1864 r.in.server = &server;
1865 r.in.account = &account;
1866 r.in.password = &lm_pass;
1867 r.in.hash = &lm_verifier;
1869 /* Break the verification */
1870 lm_verifier.hash[0]++;
1872 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1874 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1875 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1876 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1881 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1882 /* Break the old password */
1884 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1885 /* unbreak it for the next operation */
1887 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1889 r.in.server = &server;
1890 r.in.account = &account;
1891 r.in.password = &lm_pass;
1892 r.in.hash = &lm_verifier;
1894 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1896 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1897 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1898 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1903 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1904 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1906 r.in.server = &server;
1907 r.in.account = &account;
1908 r.in.password = &lm_pass;
1911 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1913 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1914 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1915 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1920 /* This shouldn't be a valid name */
1921 account_bad.string = TEST_ACCOUNT_NAME "XX";
1922 r.in.account = &account_bad;
1924 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1926 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1927 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1932 /* This shouldn't be a valid name */
1933 account_bad.string = TEST_ACCOUNT_NAME "XX";
1934 r.in.account = &account_bad;
1935 r.in.password = &lm_pass;
1936 r.in.hash = &lm_verifier;
1938 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1940 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1941 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1946 /* This shouldn't be a valid name */
1947 account_bad.string = TEST_ACCOUNT_NAME "XX";
1948 r.in.account = &account_bad;
1949 r.in.password = NULL;
1950 r.in.hash = &lm_verifier;
1952 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1954 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1955 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1960 E_deshash(oldpass, old_lm_hash);
1961 E_deshash(newpass, new_lm_hash);
1963 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1964 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1965 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1967 r.in.server = &server;
1968 r.in.account = &account;
1969 r.in.password = &lm_pass;
1970 r.in.hash = &lm_verifier;
1972 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1973 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1974 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1975 } else if (!NT_STATUS_IS_OK(status)) {
1976 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1979 *password = newpass;
1986 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1987 const char *acct_name,
1989 char *newpass, bool allow_password_restriction)
1992 struct samr_ChangePasswordUser2 r;
1994 struct lsa_String server, account;
1995 struct samr_CryptPassword nt_pass, lm_pass;
1996 struct samr_Password nt_verifier, lm_verifier;
1998 uint8_t old_nt_hash[16], new_nt_hash[16];
1999 uint8_t old_lm_hash[16], new_lm_hash[16];
2001 struct samr_GetDomPwInfo dom_pw_info;
2002 struct samr_PwInfo info;
2004 struct lsa_String domain_name;
2006 domain_name.string = "";
2007 dom_pw_info.in.domain_name = &domain_name;
2008 dom_pw_info.out.info = &info;
2010 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2012 torture_assert(tctx, *password != NULL,
2013 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2014 oldpass = *password;
2017 int policy_min_pw_len = 0;
2018 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2019 if (NT_STATUS_IS_OK(status)) {
2020 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2023 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2026 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2027 init_lsa_String(&account, acct_name);
2029 E_md4hash(oldpass, old_nt_hash);
2030 E_md4hash(newpass, new_nt_hash);
2032 E_deshash(oldpass, old_lm_hash);
2033 E_deshash(newpass, new_lm_hash);
2035 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2036 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2037 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2039 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2040 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2041 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2043 r.in.server = &server;
2044 r.in.account = &account;
2045 r.in.nt_password = &nt_pass;
2046 r.in.nt_verifier = &nt_verifier;
2048 r.in.lm_password = &lm_pass;
2049 r.in.lm_verifier = &lm_verifier;
2051 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2052 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2053 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2054 } else if (!NT_STATUS_IS_OK(status)) {
2055 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2058 *password = newpass;
2065 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2066 const char *account_string,
2067 int policy_min_pw_len,
2069 const char *newpass,
2070 NTTIME last_password_change,
2071 bool handle_reject_reason)
2074 struct samr_ChangePasswordUser3 r;
2076 struct lsa_String server, account, account_bad;
2077 struct samr_CryptPassword nt_pass, lm_pass;
2078 struct samr_Password nt_verifier, lm_verifier;
2080 uint8_t old_nt_hash[16], new_nt_hash[16];
2081 uint8_t old_lm_hash[16], new_lm_hash[16];
2083 struct samr_DomInfo1 *dominfo = NULL;
2084 struct samr_ChangeReject *reject = NULL;
2086 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2088 if (newpass == NULL) {
2090 if (policy_min_pw_len == 0) {
2091 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2093 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2095 } while (check_password_quality(newpass) == false);
2097 torture_comment(tctx, "Using password '%s'\n", newpass);
2100 torture_assert(tctx, *password != NULL,
2101 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2103 oldpass = *password;
2104 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2105 init_lsa_String(&account, account_string);
2107 E_md4hash(oldpass, old_nt_hash);
2108 E_md4hash(newpass, new_nt_hash);
2110 E_deshash(oldpass, old_lm_hash);
2111 E_deshash(newpass, new_lm_hash);
2113 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2114 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2115 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2117 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2118 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2119 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2121 /* Break the verification */
2122 nt_verifier.hash[0]++;
2124 r.in.server = &server;
2125 r.in.account = &account;
2126 r.in.nt_password = &nt_pass;
2127 r.in.nt_verifier = &nt_verifier;
2129 r.in.lm_password = &lm_pass;
2130 r.in.lm_verifier = &lm_verifier;
2131 r.in.password3 = NULL;
2132 r.out.dominfo = &dominfo;
2133 r.out.reject = &reject;
2135 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2136 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2137 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2138 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2143 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2144 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2145 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2147 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2148 /* Break the NT hash */
2150 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2151 /* Unbreak it again */
2153 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2155 r.in.server = &server;
2156 r.in.account = &account;
2157 r.in.nt_password = &nt_pass;
2158 r.in.nt_verifier = &nt_verifier;
2160 r.in.lm_password = &lm_pass;
2161 r.in.lm_verifier = &lm_verifier;
2162 r.in.password3 = NULL;
2163 r.out.dominfo = &dominfo;
2164 r.out.reject = &reject;
2166 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2167 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2168 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2169 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2174 /* This shouldn't be a valid name */
2175 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2177 r.in.account = &account_bad;
2178 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2179 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2180 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2185 E_md4hash(oldpass, old_nt_hash);
2186 E_md4hash(newpass, new_nt_hash);
2188 E_deshash(oldpass, old_lm_hash);
2189 E_deshash(newpass, new_lm_hash);
2191 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2192 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2193 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2195 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2196 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2197 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2199 r.in.server = &server;
2200 r.in.account = &account;
2201 r.in.nt_password = &nt_pass;
2202 r.in.nt_verifier = &nt_verifier;
2204 r.in.lm_password = &lm_pass;
2205 r.in.lm_verifier = &lm_verifier;
2206 r.in.password3 = NULL;
2207 r.out.dominfo = &dominfo;
2208 r.out.reject = &reject;
2210 unix_to_nt_time(&t, time(NULL));
2212 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2214 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2217 && handle_reject_reason
2218 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2219 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2221 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2222 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2223 SAMR_REJECT_OTHER, reject->reason);
2228 /* We tested the order of precendence which is as follows:
2237 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2238 (last_password_change + dominfo->min_password_age > t)) {
2240 if (reject->reason != SAMR_REJECT_OTHER) {
2241 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2242 SAMR_REJECT_OTHER, reject->reason);
2246 } else if ((dominfo->min_password_length > 0) &&
2247 (strlen(newpass) < dominfo->min_password_length)) {
2249 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2250 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2251 SAMR_REJECT_TOO_SHORT, reject->reason);
2255 } else if ((dominfo->password_history_length > 0) &&
2256 strequal(oldpass, newpass)) {
2258 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2259 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2260 SAMR_REJECT_IN_HISTORY, reject->reason);
2263 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2265 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2266 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2267 SAMR_REJECT_COMPLEXITY, reject->reason);
2273 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2274 /* retry with adjusted size */
2275 return test_ChangePasswordUser3(p, tctx, account_string,
2276 dominfo->min_password_length,
2277 password, NULL, 0, false);
2281 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2282 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2283 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2284 SAMR_REJECT_OTHER, reject->reason);
2287 /* Perhaps the server has a 'min password age' set? */
2290 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2291 *password = talloc_strdup(tctx, newpass);
2297 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2298 const char *account_string,
2299 struct policy_handle *handle,
2303 struct samr_ChangePasswordUser3 r;
2304 struct samr_SetUserInfo s;
2305 union samr_UserInfo u;
2306 DATA_BLOB session_key;
2307 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2308 uint8_t confounder[16];
2309 struct MD5Context ctx;
2312 struct lsa_String server, account;
2313 struct samr_CryptPassword nt_pass;
2314 struct samr_Password nt_verifier;
2315 DATA_BLOB new_random_pass;
2318 uint8_t old_nt_hash[16], new_nt_hash[16];
2320 struct samr_DomInfo1 *dominfo = NULL;
2321 struct samr_ChangeReject *reject = NULL;
2323 new_random_pass = samr_very_rand_pass(tctx, 128);
2325 torture_assert(tctx, *password != NULL,
2326 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2328 oldpass = *password;
2329 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2330 init_lsa_String(&account, account_string);
2332 s.in.user_handle = handle;
2338 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2340 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2342 status = dcerpc_fetch_session_key(p, &session_key);
2343 if (!NT_STATUS_IS_OK(status)) {
2344 printf("SetUserInfo level %u - no session key - %s\n",
2345 s.in.level, nt_errstr(status));
2349 generate_random_buffer((uint8_t *)confounder, 16);
2352 MD5Update(&ctx, confounder, 16);
2353 MD5Update(&ctx, session_key.data, session_key.length);
2354 MD5Final(confounded_session_key.data, &ctx);
2356 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2357 memcpy(&u.info25.password.data[516], confounder, 16);
2359 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2361 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 printf("SetUserInfo level %u failed - %s\n",
2364 s.in.level, nt_errstr(status));
2368 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2370 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2372 new_random_pass = samr_very_rand_pass(tctx, 128);
2374 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2376 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2377 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2378 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2380 r.in.server = &server;
2381 r.in.account = &account;
2382 r.in.nt_password = &nt_pass;
2383 r.in.nt_verifier = &nt_verifier;
2385 r.in.lm_password = NULL;
2386 r.in.lm_verifier = NULL;
2387 r.in.password3 = NULL;
2388 r.out.dominfo = &dominfo;
2389 r.out.reject = &reject;
2391 unix_to_nt_time(&t, time(NULL));
2393 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2395 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2396 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2397 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2398 SAMR_REJECT_OTHER, reject->reason);
2401 /* Perhaps the server has a 'min password age' set? */
2403 } else if (!NT_STATUS_IS_OK(status)) {
2404 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2408 newpass = samr_rand_pass(tctx, 128);
2410 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2412 E_md4hash(newpass, new_nt_hash);
2414 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2415 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2416 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2418 r.in.server = &server;
2419 r.in.account = &account;
2420 r.in.nt_password = &nt_pass;
2421 r.in.nt_verifier = &nt_verifier;
2423 r.in.lm_password = NULL;
2424 r.in.lm_verifier = NULL;
2425 r.in.password3 = NULL;
2426 r.out.dominfo = &dominfo;
2427 r.out.reject = &reject;
2429 unix_to_nt_time(&t, time(NULL));
2431 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2433 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2434 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2435 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2436 SAMR_REJECT_OTHER, reject->reason);
2439 /* Perhaps the server has a 'min password age' set? */
2442 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2443 *password = talloc_strdup(tctx, newpass);
2450 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2451 struct policy_handle *alias_handle)
2453 struct samr_GetMembersInAlias r;
2454 struct lsa_SidArray sids;
2457 torture_comment(tctx, "Testing GetMembersInAlias\n");
2459 r.in.alias_handle = alias_handle;
2462 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2463 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2468 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2469 struct policy_handle *alias_handle,
2470 const struct dom_sid *domain_sid)
2472 struct samr_AddAliasMember r;
2473 struct samr_DeleteAliasMember d;
2475 struct dom_sid *sid;
2477 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2479 torture_comment(tctx, "testing AddAliasMember\n");
2480 r.in.alias_handle = alias_handle;
2483 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2484 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2486 d.in.alias_handle = alias_handle;
2489 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2490 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2495 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2496 struct policy_handle *alias_handle)
2498 struct samr_AddMultipleMembersToAlias a;
2499 struct samr_RemoveMultipleMembersFromAlias r;
2501 struct lsa_SidArray sids;
2503 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2504 a.in.alias_handle = alias_handle;
2508 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2510 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2511 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2512 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2514 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2515 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2518 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2519 r.in.alias_handle = alias_handle;
2522 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2523 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2525 /* strange! removing twice doesn't give any error */
2526 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2527 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2529 /* but removing an alias that isn't there does */
2530 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2532 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2533 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2538 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2539 struct policy_handle *user_handle)
2541 struct samr_TestPrivateFunctionsUser r;
2544 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2546 r.in.user_handle = user_handle;
2548 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2549 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2554 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2555 struct torture_context *tctx,
2556 struct policy_handle *handle,
2561 uint16_t levels[] = { /* 3, */ 5, 21 };
2563 NTTIME pwdlastset3 = 0;
2564 NTTIME pwdlastset5 = 0;
2565 NTTIME pwdlastset21 = 0;
2567 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2568 use_info2 ? "2":"");
2570 for (i=0; i<ARRAY_SIZE(levels); i++) {
2572 struct samr_QueryUserInfo r;
2573 struct samr_QueryUserInfo2 r2;
2574 union samr_UserInfo *info;
2577 r2.in.user_handle = handle;
2578 r2.in.level = levels[i];
2579 r2.out.info = &info;
2580 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2583 r.in.user_handle = handle;
2584 r.in.level = levels[i];
2586 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2589 if (!NT_STATUS_IS_OK(status) &&
2590 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2591 printf("QueryUserInfo%s level %u failed - %s\n",
2592 use_info2 ? "2":"", levels[i], nt_errstr(status));
2596 switch (levels[i]) {
2598 pwdlastset3 = info->info3.last_password_change;
2601 pwdlastset5 = info->info5.last_password_change;
2604 pwdlastset21 = info->info21.last_password_change;
2610 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2611 "pwdlastset mixup"); */
2612 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2613 "pwdlastset mixup");
2615 *pwdlastset = pwdlastset21;
2617 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2622 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2623 struct torture_context *tctx,
2624 struct policy_handle *handle,
2626 uint32_t fields_present,
2627 uint8_t password_expired,
2628 bool *matched_expected_error,
2631 bool use_queryinfo2,
2634 const char *fields = NULL;
2641 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2648 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2649 "(password_expired: %d) %s\n",
2650 use_setinfo2 ? "2":"", level, password_expired,
2651 fields ? fields : "");
2653 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2658 matched_expected_error)) {
2662 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2671 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2672 struct torture_context *tctx,
2673 uint32_t acct_flags,
2674 struct policy_handle *handle,
2677 int i, s = 0, q = 0, f = 0, l = 0, z = 0;
2680 bool set_levels[] = { false, true };
2681 bool query_levels[] = { false, true };
2682 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2683 uint32_t nonzeros[] = { 1, 24 };
2684 uint32_t fields_present[] = {
2686 SAMR_FIELD_EXPIRED_FLAG,
2687 SAMR_FIELD_LAST_PWD_CHANGE,
2688 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2690 SAMR_FIELD_NT_PASSWORD_PRESENT,
2691 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2692 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2693 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2694 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2695 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2696 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2699 if (torture_setting_bool(tctx, "samba3", false)) {
2701 printf("Samba3 has second granularity, setting delay to: %d\n",
2705 /* set to 1 to enable testing for all possible opcode
2706 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2709 #define TEST_SET_LEVELS 1
2710 #define TEST_QUERY_LEVELS 1
2712 for (l=0; l<ARRAY_SIZE(levels); l++) {
2713 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2714 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2715 #ifdef TEST_SET_LEVELS
2716 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2718 #ifdef TEST_QUERY_LEVELS
2719 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2721 NTTIME pwdlastset_old = 0;
2722 NTTIME pwdlastset_new = 0;
2723 bool matched_expected_error = false;
2725 torture_comment(tctx, "------------------------------\n"
2726 "Testing pwdLastSet attribute for flags: 0x%08x "
2727 "(s: %d (l: %d), q: %d)\n",
2728 acct_flags, s, levels[l], q);
2732 /* set a password and force password change (pwdlastset 0) by
2733 * setting the password expired flag to a non-0 value */
2735 if (!test_SetPassword_level(p, tctx, handle,
2739 &matched_expected_error,
2747 if (matched_expected_error == true) {
2748 /* skipping on expected failure */
2752 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2753 * set without the SAMR_FIELD_EXPIRED_FLAG */
2755 switch (levels[l]) {
2759 if ((pwdlastset_new != 0) &&
2760 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2761 torture_comment(tctx, "not considering a non-0 "
2762 "pwdLastSet as a an error as the "
2763 "SAMR_FIELD_EXPIRED_FLAG has not "
2768 if (pwdlastset_new != 0) {
2769 torture_warning(tctx, "pwdLastSet test failed: "
2770 "expected pwdLastSet 0 but got %lld\n",
2777 switch (levels[l]) {
2781 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2782 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2783 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2784 (pwdlastset_old >= pwdlastset_new)) {
2785 torture_warning(tctx, "pwdlastset not increasing\n");
2790 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2791 (pwdlastset_old >= pwdlastset_new)) {
2792 torture_warning(tctx, "pwdlastset not increasing\n");
2802 /* set a password, pwdlastset needs to get updated (increased
2803 * value), password_expired value used here is 0 */
2805 if (!test_SetPassword_level(p, tctx, handle,
2809 &matched_expected_error,
2817 /* when a password has been changed, pwdlastset must not be 0 afterwards
2818 * and must be larger then the old value */
2820 switch (levels[l]) {
2825 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2826 * password has been changed, old and new pwdlastset
2827 * need to be the same value */
2829 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
2830 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2831 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2833 torture_assert_int_equal(tctx, pwdlastset_old,
2834 pwdlastset_new, "pwdlastset must be equal");
2838 if (pwdlastset_old >= pwdlastset_new) {
2839 torture_warning(tctx, "pwdLastSet test failed: "
2840 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2841 pwdlastset_old, pwdlastset_new);
2844 if (pwdlastset_new == 0) {
2845 torture_warning(tctx, "pwdLastSet test failed: "
2846 "expected non-0 pwdlastset, got: %lld\n",
2852 switch (levels[l]) {
2856 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2857 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2858 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2859 (pwdlastset_old >= pwdlastset_new)) {
2860 torture_warning(tctx, "pwdlastset not increasing\n");
2865 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2866 (pwdlastset_old >= pwdlastset_new)) {
2867 torture_warning(tctx, "pwdlastset not increasing\n");
2873 pwdlastset_old = pwdlastset_new;
2879 /* set a password, pwdlastset needs to get updated (increased
2880 * value), password_expired value used here is 0 */
2882 if (!test_SetPassword_level(p, tctx, handle,
2886 &matched_expected_error,
2894 /* when a password has been changed, pwdlastset must not be 0 afterwards
2895 * and must be larger then the old value */
2897 switch (levels[l]) {
2902 /* if no password has been changed, old and new pwdlastset
2903 * need to be the same value */
2905 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2906 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2908 torture_assert_int_equal(tctx, pwdlastset_old,
2909 pwdlastset_new, "pwdlastset must be equal");
2913 if (pwdlastset_old >= pwdlastset_new) {
2914 torture_warning(tctx, "pwdLastSet test failed: "
2915 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2916 pwdlastset_old, pwdlastset_new);
2919 if (pwdlastset_new == 0) {
2920 torture_warning(tctx, "pwdLastSet test failed: "
2921 "expected non-0 pwdlastset, got: %lld\n",
2929 /* set a password and force password change (pwdlastset 0) by
2930 * setting the password expired flag to a non-0 value */
2932 if (!test_SetPassword_level(p, tctx, handle,
2936 &matched_expected_error,
2944 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2945 * set without the SAMR_FIELD_EXPIRED_FLAG */
2947 switch (levels[l]) {
2951 if ((pwdlastset_new != 0) &&
2952 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2953 torture_comment(tctx, "not considering a non-0 "
2954 "pwdLastSet as a an error as the "
2955 "SAMR_FIELD_EXPIRED_FLAG has not "
2960 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2961 * password has been changed, old and new pwdlastset
2962 * need to be the same value */
2964 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
2965 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2966 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2968 torture_assert_int_equal(tctx, pwdlastset_old,
2969 pwdlastset_new, "pwdlastset must be equal");
2974 if (pwdlastset_old == pwdlastset_new) {
2975 torture_warning(tctx, "pwdLastSet test failed: "
2976 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2977 pwdlastset_old, pwdlastset_new);
2981 if (pwdlastset_new != 0) {
2982 torture_warning(tctx, "pwdLastSet test failed: "
2983 "expected pwdLastSet 0, got %lld\n",
2990 switch (levels[l]) {
2994 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2995 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2996 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2997 (pwdlastset_old >= pwdlastset_new)) {
2998 torture_warning(tctx, "pwdlastset not increasing\n");
3003 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3004 (pwdlastset_old >= pwdlastset_new)) {
3005 torture_warning(tctx, "pwdlastset not increasing\n");
3011 /* if the level we are testing does not have a fields_present
3012 * field, skip all fields present tests by setting f to to
3014 switch (levels[l]) {
3018 f = ARRAY_SIZE(fields_present);
3022 #ifdef TEST_QUERY_LEVELS
3025 #ifdef TEST_SET_LEVELS
3028 } /* fields present */
3032 #undef TEST_SET_LEVELS
3033 #undef TEST_QUERY_LEVELS
3038 static bool test_user_ops(struct dcerpc_pipe *p,
3039 struct torture_context *tctx,
3040 struct policy_handle *user_handle,
3041 struct policy_handle *domain_handle,
3042 uint32_t base_acct_flags,
3043 const char *base_acct_name, enum torture_samr_choice which_ops)
3045 char *password = NULL;
3046 struct samr_QueryUserInfo q;
3047 union samr_UserInfo *info;
3053 const uint32_t password_fields[] = {
3054 SAMR_FIELD_NT_PASSWORD_PRESENT,
3055 SAMR_FIELD_LM_PASSWORD_PRESENT,
3056 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3060 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3061 if (!NT_STATUS_IS_OK(status)) {
3065 switch (which_ops) {
3066 case TORTURE_SAMR_USER_ATTRIBUTES:
3067 if (!test_QuerySecurity(p, tctx, user_handle)) {
3071 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3075 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3079 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3084 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3088 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3092 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3096 case TORTURE_SAMR_PASSWORDS:
3097 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3098 char simple_pass[9];
3099 char *v = generate_random_str(tctx, 1);
3101 ZERO_STRUCT(simple_pass);
3102 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3104 printf("Testing machine account password policy rules\n");
3106 /* Workstation trust accounts don't seem to need to honour password quality policy */
3107 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3111 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3115 /* reset again, to allow another 'user' password change */
3116 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3120 /* Try a 'short' password */
3121 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3125 /* Try a compleatly random password */
3126 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3131 for (i = 0; password_fields[i]; i++) {
3132 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3136 /* check it was set right */
3137 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3142 for (i = 0; password_fields[i]; i++) {
3143 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3147 /* check it was set right */
3148 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3153 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3157 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3161 if (torture_setting_bool(tctx, "samba4", false)) {
3162 printf("skipping Set Password level 18 and 21 against Samba4\n");
3165 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3169 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3173 for (i = 0; password_fields[i]; i++) {
3175 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3176 /* we need to skip as that would break
3177 * the ChangePasswordUser3 verify */
3181 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3185 /* check it was set right */
3186 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3192 q.in.user_handle = user_handle;
3196 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3197 if (!NT_STATUS_IS_OK(status)) {
3198 printf("QueryUserInfo level %u failed - %s\n",
3199 q.in.level, nt_errstr(status));
3202 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3203 if ((info->info5.acct_flags) != expected_flags) {
3204 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3205 info->info5.acct_flags,
3209 if (info->info5.rid != rid) {
3210 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3211 info->info5.rid, rid);
3218 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3220 /* test last password change timestamp behaviour */
3221 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3222 user_handle, &password)) {
3227 torture_comment(tctx, "pwdLastSet test succeeded\n");
3229 torture_warning(tctx, "pwdLastSet test failed\n");
3234 case TORTURE_SAMR_OTHER:
3235 /* We just need the account to exist */
3241 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3242 struct policy_handle *alias_handle,
3243 const struct dom_sid *domain_sid)
3247 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3251 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3255 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3259 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3263 if (torture_setting_bool(tctx, "samba4", false)) {
3264 printf("skipping MultipleMembers Alias tests against Samba4\n");
3268 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3276 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3277 struct policy_handle *user_handle)
3279 struct samr_DeleteUser d;
3281 torture_comment(tctx, "Testing DeleteUser\n");
3283 d.in.user_handle = user_handle;
3284 d.out.user_handle = user_handle;
3286 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3287 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3292 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3293 struct policy_handle *handle, const char *name)
3296 struct samr_DeleteUser d;
3297 struct policy_handle user_handle;
3300 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3301 if (!NT_STATUS_IS_OK(status)) {
3305 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3306 if (!NT_STATUS_IS_OK(status)) {
3310 d.in.user_handle = &user_handle;
3311 d.out.user_handle = &user_handle;
3312 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3313 if (!NT_STATUS_IS_OK(status)) {
3320 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3325 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3326 struct policy_handle *handle, const char *name)
3329 struct samr_OpenGroup r;
3330 struct samr_DeleteDomainGroup d;
3331 struct policy_handle group_handle;
3334 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3335 if (!NT_STATUS_IS_OK(status)) {
3339 r.in.domain_handle = handle;
3340 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3342 r.out.group_handle = &group_handle;
3343 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3344 if (!NT_STATUS_IS_OK(status)) {
3348 d.in.group_handle = &group_handle;
3349 d.out.group_handle = &group_handle;
3350 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3351 if (!NT_STATUS_IS_OK(status)) {
3358 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3363 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3364 struct policy_handle *domain_handle, const char *name)
3367 struct samr_OpenAlias r;
3368 struct samr_DeleteDomAlias d;
3369 struct policy_handle alias_handle;
3372 printf("testing DeleteAlias_byname\n");
3374 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3375 if (!NT_STATUS_IS_OK(status)) {
3379 r.in.domain_handle = domain_handle;
3380 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3382 r.out.alias_handle = &alias_handle;
3383 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3384 if (!NT_STATUS_IS_OK(status)) {
3388 d.in.alias_handle = &alias_handle;
3389 d.out.alias_handle = &alias_handle;
3390 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3391 if (!NT_STATUS_IS_OK(status)) {
3398 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3402 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3403 struct policy_handle *alias_handle)
3405 struct samr_DeleteDomAlias d;
3408 printf("Testing DeleteAlias\n");
3410 d.in.alias_handle = alias_handle;
3411 d.out.alias_handle = alias_handle;
3413 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3414 if (!NT_STATUS_IS_OK(status)) {
3415 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3422 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3423 struct policy_handle *domain_handle,
3424 struct policy_handle *alias_handle,
3425 const struct dom_sid *domain_sid)
3428 struct samr_CreateDomAlias r;
3429 struct lsa_String name;
3433 init_lsa_String(&name, TEST_ALIASNAME);
3434 r.in.domain_handle = domain_handle;
3435 r.in.alias_name = &name;
3436 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3437 r.out.alias_handle = alias_handle;
3440 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3442 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3444 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3445 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3446 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3449 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3455 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3456 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3459 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3462 if (!NT_STATUS_IS_OK(status)) {
3463 printf("CreateAlias failed - %s\n", nt_errstr(status));
3467 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3474 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3475 const char *acct_name,
3476 struct policy_handle *domain_handle, char **password)
3484 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3488 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3492 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3496 /* test what happens when setting the old password again */
3497 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3502 char simple_pass[9];
3503 char *v = generate_random_str(mem_ctx, 1);
3505 ZERO_STRUCT(simple_pass);
3506 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3508 /* test what happens when picking a simple password */
3509 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3514 /* set samr_SetDomainInfo level 1 with min_length 5 */
3516 struct samr_QueryDomainInfo r;
3517 union samr_DomainInfo *info = NULL;
3518 struct samr_SetDomainInfo s;
3519 uint16_t len_old, len;
3520 uint32_t pwd_prop_old;
3521 int64_t min_pwd_age_old;
3526 r.in.domain_handle = domain_handle;
3530 printf("testing samr_QueryDomainInfo level 1\n");
3531 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3532 if (!NT_STATUS_IS_OK(status)) {
3536 s.in.domain_handle = domain_handle;
3540 /* remember the old min length, so we can reset it */
3541 len_old = s.in.info->info1.min_password_length;
3542 s.in.info->info1.min_password_length = len;
3543 pwd_prop_old = s.in.info->info1.password_properties;
3544 /* turn off password complexity checks for this test */
3545 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3547 min_pwd_age_old = s.in.info->info1.min_password_age;
3548 s.in.info->info1.min_password_age = 0;
3550 printf("testing samr_SetDomainInfo level 1\n");
3551 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3552 if (!NT_STATUS_IS_OK(status)) {
3556 printf("calling test_ChangePasswordUser3 with too short password\n");
3558 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3562 s.in.info->info1.min_password_length = len_old;
3563 s.in.info->info1.password_properties = pwd_prop_old;
3564 s.in.info->info1.min_password_age = min_pwd_age_old;
3566 printf("testing samr_SetDomainInfo level 1\n");
3567 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3568 if (!NT_STATUS_IS_OK(status)) {
3576 struct samr_OpenUser r;
3577 struct samr_QueryUserInfo q;
3578 union samr_UserInfo *info;
3579 struct samr_LookupNames n;
3580 struct policy_handle user_handle;
3581 struct samr_Ids rids, types;
3583 n.in.domain_handle = domain_handle;
3585 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3586 n.in.names[0].string = acct_name;
3588 n.out.types = &types;
3590 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3591 if (!NT_STATUS_IS_OK(status)) {
3592 printf("LookupNames failed - %s\n", nt_errstr(status));
3596 r.in.domain_handle = domain_handle;
3597 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3598 r.in.rid = n.out.rids->ids[0];
3599 r.out.user_handle = &user_handle;
3601 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3602 if (!NT_STATUS_IS_OK(status)) {
3603 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3607 q.in.user_handle = &user_handle;
3611 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3612 if (!NT_STATUS_IS_OK(status)) {
3613 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3617 printf("calling test_ChangePasswordUser3 with too early password change\n");
3619 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3620 info->info5.last_password_change, true)) {
3625 /* we change passwords twice - this has the effect of verifying
3626 they were changed correctly for the final call */
3627 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3631 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3638 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3639 struct policy_handle *domain_handle,
3640 struct policy_handle *user_handle_out,
3641 struct dom_sid *domain_sid,
3642 enum torture_samr_choice which_ops)
3645 TALLOC_CTX *user_ctx;
3648 struct samr_CreateUser r;
3649 struct samr_QueryUserInfo q;
3650 union samr_UserInfo *info;
3651 struct samr_DeleteUser d;
3654 /* This call creates a 'normal' account - check that it really does */
3655 const uint32_t acct_flags = ACB_NORMAL;
3656 struct lsa_String name;
3659 struct policy_handle user_handle;
3660 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3661 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3663 r.in.domain_handle = domain_handle;
3664 r.in.account_name = &name;
3665 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3666 r.out.user_handle = &user_handle;
3669 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3671 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3673 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3674 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3675 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3678 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3684 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3685 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3686 talloc_free(user_ctx);
3689 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3691 if (!NT_STATUS_IS_OK(status)) {
3692 talloc_free(user_ctx);
3693 printf("CreateUser failed - %s\n", nt_errstr(status));
3696 q.in.user_handle = &user_handle;
3700 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3701 if (!NT_STATUS_IS_OK(status)) {
3702 printf("QueryUserInfo level %u failed - %s\n",
3703 q.in.level, nt_errstr(status));
3706 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3707 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3708 info->info16.acct_flags,
3714 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3715 acct_flags, name.string, which_ops)) {
3719 if (user_handle_out) {
3720 *user_handle_out = user_handle;
3722 printf("Testing DeleteUser (createuser test)\n");
3724 d.in.user_handle = &user_handle;
3725 d.out.user_handle = &user_handle;
3727 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3728 if (!NT_STATUS_IS_OK(status)) {
3729 printf("DeleteUser failed - %s\n", nt_errstr(status));
3736 talloc_free(user_ctx);
3742 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3743 struct policy_handle *domain_handle,
3744 struct dom_sid *domain_sid,
3745 enum torture_samr_choice which_ops)
3748 struct samr_CreateUser2 r;
3749 struct samr_QueryUserInfo q;
3750 union samr_UserInfo *info;
3751 struct samr_DeleteUser d;
3752 struct policy_handle user_handle;
3754 struct lsa_String name;
3759 uint32_t acct_flags;
3760 const char *account_name;
3762 } account_types[] = {
3763 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3764 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3765 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3766 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3767 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3768 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3769 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3770 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3771 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3772 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3773 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3774 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3775 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3776 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3777 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3780 for (i = 0; account_types[i].account_name; i++) {
3781 TALLOC_CTX *user_ctx;
3782 uint32_t acct_flags = account_types[i].acct_flags;
3783 uint32_t access_granted;
3784 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3785 init_lsa_String(&name, account_types[i].account_name);
3787 r.in.domain_handle = domain_handle;
3788 r.in.account_name = &name;
3789 r.in.acct_flags = acct_flags;
3790 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3791 r.out.user_handle = &user_handle;
3792 r.out.access_granted = &access_granted;
3795 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
3797 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3799 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3800 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3801 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3804 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3811 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3812 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3813 talloc_free(user_ctx);
3817 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3820 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
3821 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
3822 nt_errstr(status), nt_errstr(account_types[i].nt_status));
3826 if (NT_STATUS_IS_OK(status)) {
3827 q.in.user_handle = &user_handle;
3831 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3832 if (!NT_STATUS_IS_OK(status)) {
3833 printf("QueryUserInfo level %u failed - %s\n",
3834 q.in.level, nt_errstr(status));
3837 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3838 if (acct_flags == ACB_NORMAL) {
3839 expected_flags |= ACB_PW_EXPIRED;
3841 if ((info->info5.acct_flags) != expected_flags) {
3842 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3843 info->info5.acct_flags,
3847 switch (acct_flags) {
3849 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
3850 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
3851 DOMAIN_RID_DCS, info->info5.primary_gid);
3856 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
3857 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
3858 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
3863 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
3864 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
3865 DOMAIN_RID_USERS, info->info5.primary_gid);
3872 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3873 acct_flags, name.string, which_ops)) {
3877 printf("Testing DeleteUser (createuser2 test)\n");
3879 d.in.user_handle = &user_handle;
3880 d.out.user_handle = &user_handle;
3882 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3883 if (!NT_STATUS_IS_OK(status)) {
3884 printf("DeleteUser failed - %s\n", nt_errstr(status));
3888 talloc_free(user_ctx);
3894 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3895 struct policy_handle *handle)
3898 struct samr_QueryAliasInfo r;
3899 union samr_AliasInfo *info;
3900 uint16_t levels[] = {1, 2, 3};
3904 for (i=0;i<ARRAY_SIZE(levels);i++) {
3905 printf("Testing QueryAliasInfo level %u\n", levels[i]);
3907 r.in.alias_handle = handle;
3908 r.in.level = levels[i];
3911 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
3912 if (!NT_STATUS_IS_OK(status)) {
3913 printf("QueryAliasInfo level %u failed - %s\n",
3914 levels[i], nt_errstr(status));
3922 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3923 struct policy_handle *handle)
3926 struct samr_QueryGroupInfo r;
3927 union samr_GroupInfo *info;
3928 uint16_t levels[] = {1, 2, 3, 4, 5};
3932 for (i=0;i<ARRAY_SIZE(levels);i++) {
3933 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3935 r.in.group_handle = handle;
3936 r.in.level = levels[i];
3939 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3940 if (!NT_STATUS_IS_OK(status)) {
3941 printf("QueryGroupInfo level %u failed - %s\n",
3942 levels[i], nt_errstr(status));
3950 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3951 struct policy_handle *handle)
3954 struct samr_QueryGroupMember r;
3955 struct samr_RidTypeArray *rids = NULL;
3958 printf("Testing QueryGroupMember\n");
3960 r.in.group_handle = handle;
3963 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3964 if (!NT_STATUS_IS_OK(status)) {
3965 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3973 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3974 struct policy_handle *handle)
3977 struct samr_QueryGroupInfo r;
3978 union samr_GroupInfo *info;
3979 struct samr_SetGroupInfo s;
3980 uint16_t levels[] = {1, 2, 3, 4};
3981 uint16_t set_ok[] = {0, 1, 1, 1};
3985 for (i=0;i<ARRAY_SIZE(levels);i++) {
3986 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3988 r.in.group_handle = handle;
3989 r.in.level = levels[i];
3992 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3993 if (!NT_STATUS_IS_OK(status)) {
3994 printf("QueryGroupInfo level %u failed - %s\n",
3995 levels[i], nt_errstr(status));
3999 printf("Testing SetGroupInfo level %u\n", levels[i]);
4001 s.in.group_handle = handle;
4002 s.in.level = levels[i];
4003 s.in.info = *r.out.info;
4006 /* disabled this, as it changes the name only from the point of view of samr,
4007 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4008 the name is still reserved, so creating the old name fails, but deleting by the old name
4010 if (s.in.level == 2) {
4011 init_lsa_String(&s.in.info->string, "NewName");
4015 if (s.in.level == 4) {
4016 init_lsa_String(&s.in.info->description, "test description");
4019 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4021 if (!NT_STATUS_IS_OK(status)) {
4022 printf("SetGroupInfo level %u failed - %s\n",
4023 r.in.level, nt_errstr(status));
4028 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4029 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4030 r.in.level, nt_errstr(status));
4040 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4041 struct policy_handle *handle)
4044 struct samr_QueryUserInfo r;
4045 union samr_UserInfo *info;
4046 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4047 11, 12, 13, 14, 16, 17, 20, 21};
4051 for (i=0;i<ARRAY_SIZE(levels);i++) {
4052 printf("Testing QueryUserInfo level %u\n", levels[i]);
4054 r.in.user_handle = handle;
4055 r.in.level = levels[i];
4058 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4059 if (!NT_STATUS_IS_OK(status)) {
4060 printf("QueryUserInfo level %u failed - %s\n",
4061 levels[i], nt_errstr(status));
4069 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4070 struct policy_handle *handle)
4073 struct samr_QueryUserInfo2 r;
4074 union samr_UserInfo *info;
4075 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4076 11, 12, 13, 14, 16, 17, 20, 21};
4080 for (i=0;i<ARRAY_SIZE(levels);i++) {
4081 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4083 r.in.user_handle = handle;
4084 r.in.level = levels[i];
4087 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4088 if (!NT_STATUS_IS_OK(status)) {
4089 printf("QueryUserInfo2 level %u failed - %s\n",
4090 levels[i], nt_errstr(status));
4098 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4099 struct policy_handle *handle, uint32_t rid)
4102 struct samr_OpenUser r;
4103 struct policy_handle user_handle;
4106 printf("Testing OpenUser(%u)\n", rid);
4108 r.in.domain_handle = handle;
4109 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4111 r.out.user_handle = &user_handle;
4113 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4114 if (!NT_STATUS_IS_OK(status)) {
4115 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4119 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4123 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4127 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4131 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4135 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4139 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4146 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4147 struct policy_handle *handle, uint32_t rid)
4150 struct samr_OpenGroup r;
4151 struct policy_handle group_handle;
4154 printf("Testing OpenGroup(%u)\n", rid);
4156 r.in.domain_handle = handle;
4157 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4159 r.out.group_handle = &group_handle;
4161 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4162 if (!NT_STATUS_IS_OK(status)) {
4163 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4167 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4171 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4175 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4179 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4186 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4187 struct policy_handle *handle, uint32_t rid)
4190 struct samr_OpenAlias r;
4191 struct policy_handle alias_handle;
4194 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4196 r.in.domain_handle = handle;
4197 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4199 r.out.alias_handle = &alias_handle;
4201 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4202 if (!NT_STATUS_IS_OK(status)) {
4203 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4207 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4211 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4215 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4219 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4226 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4227 struct policy_handle *handle, uint32_t rid,
4228 uint32_t acct_flag_mask)
4231 struct samr_OpenUser r;
4232 struct samr_QueryUserInfo q;
4233 union samr_UserInfo *info;
4234 struct policy_handle user_handle;
4237 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4239 r.in.domain_handle = handle;
4240 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4242 r.out.user_handle = &user_handle;
4244 status = dcerpc_samr_OpenUser(p, tctx, &r);
4245 if (!NT_STATUS_IS_OK(status)) {
4246 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4250 q.in.user_handle = &user_handle;
4254 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4255 if (!NT_STATUS_IS_OK(status)) {
4256 printf("QueryUserInfo level 16 failed - %s\n",
4260 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4261 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4262 acct_flag_mask, info->info16.acct_flags, rid);
4267 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4274 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4275 struct policy_handle *handle)
4277 NTSTATUS status = STATUS_MORE_ENTRIES;
4278 struct samr_EnumDomainUsers r;
4279 uint32_t mask, resume_handle=0;
4282 struct samr_LookupNames n;
4283 struct samr_LookupRids lr ;
4284 struct lsa_Strings names;
4285 struct samr_Ids rids, types;
4286 struct samr_SamArray *sam = NULL;
4287 uint32_t num_entries = 0;
4289 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4290 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4291 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4294 printf("Testing EnumDomainUsers\n");
4296 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4297 r.in.domain_handle = handle;
4298 r.in.resume_handle = &resume_handle;
4299 r.in.acct_flags = mask = masks[mask_idx];
4300 r.in.max_size = (uint32_t)-1;
4301 r.out.resume_handle = &resume_handle;
4302 r.out.num_entries = &num_entries;
4305 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4306 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4307 !NT_STATUS_IS_OK(status)) {
4308 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4312 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4314 if (sam->count == 0) {
4318 for (i=0;i<sam->count;i++) {
4320 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4323 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4329 printf("Testing LookupNames\n");
4330 n.in.domain_handle = handle;
4331 n.in.num_names = sam->count;
4332 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4334 n.out.types = &types;
4335 for (i=0;i<sam->count;i++) {
4336 n.in.names[i].string = sam->entries[i].name.string;
4338 status = dcerpc_samr_LookupNames(p, tctx, &n);
4339 if (!NT_STATUS_IS_OK(status)) {
4340 printf("LookupNames failed - %s\n", nt_errstr(status));
4345 printf("Testing LookupRids\n");
4346 lr.in.domain_handle = handle;
4347 lr.in.num_rids = sam->count;
4348 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4349 lr.out.names = &names;
4350 lr.out.types = &types;
4351 for (i=0;i<sam->count;i++) {
4352 lr.in.rids[i] = sam->entries[i].idx;
4354 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4355 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4361 try blasting the server with a bunch of sync requests
4363 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4364 struct policy_handle *handle)
4367 struct samr_EnumDomainUsers r;
4368 uint32_t resume_handle=0;
4370 #define ASYNC_COUNT 100
4371 struct rpc_request *req[ASYNC_COUNT];
4373 if (!torture_setting_bool(tctx, "dangerous", false)) {
4374 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4377 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4379 r.in.domain_handle = handle;
4380 r.in.resume_handle = &resume_handle;
4381 r.in.acct_flags = 0;
4382 r.in.max_size = (uint32_t)-1;
4383 r.out.resume_handle = &resume_handle;
4385 for (i=0;i<ASYNC_COUNT;i++) {
4386 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4389 for (i=0;i<ASYNC_COUNT;i++) {
4390 status = dcerpc_ndr_request_recv(req[i]);
4391 if (!NT_STATUS_IS_OK(status)) {
4392 printf("EnumDomainUsers[%d] failed - %s\n",
4393 i, nt_errstr(status));
4398 torture_comment(tctx, "%d async requests OK\n", i);
4403 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4404 struct policy_handle *handle)
4407 struct samr_EnumDomainGroups r;
4408 uint32_t resume_handle=0;
4409 struct samr_SamArray *sam = NULL;
4410 uint32_t num_entries = 0;
4414 printf("Testing EnumDomainGroups\n");
4416 r.in.domain_handle = handle;
4417 r.in.resume_handle = &resume_handle;
4418 r.in.max_size = (uint32_t)-1;
4419 r.out.resume_handle = &resume_handle;
4420 r.out.num_entries = &num_entries;
4423 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4424 if (!NT_STATUS_IS_OK(status)) {
4425 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4433 for (i=0;i<sam->count;i++) {
4434 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4442 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4443 struct policy_handle *handle)
4446 struct samr_EnumDomainAliases r;
4447 uint32_t resume_handle=0;
4448 struct samr_SamArray *sam = NULL;
4449 uint32_t num_entries = 0;
4453 printf("Testing EnumDomainAliases\n");
4455 r.in.domain_handle = handle;
4456 r.in.resume_handle = &resume_handle;
4457 r.in.max_size = (uint32_t)-1;
4459 r.out.num_entries = &num_entries;
4460 r.out.resume_handle = &resume_handle;
4462 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4463 if (!NT_STATUS_IS_OK(status)) {
4464 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4472 for (i=0;i<sam->count;i++) {
4473 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4481 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4482 struct policy_handle *handle)
4485 struct samr_GetDisplayEnumerationIndex r;
4487 uint16_t levels[] = {1, 2, 3, 4, 5};
4488 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4489 struct lsa_String name;
4493 for (i=0;i<ARRAY_SIZE(levels);i++) {
4494 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4496 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4498 r.in.domain_handle = handle;
4499 r.in.level = levels[i];
4503 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4506 !NT_STATUS_IS_OK(status) &&
4507 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4508 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4509 levels[i], nt_errstr(status));
4513 init_lsa_String(&name, "zzzzzzzz");
4515 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4517 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4518 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4519 levels[i], nt_errstr(status));
4527 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4528 struct policy_handle *handle)
4531 struct samr_GetDisplayEnumerationIndex2 r;
4533 uint16_t levels[] = {1, 2, 3, 4, 5};
4534 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4535 struct lsa_String name;
4539 for (i=0;i<ARRAY_SIZE(levels);i++) {
4540 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4542 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4544 r.in.domain_handle = handle;
4545 r.in.level = levels[i];
4549 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4551 !NT_STATUS_IS_OK(status) &&
4552 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4553 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4554 levels[i], nt_errstr(status));
4558 init_lsa_String(&name, "zzzzzzzz");
4560 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4561 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4562 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4563 levels[i], nt_errstr(status));
4571 #define STRING_EQUAL_QUERY(s1, s2, user) \
4572 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4573 /* odd, but valid */ \
4574 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4575 printf("%s mismatch for %s: %s != %s (%s)\n", \
4576 #s1, user.string, s1.string, s2.string, __location__); \
4579 #define INT_EQUAL_QUERY(s1, s2, user) \
4581 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4582 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4586 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4587 struct samr_QueryDisplayInfo *querydisplayinfo,
4588 bool *seen_testuser)
4590 struct samr_OpenUser r;
4591 struct samr_QueryUserInfo q;
4592 union samr_UserInfo *info;
4593 struct policy_handle user_handle;
4596 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4597 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4598 for (i = 0; ; i++) {
4599 switch (querydisplayinfo->in.level) {
4601 if (i >= querydisplayinfo->out.info->info1.count) {
4604 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4607 if (i >= querydisplayinfo->out.info->info2.count) {
4610 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4616 /* Not interested in validating just the account name */
4620 r.out.user_handle = &user_handle;
4622 switch (querydisplayinfo->in.level) {
4625 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4626 if (!NT_STATUS_IS_OK(status)) {
4627 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4632 q.in.user_handle = &user_handle;
4635 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4636 if (!NT_STATUS_IS_OK(status)) {
4637 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4641 switch (querydisplayinfo->in.level) {
4643 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4644 *seen_testuser = true;
4646 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4647 info->info21.full_name, info->info21.account_name);
4648 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4649 info->info21.account_name, info->info21.account_name);
4650 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4651 info->info21.description, info->info21.account_name);
4652 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4653 info->info21.rid, info->info21.account_name);
4654 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4655 info->info21.acct_flags, info->info21.account_name);
4659 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4660 info->info21.account_name, info->info21.account_name);
4661 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4662 info->info21.description, info->info21.account_name);
4663 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4664 info->info21.rid, info->info21.account_name);
4665 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4666 info->info21.acct_flags, info->info21.account_name);
4668 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4669 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4670 info->info21.account_name.string);
4673 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4674 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4675 info->info21.account_name.string,
4676 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4677 info->info21.acct_flags);
4684 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4691 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4692 struct policy_handle *handle)
4695 struct samr_QueryDisplayInfo r;
4696 struct samr_QueryDomainInfo dom_info;
4697 union samr_DomainInfo *info = NULL;
4699 uint16_t levels[] = {1, 2, 3, 4, 5};
4701 bool seen_testuser = false;
4702 uint32_t total_size;
4703 uint32_t returned_size;
4704 union samr_DispInfo disp_info;
4707 for (i=0;i<ARRAY_SIZE(levels);i++) {
4708 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4711 status = STATUS_MORE_ENTRIES;
4712 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4713 r.in.domain_handle = handle;
4714 r.in.level = levels[i];
4715 r.in.max_entries = 2;
4716 r.in.buf_size = (uint32_t)-1;
4717 r.out.total_size = &total_size;
4718 r.out.returned_size = &returned_size;
4719 r.out.info = &disp_info;
4721 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4722 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4723 printf("QueryDisplayInfo level %u failed - %s\n",
4724 levels[i], nt_errstr(status));
4727 switch (r.in.level) {
4729 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4732 r.in.start_idx += r.out.info->info1.count;
4735 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4738 r.in.start_idx += r.out.info->info2.count;
4741 r.in.start_idx += r.out.info->info3.count;
4744 r.in.start_idx += r.out.info->info4.count;
4747 r.in.start_idx += r.out.info->info5.count;
4751 dom_info.in.domain_handle = handle;
4752 dom_info.in.level = 2;
4753 dom_info.out.info = &info;
4755 /* Check number of users returned is correct */
4756 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4757 if (!NT_STATUS_IS_OK(status)) {
4758 printf("QueryDomainInfo level %u failed - %s\n",
4759 r.in.level, nt_errstr(status));
4763 switch (r.in.level) {
4766 if (info->general.num_users < r.in.start_idx) {
4767 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4768 r.in.start_idx, info->general.num_groups,
4769 info->general.domain_name.string);
4772 if (!seen_testuser) {
4773 struct policy_handle user_handle;
4774 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4775 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4776 info->general.domain_name.string);
4778 test_samr_handle_Close(p, mem_ctx, &user_handle);
4784 if (info->general.num_groups != r.in.start_idx) {
4785 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
4786 r.in.start_idx, info->general.num_groups,
4787 info->general.domain_name.string);
4799 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4800 struct policy_handle *handle)
4803 struct samr_QueryDisplayInfo2 r;
4805 uint16_t levels[] = {1, 2, 3, 4, 5};
4807 uint32_t total_size;
4808 uint32_t returned_size;
4809 union samr_DispInfo info;
4811 for (i=0;i<ARRAY_SIZE(levels);i++) {
4812 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
4814 r.in.domain_handle = handle;
4815 r.in.level = levels[i];
4817 r.in.max_entries = 1000;
4818 r.in.buf_size = (uint32_t)-1;
4819 r.out.total_size = &total_size;
4820 r.out.returned_size = &returned_size;
4823 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
4824 if (!NT_STATUS_IS_OK(status)) {
4825 printf("QueryDisplayInfo2 level %u failed - %s\n",
4826 levels[i], nt_errstr(status));
4834 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
4835 struct policy_handle *handle)
4838 struct samr_QueryDisplayInfo3 r;
4840 uint16_t levels[] = {1, 2, 3, 4, 5};
4842 uint32_t total_size;
4843 uint32_t returned_size;
4844 union samr_DispInfo info;
4846 for (i=0;i<ARRAY_SIZE(levels);i++) {
4847 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
4849 r.in.domain_handle = handle;
4850 r.in.level = levels[i];
4852 r.in.max_entries = 1000;
4853 r.in.buf_size = (uint32_t)-1;
4854 r.out.total_size = &total_size;
4855 r.out.returned_size = &returned_size;
4858 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
4859 if (!NT_STATUS_IS_OK(status)) {
4860 printf("QueryDisplayInfo3 level %u failed - %s\n",
4861 levels[i], nt_errstr(status));
4870 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4871 struct policy_handle *handle)
4874 struct samr_QueryDisplayInfo r;
4876 uint32_t total_size;
4877 uint32_t returned_size;
4878 union samr_DispInfo info;
4880 printf("Testing QueryDisplayInfo continuation\n");
4882 r.in.domain_handle = handle;
4885 r.in.max_entries = 1;
4886 r.in.buf_size = (uint32_t)-1;
4887 r.out.total_size = &total_size;
4888 r.out.returned_size = &returned_size;
4892 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4893 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
4894 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
4895 printf("expected idx %d but got %d\n",
4897 r.out.info->info1.entries[0].idx);
4901 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4902 !NT_STATUS_IS_OK(status)) {
4903 printf("QueryDisplayInfo level %u failed - %s\n",
4904 r.in.level, nt_errstr(status));
4909 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
4910 NT_STATUS_IS_OK(status)) &&
4911 *r.out.returned_size != 0);
4916 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
4917 struct policy_handle *handle)
4920 struct samr_QueryDomainInfo r;
4921 union samr_DomainInfo *info = NULL;
4922 struct samr_SetDomainInfo s;
4923 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4924 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
4927 const char *domain_comment = talloc_asprintf(tctx,
4928 "Tortured by Samba4 RPC-SAMR: %s",
4929 timestring(tctx, time(NULL)));
4931 s.in.domain_handle = handle;
4933 s.in.info = talloc(tctx, union samr_DomainInfo);
4935 s.in.info->oem.oem_information.string = domain_comment;
4936 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4937 if (!NT_STATUS_IS_OK(status)) {
4938 printf("SetDomainInfo level %u (set comment) failed - %s\n",
4939 r.in.level, nt_errstr(status));
4943 for (i=0;i<ARRAY_SIZE(levels);i++) {
4944 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4946 r.in.domain_handle = handle;
4947 r.in.level = levels[i];
4950 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4951 if (!NT_STATUS_IS_OK(status)) {
4952 printf("QueryDomainInfo level %u failed - %s\n",
4953 r.in.level, nt_errstr(status));
4958 switch (levels[i]) {
4960 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4961 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4962 levels[i], info->general.oem_information.string, domain_comment);
4965 if (!info->general.primary.string) {
4966 printf("QueryDomainInfo level %u returned no PDC name\n",
4969 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4970 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4971 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4972 levels[i], info->general.primary.string, dcerpc_server_name(p));
4977 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4978 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4979 levels[i], info->oem.oem_information.string, domain_comment);
4984 if (!info->info6.primary.string) {
4985 printf("QueryDomainInfo level %u returned no PDC name\n",
4991 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4992 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4993 levels[i], info->general2.general.oem_information.string, domain_comment);
4999 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5001 s.in.domain_handle = handle;
5002 s.in.level = levels[i];
5005 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5007 if (!NT_STATUS_IS_OK(status)) {
5008 printf("SetDomainInfo level %u failed - %s\n",
5009 r.in.level, nt_errstr(status));
5014 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5015 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5016 r.in.level, nt_errstr(status));
5022 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5023 if (!NT_STATUS_IS_OK(status)) {
5024 printf("QueryDomainInfo level %u failed - %s\n",
5025 r.in.level, nt_errstr(status));
5035 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5036 struct policy_handle *handle)
5039 struct samr_QueryDomainInfo2 r;
5040 union samr_DomainInfo *info = NULL;
5041 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5045 for (i=0;i<ARRAY_SIZE(levels);i++) {
5046 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5048 r.in.domain_handle = handle;
5049 r.in.level = levels[i];
5052 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5053 if (!NT_STATUS_IS_OK(status)) {
5054 printf("QueryDomainInfo2 level %u failed - %s\n",
5055 r.in.level, nt_errstr(status));
5064 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5065 set of group names. */
5066 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5067 struct policy_handle *handle)
5069 struct samr_EnumDomainGroups q1;
5070 struct samr_QueryDisplayInfo q2;
5072 uint32_t resume_handle=0;
5073 struct samr_SamArray *sam = NULL;
5074 uint32_t num_entries = 0;
5077 uint32_t total_size;
5078 uint32_t returned_size;
5079 union samr_DispInfo info;
5082 const char **names = NULL;
5084 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5086 q1.in.domain_handle = handle;
5087 q1.in.resume_handle = &resume_handle;
5089 q1.out.resume_handle = &resume_handle;
5090 q1.out.num_entries = &num_entries;
5093 status = STATUS_MORE_ENTRIES;
5094 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5095 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5097 if (!NT_STATUS_IS_OK(status) &&
5098 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5101 for (i=0; i<*q1.out.num_entries; i++) {
5102 add_string_to_array(tctx,
5103 sam->entries[i].name.string,
5104 &names, &num_names);
5108 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5110 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5112 q2.in.domain_handle = handle;
5114 q2.in.start_idx = 0;
5115 q2.in.max_entries = 5;
5116 q2.in.buf_size = (uint32_t)-1;
5117 q2.out.total_size = &total_size;
5118 q2.out.returned_size = &returned_size;
5119 q2.out.info = &info;
5121 status = STATUS_MORE_ENTRIES;
5122 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5123 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5125 if (!NT_STATUS_IS_OK(status) &&
5126 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5129 for (i=0; i<q2.out.info->info5.count; i++) {
5131 const char *name = q2.out.info->info5.entries[i].account_name.string;
5133 for (j=0; j<num_names; j++) {
5134 if (names[j] == NULL)
5136 if (strequal(names[j], name)) {
5144 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5149 q2.in.start_idx += q2.out.info->info5.count;
5152 if (!NT_STATUS_IS_OK(status)) {
5153 printf("QueryDisplayInfo level 5 failed - %s\n",
5158 for (i=0; i<num_names; i++) {
5159 if (names[i] != NULL) {
5160 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5169 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5170 struct policy_handle *group_handle)
5172 struct samr_DeleteDomainGroup d;
5175 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5177 d.in.group_handle = group_handle;
5178 d.out.group_handle = group_handle;
5180 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5181 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5186 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5187 struct policy_handle *domain_handle)
5189 struct samr_TestPrivateFunctionsDomain r;
5193 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5195 r.in.domain_handle = domain_handle;
5197 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5198 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5203 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5204 struct dom_sid *domain_sid,
5205 struct policy_handle *domain_handle)
5207 struct samr_RidToSid r;
5210 struct dom_sid *calc_sid, *out_sid;
5211 int rids[] = { 0, 42, 512, 10200 };
5214 for (i=0;i<ARRAY_SIZE(rids);i++) {
5215 torture_comment(tctx, "Testing RidToSid\n");
5217 calc_sid = dom_sid_dup(tctx, domain_sid);
5218 r.in.domain_handle = domain_handle;
5220 r.out.sid = &out_sid;
5222 status = dcerpc_samr_RidToSid(p, tctx, &r);
5223 if (!NT_STATUS_IS_OK(status)) {
5224 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5227 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5229 if (!dom_sid_equal(calc_sid, out_sid)) {
5230 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5231 dom_sid_string(tctx, out_sid),
5232 dom_sid_string(tctx, calc_sid));
5241 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5242 struct policy_handle *domain_handle)
5244 struct samr_GetBootKeyInformation r;
5247 uint32_t unknown = 0;
5249 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5251 r.in.domain_handle = domain_handle;
5252 r.out.unknown = &unknown;
5254 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5255 if (!NT_STATUS_IS_OK(status)) {
5256 /* w2k3 seems to fail this sometimes and pass it sometimes */
5257 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5263 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5264 struct policy_handle *domain_handle,
5265 struct policy_handle *group_handle)
5268 struct samr_AddGroupMember r;
5269 struct samr_DeleteGroupMember d;
5270 struct samr_QueryGroupMember q;
5271 struct samr_RidTypeArray *rids = NULL;
5272 struct samr_SetMemberAttributesOfGroup s;
5275 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5276 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5278 r.in.group_handle = group_handle;
5280 r.in.flags = 0; /* ??? */
5282 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5284 d.in.group_handle = group_handle;
5287 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5288 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5290 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5291 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5293 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5294 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5296 if (torture_setting_bool(tctx, "samba4", false)) {
5297 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5299 /* this one is quite strange. I am using random inputs in the
5300 hope of triggering an error that might give us a clue */
5302 s.in.group_handle = group_handle;
5303 s.in.unknown1 = random();
5304 s.in.unknown2 = random();
5306 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5307 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5310 q.in.group_handle = group_handle;
5313 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5314 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5316 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5317 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5319 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5320 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5326 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5327 struct torture_context *tctx,
5328 struct policy_handle *domain_handle,
5329 struct policy_handle *group_handle,
5330 struct dom_sid *domain_sid)
5333 struct samr_CreateDomainGroup r;
5335 struct lsa_String name;
5338 init_lsa_String(&name, TEST_GROUPNAME);
5340 r.in.domain_handle = domain_handle;
5342 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5343 r.out.group_handle = group_handle;
5346 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5348 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5350 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5351 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5352 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5355 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5361 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5362 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5363 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5367 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5369 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5370 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5372 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5376 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5378 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5380 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5381 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5385 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5394 its not totally clear what this does. It seems to accept any sid you like.
5396 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5397 struct torture_context *tctx,
5398 struct policy_handle *domain_handle)
5401 struct samr_RemoveMemberFromForeignDomain r;
5403 r.in.domain_handle = domain_handle;
5404 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5406 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5407 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5414 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5415 struct policy_handle *handle);
5417 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5418 struct policy_handle *handle, struct dom_sid *sid,
5419 enum torture_samr_choice which_ops)
5422 struct samr_OpenDomain r;
5423 struct policy_handle domain_handle;
5424 struct policy_handle alias_handle;
5425 struct policy_handle user_handle;
5426 struct policy_handle group_handle;
5429 ZERO_STRUCT(alias_handle);
5430 ZERO_STRUCT(user_handle);
5431 ZERO_STRUCT(group_handle);
5432 ZERO_STRUCT(domain_handle);
5434 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5436 r.in.connect_handle = handle;
5437 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5439 r.out.domain_handle = &domain_handle;
5441 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5442 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5444 /* run the domain tests with the main handle closed - this tests
5445 the servers reference counting */
5446 ret &= test_samr_handle_Close(p, tctx, handle);
5448 switch (which_ops) {
5449 case TORTURE_SAMR_USER_ATTRIBUTES:
5450 case TORTURE_SAMR_PASSWORDS:
5451 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5452 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5453 /* This test needs 'complex' users to validate */
5454 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5456 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5459 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5460 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5461 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5463 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5466 case TORTURE_SAMR_OTHER:
5467 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5469 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5471 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5472 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5473 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5474 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5475 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5476 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5477 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5478 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5479 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5480 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5481 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5482 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5483 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5485 if (torture_setting_bool(tctx, "samba4", false)) {
5486 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5488 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5489 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5491 ret &= test_GroupList(p, tctx, &domain_handle);
5492 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5493 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5494 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5496 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5501 if (!policy_handle_empty(&user_handle) &&
5502 !test_DeleteUser(p, tctx, &user_handle)) {
5506 if (!policy_handle_empty(&alias_handle) &&
5507 !test_DeleteAlias(p, tctx, &alias_handle)) {
5511 if (!policy_handle_empty(&group_handle) &&
5512 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5516 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5518 /* reconnect the main handle */
5519 ret &= test_Connect(p, tctx, handle);
5522 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5528 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5529 struct policy_handle *handle, const char *domain,
5530 enum torture_samr_choice which_ops)
5533 struct samr_LookupDomain r;
5534 struct dom_sid2 *sid = NULL;
5535 struct lsa_String n1;
5536 struct lsa_String n2;
5539 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5541 /* check for correct error codes */
5542 r.in.connect_handle = handle;
5543 r.in.domain_name = &n2;
5547 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5548 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5550 init_lsa_String(&n2, "xxNODOMAINxx");
5552 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5553 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5555 r.in.connect_handle = handle;
5557 init_lsa_String(&n1, domain);
5558 r.in.domain_name = &n1;
5560 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5561 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5563 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5567 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
5575 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5576 struct policy_handle *handle, enum torture_samr_choice which_ops)
5579 struct samr_EnumDomains r;
5580 uint32_t resume_handle = 0;
5581 uint32_t num_entries = 0;
5582 struct samr_SamArray *sam = NULL;
5586 r.in.connect_handle = handle;
5587 r.in.resume_handle = &resume_handle;
5588 r.in.buf_size = (uint32_t)-1;
5589 r.out.resume_handle = &resume_handle;
5590 r.out.num_entries = &num_entries;
5593 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5594 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5600 for (i=0;i<sam->count;i++) {
5601 if (!test_LookupDomain(p, tctx, handle,
5602 sam->entries[i].name.string, which_ops)) {
5607 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5608 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5614 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5615 struct policy_handle *handle)
5618 struct samr_Connect r;
5619 struct samr_Connect2 r2;
5620 struct samr_Connect3 r3;
5621 struct samr_Connect4 r4;
5622 struct samr_Connect5 r5;
5623 union samr_ConnectInfo info;
5624 struct policy_handle h;
5625 uint32_t level_out = 0;
5626 bool ret = true, got_handle = false;
5628 torture_comment(tctx, "testing samr_Connect\n");
5630 r.in.system_name = 0;
5631 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5632 r.out.connect_handle = &h;
5634 status = dcerpc_samr_Connect(p, tctx, &r);
5635 if (!NT_STATUS_IS_OK(status)) {
5636 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5643 torture_comment(tctx, "testing samr_Connect2\n");
5645 r2.in.system_name = NULL;
5646 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5647 r2.out.connect_handle = &h;
5649 status = dcerpc_samr_Connect2(p, tctx, &r2);
5650 if (!NT_STATUS_IS_OK(status)) {
5651 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5655 test_samr_handle_Close(p, tctx, handle);
5661 torture_comment(tctx, "testing samr_Connect3\n");
5663 r3.in.system_name = NULL;
5665 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5666 r3.out.connect_handle = &h;
5668 status = dcerpc_samr_Connect3(p, tctx, &r3);
5669 if (!NT_STATUS_IS_OK(status)) {
5670 printf("Connect3 failed - %s\n", nt_errstr(status));
5674 test_samr_handle_Close(p, tctx, handle);
5680 torture_comment(tctx, "testing samr_Connect4\n");
5682 r4.in.system_name = "";
5683 r4.in.client_version = 0;
5684 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5685 r4.out.connect_handle = &h;
5687 status = dcerpc_samr_Connect4(p, tctx, &r4);
5688 if (!NT_STATUS_IS_OK(status)) {
5689 printf("Connect4 failed - %s\n", nt_errstr(status));
5693 test_samr_handle_Close(p, tctx, handle);
5699 torture_comment(tctx, "testing samr_Connect5\n");
5701 info.info1.client_version = 0;
5702 info.info1.unknown2 = 0;
5704 r5.in.system_name = "";
5705 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5707 r5.out.level_out = &level_out;
5708 r5.in.info_in = &info;
5709 r5.out.info_out = &info;
5710 r5.out.connect_handle = &h;
5712 status = dcerpc_samr_Connect5(p, tctx, &r5);
5713 if (!NT_STATUS_IS_OK(status)) {
5714 printf("Connect5 failed - %s\n", nt_errstr(status));
5718 test_samr_handle_Close(p, tctx, handle);
5728 bool torture_rpc_samr(struct torture_context *torture)
5731 struct dcerpc_pipe *p;
5733 struct policy_handle handle;
5735 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5736 if (!NT_STATUS_IS_OK(status)) {
5740 ret &= test_Connect(p, torture, &handle);
5742 ret &= test_QuerySecurity(p, torture, &handle);
5744 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
5746 ret &= test_SetDsrmPassword(p, torture, &handle);
5748 ret &= test_Shutdown(p, torture, &handle);
5750 ret &= test_samr_handle_Close(p, torture, &handle);
5756 bool torture_rpc_samr_users(struct torture_context *torture)
5759 struct dcerpc_pipe *p;
5761 struct policy_handle handle;
5763 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5764 if (!NT_STATUS_IS_OK(status)) {
5768 ret &= test_Connect(p, torture, &handle);
5770 ret &= test_QuerySecurity(p, torture, &handle);
5772 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
5774 ret &= test_SetDsrmPassword(p, torture, &handle);
5776 ret &= test_Shutdown(p, torture, &handle);
5778 ret &= test_samr_handle_Close(p, torture, &handle);
5784 bool torture_rpc_samr_passwords(struct torture_context *torture)
5787 struct dcerpc_pipe *p;
5789 struct policy_handle handle;
5791 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5792 if (!NT_STATUS_IS_OK(status)) {
5796 ret &= test_Connect(p, torture, &handle);
5798 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
5800 ret &= test_samr_handle_Close(p, torture, &handle);
5805 bool torture_rpc_samr_passwords_pwdlastset(struct torture_context *torture)
5808 struct dcerpc_pipe *p;
5810 struct policy_handle handle;
5812 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5813 if (!NT_STATUS_IS_OK(status)) {
5817 ret &= test_Connect(p, torture, &handle);
5819 ret &= test_EnumDomains(p, torture, &handle,
5820 TORTURE_SAMR_PASSWORDS_PWDLASTSET);
5822 ret &= test_samr_handle_Close(p, torture, &handle);