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);
412 /* also empty user parameters are allowed */
413 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
414 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
415 SAMR_FIELD_PARAMETERS);
416 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
417 SAMR_FIELD_PARAMETERS);
419 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
420 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
421 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
422 SAMR_FIELD_COUNTRY_CODE);
423 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
424 SAMR_FIELD_COUNTRY_CODE);
426 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
427 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
428 SAMR_FIELD_CODE_PAGE);
429 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
430 SAMR_FIELD_CODE_PAGE);
432 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
433 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
434 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
435 SAMR_FIELD_ACCT_EXPIRY);
436 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
437 SAMR_FIELD_ACCT_EXPIRY);
438 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
439 SAMR_FIELD_ACCT_EXPIRY);
441 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
442 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
443 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
444 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
445 SAMR_FIELD_LOGON_HOURS);
447 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
448 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
449 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
451 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
452 (base_acct_flags | ACB_DISABLED),
453 (base_acct_flags | ACB_DISABLED | user_extra_flags),
456 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
457 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
458 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
459 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
461 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
462 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
463 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
467 /* The 'autolock' flag doesn't stick - check this */
468 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
469 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
470 (base_acct_flags | ACB_DISABLED | user_extra_flags),
473 /* Removing the 'disabled' flag doesn't stick - check this */
474 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
476 (base_acct_flags | ACB_DISABLED | user_extra_flags),
479 /* The 'store plaintext' flag does stick */
480 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
481 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
482 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
484 /* The 'use DES' flag does stick */
485 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
486 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
487 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
489 /* The 'don't require kerberos pre-authentication flag does stick */
490 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
491 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
492 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
494 /* The 'no kerberos PAC required' flag sticks */
495 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
496 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
497 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
500 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
501 (base_acct_flags | ACB_DISABLED),
502 (base_acct_flags | ACB_DISABLED | user_extra_flags),
503 SAMR_FIELD_ACCT_FLAGS);
506 /* these fail with win2003 - it appears you can't set the primary gid?
507 the set succeeds, but the gid isn't changed. Very weird! */
508 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
509 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
510 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
511 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
518 generate a random password for password change tests
520 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
522 size_t len = MAX(8, min_len) + (random() % 6);
523 char *s = generate_random_str(mem_ctx, len);
527 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
529 char *s = samr_rand_pass_silent(mem_ctx, min_len);
530 printf("Generated password '%s'\n", s);
536 generate a random password for password change tests
538 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
541 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
542 generate_random_buffer(password.data, password.length);
544 for (i=0; i < len; i++) {
545 if (((uint16_t *)password.data)[i] == 0) {
546 ((uint16_t *)password.data)[i] = 1;
554 generate a random password for password change tests (fixed length)
556 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
558 char *s = generate_random_str(mem_ctx, len);
559 printf("Generated password '%s'\n", s);
563 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
564 struct policy_handle *handle, char **password)
567 struct samr_SetUserInfo s;
568 union samr_UserInfo u;
570 DATA_BLOB session_key;
572 struct samr_GetUserPwInfo pwp;
573 struct samr_PwInfo info;
574 int policy_min_pw_len = 0;
575 pwp.in.user_handle = handle;
576 pwp.out.info = &info;
578 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
579 if (NT_STATUS_IS_OK(status)) {
580 policy_min_pw_len = pwp.out.info->min_password_length;
582 newpass = samr_rand_pass(tctx, policy_min_pw_len);
584 s.in.user_handle = handle;
588 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
589 u.info24.password_expired = 0;
591 status = dcerpc_fetch_session_key(p, &session_key);
592 if (!NT_STATUS_IS_OK(status)) {
593 printf("SetUserInfo level %u - no session key - %s\n",
594 s.in.level, nt_errstr(status));
598 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
600 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
602 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
603 if (!NT_STATUS_IS_OK(status)) {
604 printf("SetUserInfo level %u failed - %s\n",
605 s.in.level, nt_errstr(status));
615 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
616 struct policy_handle *handle, uint32_t fields_present,
620 struct samr_SetUserInfo s;
621 union samr_UserInfo u;
623 DATA_BLOB session_key;
625 struct samr_GetUserPwInfo pwp;
626 struct samr_PwInfo info;
627 int policy_min_pw_len = 0;
628 pwp.in.user_handle = handle;
629 pwp.out.info = &info;
631 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
632 if (NT_STATUS_IS_OK(status)) {
633 policy_min_pw_len = pwp.out.info->min_password_length;
635 newpass = samr_rand_pass(tctx, policy_min_pw_len);
637 s.in.user_handle = handle;
643 u.info23.info.fields_present = fields_present;
645 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
647 status = dcerpc_fetch_session_key(p, &session_key);
648 if (!NT_STATUS_IS_OK(status)) {
649 printf("SetUserInfo level %u - no session key - %s\n",
650 s.in.level, nt_errstr(status));
654 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
656 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
658 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
659 if (!NT_STATUS_IS_OK(status)) {
660 printf("SetUserInfo level %u failed - %s\n",
661 s.in.level, nt_errstr(status));
667 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
669 status = dcerpc_fetch_session_key(p, &session_key);
670 if (!NT_STATUS_IS_OK(status)) {
671 printf("SetUserInfo level %u - no session key - %s\n",
672 s.in.level, nt_errstr(status));
676 /* This should break the key nicely */
677 session_key.length--;
678 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
680 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
682 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
683 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
684 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
685 s.in.level, nt_errstr(status));
693 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
694 struct policy_handle *handle, bool makeshort,
698 struct samr_SetUserInfo s;
699 union samr_UserInfo u;
701 DATA_BLOB session_key;
702 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
703 uint8_t confounder[16];
705 struct MD5Context ctx;
706 struct samr_GetUserPwInfo pwp;
707 struct samr_PwInfo info;
708 int policy_min_pw_len = 0;
709 pwp.in.user_handle = handle;
710 pwp.out.info = &info;
712 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
713 if (NT_STATUS_IS_OK(status)) {
714 policy_min_pw_len = pwp.out.info->min_password_length;
716 if (makeshort && policy_min_pw_len) {
717 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
719 newpass = samr_rand_pass(tctx, policy_min_pw_len);
722 s.in.user_handle = handle;
726 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
727 u.info26.password_expired = 0;
729 status = dcerpc_fetch_session_key(p, &session_key);
730 if (!NT_STATUS_IS_OK(status)) {
731 printf("SetUserInfo level %u - no session key - %s\n",
732 s.in.level, nt_errstr(status));
736 generate_random_buffer((uint8_t *)confounder, 16);
739 MD5Update(&ctx, confounder, 16);
740 MD5Update(&ctx, session_key.data, session_key.length);
741 MD5Final(confounded_session_key.data, &ctx);
743 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
744 memcpy(&u.info26.password.data[516], confounder, 16);
746 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
748 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
749 if (!NT_STATUS_IS_OK(status)) {
750 printf("SetUserInfo level %u failed - %s\n",
751 s.in.level, nt_errstr(status));
757 /* This should break the key nicely */
758 confounded_session_key.data[0]++;
760 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
761 memcpy(&u.info26.password.data[516], confounder, 16);
763 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
765 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
766 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
767 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
768 s.in.level, nt_errstr(status));
777 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
778 struct policy_handle *handle, uint32_t fields_present,
782 struct samr_SetUserInfo s;
783 union samr_UserInfo u;
785 DATA_BLOB session_key;
786 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
787 struct MD5Context ctx;
788 uint8_t confounder[16];
790 struct samr_GetUserPwInfo pwp;
791 struct samr_PwInfo info;
792 int policy_min_pw_len = 0;
793 pwp.in.user_handle = handle;
794 pwp.out.info = &info;
796 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
797 if (NT_STATUS_IS_OK(status)) {
798 policy_min_pw_len = pwp.out.info->min_password_length;
800 newpass = samr_rand_pass(tctx, policy_min_pw_len);
802 s.in.user_handle = handle;
808 u.info25.info.fields_present = fields_present;
810 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
812 status = dcerpc_fetch_session_key(p, &session_key);
813 if (!NT_STATUS_IS_OK(status)) {
814 printf("SetUserInfo level %u - no session key - %s\n",
815 s.in.level, nt_errstr(status));
819 generate_random_buffer((uint8_t *)confounder, 16);
822 MD5Update(&ctx, confounder, 16);
823 MD5Update(&ctx, session_key.data, session_key.length);
824 MD5Final(confounded_session_key.data, &ctx);
826 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
827 memcpy(&u.info25.password.data[516], confounder, 16);
829 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
831 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
832 if (!NT_STATUS_IS_OK(status)) {
833 printf("SetUserInfo level %u failed - %s\n",
834 s.in.level, nt_errstr(status));
840 /* This should break the key nicely */
841 confounded_session_key.data[0]++;
843 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
844 memcpy(&u.info25.password.data[516], confounder, 16);
846 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
848 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
849 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
850 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
851 s.in.level, nt_errstr(status));
858 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
859 struct policy_handle *handle, char **password)
862 struct samr_SetUserInfo s;
863 union samr_UserInfo u;
865 DATA_BLOB session_key;
867 struct samr_GetUserPwInfo pwp;
868 struct samr_PwInfo info;
869 int policy_min_pw_len = 0;
870 uint8_t lm_hash[16], nt_hash[16];
872 pwp.in.user_handle = handle;
873 pwp.out.info = &info;
875 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
876 if (NT_STATUS_IS_OK(status)) {
877 policy_min_pw_len = pwp.out.info->min_password_length;
879 newpass = samr_rand_pass(tctx, policy_min_pw_len);
881 s.in.user_handle = handle;
887 u.info18.nt_pwd_active = true;
888 u.info18.lm_pwd_active = true;
890 E_md4hash(newpass, nt_hash);
891 E_deshash(newpass, lm_hash);
893 status = dcerpc_fetch_session_key(p, &session_key);
894 if (!NT_STATUS_IS_OK(status)) {
895 printf("SetUserInfo level %u - no session key - %s\n",
896 s.in.level, nt_errstr(status));
902 in = data_blob_const(nt_hash, 16);
903 out = data_blob_talloc_zero(tctx, 16);
904 sess_crypt_blob(&out, &in, &session_key, true);
905 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
909 in = data_blob_const(lm_hash, 16);
910 out = data_blob_talloc_zero(tctx, 16);
911 sess_crypt_blob(&out, &in, &session_key, true);
912 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
915 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
917 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
918 if (!NT_STATUS_IS_OK(status)) {
919 printf("SetUserInfo level %u failed - %s\n",
920 s.in.level, nt_errstr(status));
929 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
930 struct policy_handle *handle, uint32_t fields_present,
934 struct samr_SetUserInfo s;
935 union samr_UserInfo u;
937 DATA_BLOB session_key;
939 struct samr_GetUserPwInfo pwp;
940 struct samr_PwInfo info;
941 int policy_min_pw_len = 0;
942 uint8_t lm_hash[16], nt_hash[16];
944 pwp.in.user_handle = handle;
945 pwp.out.info = &info;
947 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
948 if (NT_STATUS_IS_OK(status)) {
949 policy_min_pw_len = pwp.out.info->min_password_length;
951 newpass = samr_rand_pass(tctx, policy_min_pw_len);
953 s.in.user_handle = handle;
957 E_md4hash(newpass, nt_hash);
958 E_deshash(newpass, lm_hash);
962 u.info21.fields_present = fields_present;
964 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
965 u.info21.lm_owf_password.length = 16;
966 u.info21.lm_owf_password.size = 16;
967 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
968 u.info21.lm_password_set = true;
971 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
972 u.info21.nt_owf_password.length = 16;
973 u.info21.nt_owf_password.size = 16;
974 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
975 u.info21.nt_password_set = true;
978 status = dcerpc_fetch_session_key(p, &session_key);
979 if (!NT_STATUS_IS_OK(status)) {
980 printf("SetUserInfo level %u - no session key - %s\n",
981 s.in.level, nt_errstr(status));
985 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
987 in = data_blob_const(u.info21.lm_owf_password.array,
988 u.info21.lm_owf_password.length);
989 out = data_blob_talloc_zero(tctx, 16);
990 sess_crypt_blob(&out, &in, &session_key, true);
991 u.info21.lm_owf_password.array = (uint16_t *)out.data;
994 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
996 in = data_blob_const(u.info21.nt_owf_password.array,
997 u.info21.nt_owf_password.length);
998 out = data_blob_talloc_zero(tctx, 16);
999 sess_crypt_blob(&out, &in, &session_key, true);
1000 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1003 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1005 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1006 if (!NT_STATUS_IS_OK(status)) {
1007 printf("SetUserInfo level %u failed - %s\n",
1008 s.in.level, nt_errstr(status));
1011 *password = newpass;
1014 /* try invalid length */
1015 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1017 u.info21.nt_owf_password.length++;
1019 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1021 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1022 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1023 s.in.level, nt_errstr(status));
1028 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1030 u.info21.lm_owf_password.length++;
1032 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1034 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1035 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1036 s.in.level, nt_errstr(status));
1044 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1045 struct torture_context *tctx,
1046 struct policy_handle *handle,
1048 uint32_t fields_present,
1049 char **password, uint8_t password_expired,
1051 bool *matched_expected_error)
1054 NTSTATUS expected_error = NT_STATUS_OK;
1055 struct samr_SetUserInfo s;
1056 struct samr_SetUserInfo2 s2;
1057 union samr_UserInfo u;
1059 DATA_BLOB session_key;
1060 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1061 struct MD5Context ctx;
1062 uint8_t confounder[16];
1064 struct samr_GetUserPwInfo pwp;
1065 struct samr_PwInfo info;
1066 int policy_min_pw_len = 0;
1067 const char *comment = NULL;
1068 uint8_t lm_hash[16], nt_hash[16];
1070 pwp.in.user_handle = handle;
1071 pwp.out.info = &info;
1073 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1074 if (NT_STATUS_IS_OK(status)) {
1075 policy_min_pw_len = pwp.out.info->min_password_length;
1077 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1080 s2.in.user_handle = handle;
1082 s2.in.level = level;
1084 s.in.user_handle = handle;
1089 if (fields_present & SAMR_FIELD_COMMENT) {
1090 comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
1097 E_md4hash(newpass, nt_hash);
1098 E_deshash(newpass, lm_hash);
1100 u.info18.nt_pwd_active = true;
1101 u.info18.lm_pwd_active = true;
1102 u.info18.password_expired = password_expired;
1104 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1105 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1109 E_md4hash(newpass, nt_hash);
1110 E_deshash(newpass, lm_hash);
1112 u.info21.fields_present = fields_present;
1113 u.info21.password_expired = password_expired;
1114 u.info21.comment.string = comment;
1116 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1117 u.info21.lm_owf_password.length = 16;
1118 u.info21.lm_owf_password.size = 16;
1119 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1120 u.info21.lm_password_set = true;
1123 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1124 u.info21.nt_owf_password.length = 16;
1125 u.info21.nt_owf_password.size = 16;
1126 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1127 u.info21.nt_password_set = true;
1132 u.info23.info.fields_present = fields_present;
1133 u.info23.info.password_expired = password_expired;
1134 u.info23.info.comment.string = comment;
1136 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1140 u.info24.password_expired = password_expired;
1142 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1146 u.info25.info.fields_present = fields_present;
1147 u.info25.info.password_expired = password_expired;
1148 u.info25.info.comment.string = comment;
1150 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1154 u.info26.password_expired = password_expired;
1156 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1161 status = dcerpc_fetch_session_key(p, &session_key);
1162 if (!NT_STATUS_IS_OK(status)) {
1163 printf("SetUserInfo level %u - no session key - %s\n",
1164 s.in.level, nt_errstr(status));
1168 generate_random_buffer((uint8_t *)confounder, 16);
1171 MD5Update(&ctx, confounder, 16);
1172 MD5Update(&ctx, session_key.data, session_key.length);
1173 MD5Final(confounded_session_key.data, &ctx);
1179 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1180 out = data_blob_talloc_zero(tctx, 16);
1181 sess_crypt_blob(&out, &in, &session_key, true);
1182 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1186 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1187 out = data_blob_talloc_zero(tctx, 16);
1188 sess_crypt_blob(&out, &in, &session_key, true);
1189 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1194 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1196 in = data_blob_const(u.info21.lm_owf_password.array,
1197 u.info21.lm_owf_password.length);
1198 out = data_blob_talloc_zero(tctx, 16);
1199 sess_crypt_blob(&out, &in, &session_key, true);
1200 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1202 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1204 in = data_blob_const(u.info21.nt_owf_password.array,
1205 u.info21.nt_owf_password.length);
1206 out = data_blob_talloc_zero(tctx, 16);
1207 sess_crypt_blob(&out, &in, &session_key, true);
1208 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1212 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1215 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1218 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1219 memcpy(&u.info25.password.data[516], confounder, 16);
1222 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1223 memcpy(&u.info26.password.data[516], confounder, 16);
1228 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1230 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 if (fields_present == 0) {
1235 expected_error = NT_STATUS_INVALID_PARAMETER;
1237 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1238 expected_error = NT_STATUS_ACCESS_DENIED;
1242 if (!NT_STATUS_IS_OK(expected_error)) {
1244 torture_assert_ntstatus_equal(tctx,
1246 expected_error, "SetUserInfo2 failed");
1248 torture_assert_ntstatus_equal(tctx,
1250 expected_error, "SetUserInfo failed");
1252 *matched_expected_error = true;
1256 if (!NT_STATUS_IS_OK(status)) {
1257 printf("SetUserInfo%s level %u failed - %s\n",
1258 use_setinfo2 ? "2":"", level, nt_errstr(status));
1261 *password = newpass;
1267 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1268 struct policy_handle *handle)
1271 struct samr_SetAliasInfo r;
1272 struct samr_QueryAliasInfo q;
1273 union samr_AliasInfo *info;
1274 uint16_t levels[] = {2, 3};
1278 /* Ignoring switch level 1, as that includes the number of members for the alias
1279 * and setting this to a wrong value might have negative consequences
1282 for (i=0;i<ARRAY_SIZE(levels);i++) {
1283 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1285 r.in.alias_handle = handle;
1286 r.in.level = levels[i];
1287 r.in.info = talloc(tctx, union samr_AliasInfo);
1288 switch (r.in.level) {
1289 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1290 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1291 "Test Description, should test I18N as well"); break;
1292 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1295 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1296 if (!NT_STATUS_IS_OK(status)) {
1297 printf("SetAliasInfo level %u failed - %s\n",
1298 levels[i], nt_errstr(status));
1302 q.in.alias_handle = handle;
1303 q.in.level = levels[i];
1306 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1307 if (!NT_STATUS_IS_OK(status)) {
1308 printf("QueryAliasInfo level %u failed - %s\n",
1309 levels[i], nt_errstr(status));
1317 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1318 struct policy_handle *user_handle)
1320 struct samr_GetGroupsForUser r;
1321 struct samr_RidWithAttributeArray *rids = NULL;
1324 torture_comment(tctx, "testing GetGroupsForUser\n");
1326 r.in.user_handle = user_handle;
1329 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1330 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1336 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1337 struct lsa_String *domain_name)
1340 struct samr_GetDomPwInfo r;
1341 struct samr_PwInfo info;
1343 r.in.domain_name = domain_name;
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 = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
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 = "\\\\__NONAME__";
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");
1363 r.in.domain_name->string = "\\\\Builtin";
1364 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1366 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1367 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1372 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1373 struct policy_handle *handle)
1376 struct samr_GetUserPwInfo r;
1377 struct samr_PwInfo info;
1379 torture_comment(tctx, "Testing GetUserPwInfo\n");
1381 r.in.user_handle = handle;
1384 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1385 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1390 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1391 struct policy_handle *domain_handle, const char *name,
1395 struct samr_LookupNames n;
1396 struct lsa_String sname[2];
1397 struct samr_Ids rids, types;
1399 init_lsa_String(&sname[0], name);
1401 n.in.domain_handle = domain_handle;
1405 n.out.types = &types;
1406 status = dcerpc_samr_LookupNames(p, tctx, &n);
1407 if (NT_STATUS_IS_OK(status)) {
1408 *rid = n.out.rids->ids[0];
1413 init_lsa_String(&sname[1], "xxNONAMExx");
1415 status = dcerpc_samr_LookupNames(p, tctx, &n);
1416 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1417 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1418 if (NT_STATUS_IS_OK(status)) {
1419 return NT_STATUS_UNSUCCESSFUL;
1425 status = dcerpc_samr_LookupNames(p, tctx, &n);
1426 if (!NT_STATUS_IS_OK(status)) {
1427 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1431 init_lsa_String(&sname[0], "xxNONAMExx");
1433 status = dcerpc_samr_LookupNames(p, tctx, &n);
1434 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1435 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1436 if (NT_STATUS_IS_OK(status)) {
1437 return NT_STATUS_UNSUCCESSFUL;
1442 init_lsa_String(&sname[0], "xxNONAMExx");
1443 init_lsa_String(&sname[1], "xxNONAME2xx");
1445 status = dcerpc_samr_LookupNames(p, tctx, &n);
1446 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1447 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1448 if (NT_STATUS_IS_OK(status)) {
1449 return NT_STATUS_UNSUCCESSFUL;
1454 return NT_STATUS_OK;
1457 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1458 struct policy_handle *domain_handle,
1459 const char *name, struct policy_handle *user_handle)
1462 struct samr_OpenUser r;
1465 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1466 if (!NT_STATUS_IS_OK(status)) {
1470 r.in.domain_handle = domain_handle;
1471 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1473 r.out.user_handle = user_handle;
1474 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1475 if (!NT_STATUS_IS_OK(status)) {
1476 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1483 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1484 struct policy_handle *handle)
1487 struct samr_ChangePasswordUser r;
1489 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1490 struct policy_handle user_handle;
1491 char *oldpass = "test";
1492 char *newpass = "test2";
1493 uint8_t old_nt_hash[16], new_nt_hash[16];
1494 uint8_t old_lm_hash[16], new_lm_hash[16];
1496 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1497 if (!NT_STATUS_IS_OK(status)) {
1501 printf("Testing ChangePasswordUser for user 'testuser'\n");
1503 printf("old password: %s\n", oldpass);
1504 printf("new password: %s\n", newpass);
1506 E_md4hash(oldpass, old_nt_hash);
1507 E_md4hash(newpass, new_nt_hash);
1508 E_deshash(oldpass, old_lm_hash);
1509 E_deshash(newpass, new_lm_hash);
1511 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1512 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1513 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1514 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1515 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1516 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1518 r.in.handle = &user_handle;
1519 r.in.lm_present = 1;
1520 r.in.old_lm_crypted = &hash1;
1521 r.in.new_lm_crypted = &hash2;
1522 r.in.nt_present = 1;
1523 r.in.old_nt_crypted = &hash3;
1524 r.in.new_nt_crypted = &hash4;
1525 r.in.cross1_present = 1;
1526 r.in.nt_cross = &hash5;
1527 r.in.cross2_present = 1;
1528 r.in.lm_cross = &hash6;
1530 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1531 if (!NT_STATUS_IS_OK(status)) {
1532 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1536 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1544 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1545 const char *acct_name,
1546 struct policy_handle *handle, char **password)
1549 struct samr_ChangePasswordUser r;
1551 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1552 struct policy_handle user_handle;
1554 uint8_t old_nt_hash[16], new_nt_hash[16];
1555 uint8_t old_lm_hash[16], new_lm_hash[16];
1556 bool changed = true;
1559 struct samr_GetUserPwInfo pwp;
1560 struct samr_PwInfo info;
1561 int policy_min_pw_len = 0;
1563 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1564 if (!NT_STATUS_IS_OK(status)) {
1567 pwp.in.user_handle = &user_handle;
1568 pwp.out.info = &info;
1570 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1571 if (NT_STATUS_IS_OK(status)) {
1572 policy_min_pw_len = pwp.out.info->min_password_length;
1574 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1576 torture_comment(tctx, "Testing ChangePasswordUser\n");
1578 torture_assert(tctx, *password != NULL,
1579 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1581 oldpass = *password;
1583 E_md4hash(oldpass, old_nt_hash);
1584 E_md4hash(newpass, new_nt_hash);
1585 E_deshash(oldpass, old_lm_hash);
1586 E_deshash(newpass, new_lm_hash);
1588 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1589 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1590 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1591 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1592 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1593 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1595 r.in.user_handle = &user_handle;
1596 r.in.lm_present = 1;
1597 /* Break the LM hash */
1599 r.in.old_lm_crypted = &hash1;
1600 r.in.new_lm_crypted = &hash2;
1601 r.in.nt_present = 1;
1602 r.in.old_nt_crypted = &hash3;
1603 r.in.new_nt_crypted = &hash4;
1604 r.in.cross1_present = 1;
1605 r.in.nt_cross = &hash5;
1606 r.in.cross2_present = 1;
1607 r.in.lm_cross = &hash6;
1609 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1610 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1611 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1613 /* Unbreak the LM hash */
1616 r.in.user_handle = &user_handle;
1617 r.in.lm_present = 1;
1618 r.in.old_lm_crypted = &hash1;
1619 r.in.new_lm_crypted = &hash2;
1620 /* Break the NT hash */
1622 r.in.nt_present = 1;
1623 r.in.old_nt_crypted = &hash3;
1624 r.in.new_nt_crypted = &hash4;
1625 r.in.cross1_present = 1;
1626 r.in.nt_cross = &hash5;
1627 r.in.cross2_present = 1;
1628 r.in.lm_cross = &hash6;
1630 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1631 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1632 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1634 /* Unbreak the NT hash */
1637 r.in.user_handle = &user_handle;
1638 r.in.lm_present = 1;
1639 r.in.old_lm_crypted = &hash1;
1640 r.in.new_lm_crypted = &hash2;
1641 r.in.nt_present = 1;
1642 r.in.old_nt_crypted = &hash3;
1643 r.in.new_nt_crypted = &hash4;
1644 r.in.cross1_present = 1;
1645 r.in.nt_cross = &hash5;
1646 r.in.cross2_present = 1;
1647 /* Break the LM cross */
1649 r.in.lm_cross = &hash6;
1651 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1652 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1653 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1657 /* Unbreak the LM cross */
1660 r.in.user_handle = &user_handle;
1661 r.in.lm_present = 1;
1662 r.in.old_lm_crypted = &hash1;
1663 r.in.new_lm_crypted = &hash2;
1664 r.in.nt_present = 1;
1665 r.in.old_nt_crypted = &hash3;
1666 r.in.new_nt_crypted = &hash4;
1667 r.in.cross1_present = 1;
1668 /* Break the NT cross */
1670 r.in.nt_cross = &hash5;
1671 r.in.cross2_present = 1;
1672 r.in.lm_cross = &hash6;
1674 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1675 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1676 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1680 /* Unbreak the NT cross */
1684 /* Reset the hashes to not broken values */
1685 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1686 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1687 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1688 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1689 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1690 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1692 r.in.user_handle = &user_handle;
1693 r.in.lm_present = 1;
1694 r.in.old_lm_crypted = &hash1;
1695 r.in.new_lm_crypted = &hash2;
1696 r.in.nt_present = 1;
1697 r.in.old_nt_crypted = &hash3;
1698 r.in.new_nt_crypted = &hash4;
1699 r.in.cross1_present = 1;
1700 r.in.nt_cross = &hash5;
1701 r.in.cross2_present = 0;
1702 r.in.lm_cross = NULL;
1704 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1705 if (NT_STATUS_IS_OK(status)) {
1707 *password = newpass;
1708 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1709 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1714 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1716 E_md4hash(oldpass, old_nt_hash);
1717 E_md4hash(newpass, new_nt_hash);
1718 E_deshash(oldpass, old_lm_hash);
1719 E_deshash(newpass, new_lm_hash);
1722 /* Reset the hashes to not broken values */
1723 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1724 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1725 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1726 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1727 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1728 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1730 r.in.user_handle = &user_handle;
1731 r.in.lm_present = 1;
1732 r.in.old_lm_crypted = &hash1;
1733 r.in.new_lm_crypted = &hash2;
1734 r.in.nt_present = 1;
1735 r.in.old_nt_crypted = &hash3;
1736 r.in.new_nt_crypted = &hash4;
1737 r.in.cross1_present = 0;
1738 r.in.nt_cross = NULL;
1739 r.in.cross2_present = 1;
1740 r.in.lm_cross = &hash6;
1742 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1743 if (NT_STATUS_IS_OK(status)) {
1745 *password = newpass;
1746 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1747 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1752 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1754 E_md4hash(oldpass, old_nt_hash);
1755 E_md4hash(newpass, new_nt_hash);
1756 E_deshash(oldpass, old_lm_hash);
1757 E_deshash(newpass, new_lm_hash);
1760 /* Reset the hashes to not broken values */
1761 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1762 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1763 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1764 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1765 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1766 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1768 r.in.user_handle = &user_handle;
1769 r.in.lm_present = 1;
1770 r.in.old_lm_crypted = &hash1;
1771 r.in.new_lm_crypted = &hash2;
1772 r.in.nt_present = 1;
1773 r.in.old_nt_crypted = &hash3;
1774 r.in.new_nt_crypted = &hash4;
1775 r.in.cross1_present = 1;
1776 r.in.nt_cross = &hash5;
1777 r.in.cross2_present = 1;
1778 r.in.lm_cross = &hash6;
1780 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1781 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1782 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1783 } else if (!NT_STATUS_IS_OK(status)) {
1784 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1788 *password = newpass;
1791 r.in.user_handle = &user_handle;
1792 r.in.lm_present = 1;
1793 r.in.old_lm_crypted = &hash1;
1794 r.in.new_lm_crypted = &hash2;
1795 r.in.nt_present = 1;
1796 r.in.old_nt_crypted = &hash3;
1797 r.in.new_nt_crypted = &hash4;
1798 r.in.cross1_present = 1;
1799 r.in.nt_cross = &hash5;
1800 r.in.cross2_present = 1;
1801 r.in.lm_cross = &hash6;
1804 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1805 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1806 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1807 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1808 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1814 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1822 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1823 const char *acct_name,
1824 struct policy_handle *handle, char **password)
1827 struct samr_OemChangePasswordUser2 r;
1829 struct samr_Password lm_verifier;
1830 struct samr_CryptPassword lm_pass;
1831 struct lsa_AsciiString server, account, account_bad;
1834 uint8_t old_lm_hash[16], new_lm_hash[16];
1836 struct samr_GetDomPwInfo dom_pw_info;
1837 struct samr_PwInfo info;
1838 int policy_min_pw_len = 0;
1840 struct lsa_String domain_name;
1842 domain_name.string = "";
1843 dom_pw_info.in.domain_name = &domain_name;
1844 dom_pw_info.out.info = &info;
1846 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1848 torture_assert(tctx, *password != NULL,
1849 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1851 oldpass = *password;
1853 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1854 if (NT_STATUS_IS_OK(status)) {
1855 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1858 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1860 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1861 account.string = acct_name;
1863 E_deshash(oldpass, old_lm_hash);
1864 E_deshash(newpass, new_lm_hash);
1866 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1867 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1868 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1870 r.in.server = &server;
1871 r.in.account = &account;
1872 r.in.password = &lm_pass;
1873 r.in.hash = &lm_verifier;
1875 /* Break the verification */
1876 lm_verifier.hash[0]++;
1878 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1880 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1881 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1882 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1887 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1888 /* Break the old password */
1890 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1891 /* unbreak it for the next operation */
1893 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1895 r.in.server = &server;
1896 r.in.account = &account;
1897 r.in.password = &lm_pass;
1898 r.in.hash = &lm_verifier;
1900 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1902 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1903 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1904 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1909 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1910 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1912 r.in.server = &server;
1913 r.in.account = &account;
1914 r.in.password = &lm_pass;
1917 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1919 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1920 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1921 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1926 /* This shouldn't be a valid name */
1927 account_bad.string = TEST_ACCOUNT_NAME "XX";
1928 r.in.account = &account_bad;
1930 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1932 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1933 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1938 /* This shouldn't be a valid name */
1939 account_bad.string = TEST_ACCOUNT_NAME "XX";
1940 r.in.account = &account_bad;
1941 r.in.password = &lm_pass;
1942 r.in.hash = &lm_verifier;
1944 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1946 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1947 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1952 /* This shouldn't be a valid name */
1953 account_bad.string = TEST_ACCOUNT_NAME "XX";
1954 r.in.account = &account_bad;
1955 r.in.password = NULL;
1956 r.in.hash = &lm_verifier;
1958 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1960 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1961 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1966 E_deshash(oldpass, old_lm_hash);
1967 E_deshash(newpass, new_lm_hash);
1969 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1970 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1971 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1973 r.in.server = &server;
1974 r.in.account = &account;
1975 r.in.password = &lm_pass;
1976 r.in.hash = &lm_verifier;
1978 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1979 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1980 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1981 } else if (!NT_STATUS_IS_OK(status)) {
1982 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1985 *password = newpass;
1992 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1993 const char *acct_name,
1995 char *newpass, bool allow_password_restriction)
1998 struct samr_ChangePasswordUser2 r;
2000 struct lsa_String server, account;
2001 struct samr_CryptPassword nt_pass, lm_pass;
2002 struct samr_Password nt_verifier, lm_verifier;
2004 uint8_t old_nt_hash[16], new_nt_hash[16];
2005 uint8_t old_lm_hash[16], new_lm_hash[16];
2007 struct samr_GetDomPwInfo dom_pw_info;
2008 struct samr_PwInfo info;
2010 struct lsa_String domain_name;
2012 domain_name.string = "";
2013 dom_pw_info.in.domain_name = &domain_name;
2014 dom_pw_info.out.info = &info;
2016 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2018 torture_assert(tctx, *password != NULL,
2019 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2020 oldpass = *password;
2023 int policy_min_pw_len = 0;
2024 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2025 if (NT_STATUS_IS_OK(status)) {
2026 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2029 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2032 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2033 init_lsa_String(&account, acct_name);
2035 E_md4hash(oldpass, old_nt_hash);
2036 E_md4hash(newpass, new_nt_hash);
2038 E_deshash(oldpass, old_lm_hash);
2039 E_deshash(newpass, new_lm_hash);
2041 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2042 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2043 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2045 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2046 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2047 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2049 r.in.server = &server;
2050 r.in.account = &account;
2051 r.in.nt_password = &nt_pass;
2052 r.in.nt_verifier = &nt_verifier;
2054 r.in.lm_password = &lm_pass;
2055 r.in.lm_verifier = &lm_verifier;
2057 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2058 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2059 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2060 } else if (!NT_STATUS_IS_OK(status)) {
2061 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2064 *password = newpass;
2071 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2072 const char *account_string,
2073 int policy_min_pw_len,
2075 const char *newpass,
2076 NTTIME last_password_change,
2077 bool handle_reject_reason)
2080 struct samr_ChangePasswordUser3 r;
2082 struct lsa_String server, account, account_bad;
2083 struct samr_CryptPassword nt_pass, lm_pass;
2084 struct samr_Password nt_verifier, lm_verifier;
2086 uint8_t old_nt_hash[16], new_nt_hash[16];
2087 uint8_t old_lm_hash[16], new_lm_hash[16];
2089 struct samr_DomInfo1 *dominfo = NULL;
2090 struct samr_ChangeReject *reject = NULL;
2092 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2094 if (newpass == NULL) {
2096 if (policy_min_pw_len == 0) {
2097 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2099 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2101 } while (check_password_quality(newpass) == false);
2103 torture_comment(tctx, "Using password '%s'\n", newpass);
2106 torture_assert(tctx, *password != NULL,
2107 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2109 oldpass = *password;
2110 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2111 init_lsa_String(&account, account_string);
2113 E_md4hash(oldpass, old_nt_hash);
2114 E_md4hash(newpass, new_nt_hash);
2116 E_deshash(oldpass, old_lm_hash);
2117 E_deshash(newpass, new_lm_hash);
2119 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2120 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2121 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2123 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2124 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2125 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2127 /* Break the verification */
2128 nt_verifier.hash[0]++;
2130 r.in.server = &server;
2131 r.in.account = &account;
2132 r.in.nt_password = &nt_pass;
2133 r.in.nt_verifier = &nt_verifier;
2135 r.in.lm_password = &lm_pass;
2136 r.in.lm_verifier = &lm_verifier;
2137 r.in.password3 = NULL;
2138 r.out.dominfo = &dominfo;
2139 r.out.reject = &reject;
2141 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2142 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2143 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2144 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2149 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2150 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2151 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2153 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2154 /* Break the NT hash */
2156 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2157 /* Unbreak it again */
2159 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2161 r.in.server = &server;
2162 r.in.account = &account;
2163 r.in.nt_password = &nt_pass;
2164 r.in.nt_verifier = &nt_verifier;
2166 r.in.lm_password = &lm_pass;
2167 r.in.lm_verifier = &lm_verifier;
2168 r.in.password3 = NULL;
2169 r.out.dominfo = &dominfo;
2170 r.out.reject = &reject;
2172 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2173 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2174 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2175 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2180 /* This shouldn't be a valid name */
2181 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2183 r.in.account = &account_bad;
2184 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2185 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2186 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2191 E_md4hash(oldpass, old_nt_hash);
2192 E_md4hash(newpass, new_nt_hash);
2194 E_deshash(oldpass, old_lm_hash);
2195 E_deshash(newpass, new_lm_hash);
2197 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2198 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2199 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2201 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2202 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2203 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2205 r.in.server = &server;
2206 r.in.account = &account;
2207 r.in.nt_password = &nt_pass;
2208 r.in.nt_verifier = &nt_verifier;
2210 r.in.lm_password = &lm_pass;
2211 r.in.lm_verifier = &lm_verifier;
2212 r.in.password3 = NULL;
2213 r.out.dominfo = &dominfo;
2214 r.out.reject = &reject;
2216 unix_to_nt_time(&t, time(NULL));
2218 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2220 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2223 && handle_reject_reason
2224 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2225 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2227 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2228 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2229 SAMR_REJECT_OTHER, reject->reason);
2234 /* We tested the order of precendence which is as follows:
2243 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2244 (last_password_change + dominfo->min_password_age > t)) {
2246 if (reject->reason != SAMR_REJECT_OTHER) {
2247 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2248 SAMR_REJECT_OTHER, reject->reason);
2252 } else if ((dominfo->min_password_length > 0) &&
2253 (strlen(newpass) < dominfo->min_password_length)) {
2255 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2256 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2257 SAMR_REJECT_TOO_SHORT, reject->reason);
2261 } else if ((dominfo->password_history_length > 0) &&
2262 strequal(oldpass, newpass)) {
2264 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2265 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2266 SAMR_REJECT_IN_HISTORY, reject->reason);
2269 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2271 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2272 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2273 SAMR_REJECT_COMPLEXITY, reject->reason);
2279 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2280 /* retry with adjusted size */
2281 return test_ChangePasswordUser3(p, tctx, account_string,
2282 dominfo->min_password_length,
2283 password, NULL, 0, false);
2287 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2288 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2289 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2290 SAMR_REJECT_OTHER, reject->reason);
2293 /* Perhaps the server has a 'min password age' set? */
2296 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2297 *password = talloc_strdup(tctx, newpass);
2303 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2304 const char *account_string,
2305 struct policy_handle *handle,
2309 struct samr_ChangePasswordUser3 r;
2310 struct samr_SetUserInfo s;
2311 union samr_UserInfo u;
2312 DATA_BLOB session_key;
2313 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2314 uint8_t confounder[16];
2315 struct MD5Context ctx;
2318 struct lsa_String server, account;
2319 struct samr_CryptPassword nt_pass;
2320 struct samr_Password nt_verifier;
2321 DATA_BLOB new_random_pass;
2324 uint8_t old_nt_hash[16], new_nt_hash[16];
2326 struct samr_DomInfo1 *dominfo = NULL;
2327 struct samr_ChangeReject *reject = NULL;
2329 new_random_pass = samr_very_rand_pass(tctx, 128);
2331 torture_assert(tctx, *password != NULL,
2332 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2334 oldpass = *password;
2335 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2336 init_lsa_String(&account, account_string);
2338 s.in.user_handle = handle;
2344 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2346 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2348 status = dcerpc_fetch_session_key(p, &session_key);
2349 if (!NT_STATUS_IS_OK(status)) {
2350 printf("SetUserInfo level %u - no session key - %s\n",
2351 s.in.level, nt_errstr(status));
2355 generate_random_buffer((uint8_t *)confounder, 16);
2358 MD5Update(&ctx, confounder, 16);
2359 MD5Update(&ctx, session_key.data, session_key.length);
2360 MD5Final(confounded_session_key.data, &ctx);
2362 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2363 memcpy(&u.info25.password.data[516], confounder, 16);
2365 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2367 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2368 if (!NT_STATUS_IS_OK(status)) {
2369 printf("SetUserInfo level %u failed - %s\n",
2370 s.in.level, nt_errstr(status));
2374 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2376 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2378 new_random_pass = samr_very_rand_pass(tctx, 128);
2380 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2382 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2383 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2384 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2386 r.in.server = &server;
2387 r.in.account = &account;
2388 r.in.nt_password = &nt_pass;
2389 r.in.nt_verifier = &nt_verifier;
2391 r.in.lm_password = NULL;
2392 r.in.lm_verifier = NULL;
2393 r.in.password3 = NULL;
2394 r.out.dominfo = &dominfo;
2395 r.out.reject = &reject;
2397 unix_to_nt_time(&t, time(NULL));
2399 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2401 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2402 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2403 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2404 SAMR_REJECT_OTHER, reject->reason);
2407 /* Perhaps the server has a 'min password age' set? */
2409 } else if (!NT_STATUS_IS_OK(status)) {
2410 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2414 newpass = samr_rand_pass(tctx, 128);
2416 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2418 E_md4hash(newpass, new_nt_hash);
2420 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2421 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2422 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2424 r.in.server = &server;
2425 r.in.account = &account;
2426 r.in.nt_password = &nt_pass;
2427 r.in.nt_verifier = &nt_verifier;
2429 r.in.lm_password = NULL;
2430 r.in.lm_verifier = NULL;
2431 r.in.password3 = NULL;
2432 r.out.dominfo = &dominfo;
2433 r.out.reject = &reject;
2435 unix_to_nt_time(&t, time(NULL));
2437 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2439 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2440 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2441 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2442 SAMR_REJECT_OTHER, reject->reason);
2445 /* Perhaps the server has a 'min password age' set? */
2448 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2449 *password = talloc_strdup(tctx, newpass);
2456 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2457 struct policy_handle *alias_handle)
2459 struct samr_GetMembersInAlias r;
2460 struct lsa_SidArray sids;
2463 torture_comment(tctx, "Testing GetMembersInAlias\n");
2465 r.in.alias_handle = alias_handle;
2468 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2469 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2474 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2475 struct policy_handle *alias_handle,
2476 const struct dom_sid *domain_sid)
2478 struct samr_AddAliasMember r;
2479 struct samr_DeleteAliasMember d;
2481 struct dom_sid *sid;
2483 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2485 torture_comment(tctx, "testing AddAliasMember\n");
2486 r.in.alias_handle = alias_handle;
2489 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2490 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2492 d.in.alias_handle = alias_handle;
2495 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2496 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2501 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2502 struct policy_handle *alias_handle)
2504 struct samr_AddMultipleMembersToAlias a;
2505 struct samr_RemoveMultipleMembersFromAlias r;
2507 struct lsa_SidArray sids;
2509 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2510 a.in.alias_handle = alias_handle;
2514 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2516 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2517 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2518 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2520 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2521 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2524 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2525 r.in.alias_handle = alias_handle;
2528 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2529 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2531 /* strange! removing twice doesn't give any error */
2532 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2533 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2535 /* but removing an alias that isn't there does */
2536 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2538 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2539 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2544 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2545 struct policy_handle *user_handle)
2547 struct samr_TestPrivateFunctionsUser r;
2550 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2552 r.in.user_handle = user_handle;
2554 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2555 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2560 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2561 struct torture_context *tctx,
2562 struct policy_handle *handle,
2567 uint16_t levels[] = { /* 3, */ 5, 21 };
2569 NTTIME pwdlastset3 = 0;
2570 NTTIME pwdlastset5 = 0;
2571 NTTIME pwdlastset21 = 0;
2573 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2574 use_info2 ? "2":"");
2576 for (i=0; i<ARRAY_SIZE(levels); i++) {
2578 struct samr_QueryUserInfo r;
2579 struct samr_QueryUserInfo2 r2;
2580 union samr_UserInfo *info;
2583 r2.in.user_handle = handle;
2584 r2.in.level = levels[i];
2585 r2.out.info = &info;
2586 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2589 r.in.user_handle = handle;
2590 r.in.level = levels[i];
2592 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2595 if (!NT_STATUS_IS_OK(status) &&
2596 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2597 printf("QueryUserInfo%s level %u failed - %s\n",
2598 use_info2 ? "2":"", levels[i], nt_errstr(status));
2602 switch (levels[i]) {
2604 pwdlastset3 = info->info3.last_password_change;
2607 pwdlastset5 = info->info5.last_password_change;
2610 pwdlastset21 = info->info21.last_password_change;
2616 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2617 "pwdlastset mixup"); */
2618 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2619 "pwdlastset mixup");
2621 *pwdlastset = pwdlastset21;
2623 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2628 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2629 struct torture_context *tctx,
2630 struct policy_handle *handle,
2632 uint32_t fields_present,
2633 uint8_t password_expired,
2634 bool *matched_expected_error,
2637 bool use_queryinfo2,
2640 const char *fields = NULL;
2647 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2654 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2655 "(password_expired: %d) %s\n",
2656 use_setinfo2 ? "2":"", level, password_expired,
2657 fields ? fields : "");
2659 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2664 matched_expected_error)) {
2668 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2677 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2678 struct torture_context *tctx,
2679 uint32_t acct_flags,
2680 struct policy_handle *handle,
2683 int s = 0, q = 0, f = 0, l = 0, z = 0;
2686 bool set_levels[] = { false, true };
2687 bool query_levels[] = { false, true };
2688 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2689 uint32_t nonzeros[] = { 1, 24 };
2690 uint32_t fields_present[] = {
2692 SAMR_FIELD_EXPIRED_FLAG,
2693 SAMR_FIELD_LAST_PWD_CHANGE,
2694 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2696 SAMR_FIELD_NT_PASSWORD_PRESENT,
2697 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2698 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2699 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2700 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2701 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2702 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2705 if (torture_setting_bool(tctx, "samba3", false)) {
2707 printf("Samba3 has second granularity, setting delay to: %d\n",
2711 /* set to 1 to enable testing for all possible opcode
2712 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2715 #define TEST_SET_LEVELS 1
2716 #define TEST_QUERY_LEVELS 1
2718 for (l=0; l<ARRAY_SIZE(levels); l++) {
2719 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2720 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2721 #ifdef TEST_SET_LEVELS
2722 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2724 #ifdef TEST_QUERY_LEVELS
2725 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2727 NTTIME pwdlastset_old = 0;
2728 NTTIME pwdlastset_new = 0;
2729 bool matched_expected_error = false;
2731 torture_comment(tctx, "------------------------------\n"
2732 "Testing pwdLastSet attribute for flags: 0x%08x "
2733 "(s: %d (l: %d), q: %d)\n",
2734 acct_flags, s, levels[l], q);
2738 /* set a password and force password change (pwdlastset 0) by
2739 * setting the password expired flag to a non-0 value */
2741 if (!test_SetPassword_level(p, tctx, handle,
2745 &matched_expected_error,
2753 if (matched_expected_error == true) {
2754 /* skipping on expected failure */
2758 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2759 * set without the SAMR_FIELD_EXPIRED_FLAG */
2761 switch (levels[l]) {
2765 if ((pwdlastset_new != 0) &&
2766 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2767 torture_comment(tctx, "not considering a non-0 "
2768 "pwdLastSet as a an error as the "
2769 "SAMR_FIELD_EXPIRED_FLAG has not "
2774 if (pwdlastset_new != 0) {
2775 torture_warning(tctx, "pwdLastSet test failed: "
2776 "expected pwdLastSet 0 but got %lld\n",
2783 switch (levels[l]) {
2787 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2788 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2789 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2790 (pwdlastset_old >= pwdlastset_new)) {
2791 torture_warning(tctx, "pwdlastset not increasing\n");
2796 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2797 (pwdlastset_old >= pwdlastset_new)) {
2798 torture_warning(tctx, "pwdlastset not increasing\n");
2808 /* set a password, pwdlastset needs to get updated (increased
2809 * value), password_expired value used here is 0 */
2811 if (!test_SetPassword_level(p, tctx, handle,
2815 &matched_expected_error,
2823 /* when a password has been changed, pwdlastset must not be 0 afterwards
2824 * and must be larger then the old value */
2826 switch (levels[l]) {
2831 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2832 * password has been changed, old and new pwdlastset
2833 * need to be the same value */
2835 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
2836 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2837 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2839 torture_assert_int_equal(tctx, pwdlastset_old,
2840 pwdlastset_new, "pwdlastset must be equal");
2844 if (pwdlastset_old >= pwdlastset_new) {
2845 torture_warning(tctx, "pwdLastSet test failed: "
2846 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2847 pwdlastset_old, pwdlastset_new);
2850 if (pwdlastset_new == 0) {
2851 torture_warning(tctx, "pwdLastSet test failed: "
2852 "expected non-0 pwdlastset, got: %lld\n",
2858 switch (levels[l]) {
2862 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2863 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2864 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2865 (pwdlastset_old >= pwdlastset_new)) {
2866 torture_warning(tctx, "pwdlastset not increasing\n");
2871 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2872 (pwdlastset_old >= pwdlastset_new)) {
2873 torture_warning(tctx, "pwdlastset not increasing\n");
2879 pwdlastset_old = pwdlastset_new;
2885 /* set a password, pwdlastset needs to get updated (increased
2886 * value), password_expired value used here is 0 */
2888 if (!test_SetPassword_level(p, tctx, handle,
2892 &matched_expected_error,
2900 /* when a password has been changed, pwdlastset must not be 0 afterwards
2901 * and must be larger then the old value */
2903 switch (levels[l]) {
2908 /* if no password has been changed, old and new pwdlastset
2909 * need to be the same value */
2911 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2912 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2914 torture_assert_int_equal(tctx, pwdlastset_old,
2915 pwdlastset_new, "pwdlastset must be equal");
2919 if (pwdlastset_old >= pwdlastset_new) {
2920 torture_warning(tctx, "pwdLastSet test failed: "
2921 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
2922 pwdlastset_old, pwdlastset_new);
2925 if (pwdlastset_new == 0) {
2926 torture_warning(tctx, "pwdLastSet test failed: "
2927 "expected non-0 pwdlastset, got: %lld\n",
2935 /* set a password and force password change (pwdlastset 0) by
2936 * setting the password expired flag to a non-0 value */
2938 if (!test_SetPassword_level(p, tctx, handle,
2942 &matched_expected_error,
2950 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2951 * set without the SAMR_FIELD_EXPIRED_FLAG */
2953 switch (levels[l]) {
2957 if ((pwdlastset_new != 0) &&
2958 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2959 torture_comment(tctx, "not considering a non-0 "
2960 "pwdLastSet as a an error as the "
2961 "SAMR_FIELD_EXPIRED_FLAG has not "
2966 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
2967 * password has been changed, old and new pwdlastset
2968 * need to be the same value */
2970 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
2971 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2972 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
2974 torture_assert_int_equal(tctx, pwdlastset_old,
2975 pwdlastset_new, "pwdlastset must be equal");
2980 if (pwdlastset_old == pwdlastset_new) {
2981 torture_warning(tctx, "pwdLastSet test failed: "
2982 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
2983 pwdlastset_old, pwdlastset_new);
2987 if (pwdlastset_new != 0) {
2988 torture_warning(tctx, "pwdLastSet test failed: "
2989 "expected pwdLastSet 0, got %lld\n",
2996 switch (levels[l]) {
3000 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3001 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3002 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3003 (pwdlastset_old >= pwdlastset_new)) {
3004 torture_warning(tctx, "pwdlastset not increasing\n");
3009 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3010 (pwdlastset_old >= pwdlastset_new)) {
3011 torture_warning(tctx, "pwdlastset not increasing\n");
3017 /* if the level we are testing does not have a fields_present
3018 * field, skip all fields present tests by setting f to to
3020 switch (levels[l]) {
3024 f = ARRAY_SIZE(fields_present);
3028 #ifdef TEST_QUERY_LEVELS
3031 #ifdef TEST_SET_LEVELS
3034 } /* fields present */
3038 #undef TEST_SET_LEVELS
3039 #undef TEST_QUERY_LEVELS
3044 static bool test_user_ops(struct dcerpc_pipe *p,
3045 struct torture_context *tctx,
3046 struct policy_handle *user_handle,
3047 struct policy_handle *domain_handle,
3048 uint32_t base_acct_flags,
3049 const char *base_acct_name, enum torture_samr_choice which_ops)
3051 char *password = NULL;
3052 struct samr_QueryUserInfo q;
3053 union samr_UserInfo *info;
3059 const uint32_t password_fields[] = {
3060 SAMR_FIELD_NT_PASSWORD_PRESENT,
3061 SAMR_FIELD_LM_PASSWORD_PRESENT,
3062 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3066 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3067 if (!NT_STATUS_IS_OK(status)) {
3071 switch (which_ops) {
3072 case TORTURE_SAMR_USER_ATTRIBUTES:
3073 if (!test_QuerySecurity(p, tctx, user_handle)) {
3077 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3081 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3085 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3090 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3094 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3098 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3102 case TORTURE_SAMR_PASSWORDS:
3103 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3104 char simple_pass[9];
3105 char *v = generate_random_str(tctx, 1);
3107 ZERO_STRUCT(simple_pass);
3108 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3110 printf("Testing machine account password policy rules\n");
3112 /* Workstation trust accounts don't seem to need to honour password quality policy */
3113 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3117 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3121 /* reset again, to allow another 'user' password change */
3122 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3126 /* Try a 'short' password */
3127 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3131 /* Try a compleatly random password */
3132 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3137 for (i = 0; password_fields[i]; i++) {
3138 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3142 /* check it was set right */
3143 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3148 for (i = 0; password_fields[i]; i++) {
3149 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3153 /* check it was set right */
3154 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3159 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3163 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3167 if (torture_setting_bool(tctx, "samba4", false)) {
3168 printf("skipping Set Password level 18 and 21 against Samba4\n");
3171 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3175 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3179 for (i = 0; password_fields[i]; i++) {
3181 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3182 /* we need to skip as that would break
3183 * the ChangePasswordUser3 verify */
3187 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3191 /* check it was set right */
3192 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3198 q.in.user_handle = user_handle;
3202 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3203 if (!NT_STATUS_IS_OK(status)) {
3204 printf("QueryUserInfo level %u failed - %s\n",
3205 q.in.level, nt_errstr(status));
3208 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3209 if ((info->info5.acct_flags) != expected_flags) {
3210 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3211 info->info5.acct_flags,
3215 if (info->info5.rid != rid) {
3216 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3217 info->info5.rid, rid);
3224 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3226 /* test last password change timestamp behaviour */
3227 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3228 user_handle, &password)) {
3233 torture_comment(tctx, "pwdLastSet test succeeded\n");
3235 torture_warning(tctx, "pwdLastSet test failed\n");
3240 case TORTURE_SAMR_OTHER:
3241 /* We just need the account to exist */
3247 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3248 struct policy_handle *alias_handle,
3249 const struct dom_sid *domain_sid)
3253 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3257 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3261 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3265 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3269 if (torture_setting_bool(tctx, "samba4", false)) {
3270 printf("skipping MultipleMembers Alias tests against Samba4\n");
3274 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3282 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3283 struct policy_handle *user_handle)
3285 struct samr_DeleteUser d;
3287 torture_comment(tctx, "Testing DeleteUser\n");
3289 d.in.user_handle = user_handle;
3290 d.out.user_handle = user_handle;
3292 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3293 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3298 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3299 struct policy_handle *handle, const char *name)
3302 struct samr_DeleteUser d;
3303 struct policy_handle user_handle;
3306 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3307 if (!NT_STATUS_IS_OK(status)) {
3311 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3312 if (!NT_STATUS_IS_OK(status)) {
3316 d.in.user_handle = &user_handle;
3317 d.out.user_handle = &user_handle;
3318 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3319 if (!NT_STATUS_IS_OK(status)) {
3326 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3331 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3332 struct policy_handle *handle, const char *name)
3335 struct samr_OpenGroup r;
3336 struct samr_DeleteDomainGroup d;
3337 struct policy_handle group_handle;
3340 status = test_LookupName(p, mem_ctx, handle, name, &rid);
3341 if (!NT_STATUS_IS_OK(status)) {
3345 r.in.domain_handle = handle;
3346 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3348 r.out.group_handle = &group_handle;
3349 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3350 if (!NT_STATUS_IS_OK(status)) {
3354 d.in.group_handle = &group_handle;
3355 d.out.group_handle = &group_handle;
3356 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3357 if (!NT_STATUS_IS_OK(status)) {
3364 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3369 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3370 struct policy_handle *domain_handle, const char *name)
3373 struct samr_OpenAlias r;
3374 struct samr_DeleteDomAlias d;
3375 struct policy_handle alias_handle;
3378 printf("testing DeleteAlias_byname\n");
3380 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3381 if (!NT_STATUS_IS_OK(status)) {
3385 r.in.domain_handle = domain_handle;
3386 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3388 r.out.alias_handle = &alias_handle;
3389 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3390 if (!NT_STATUS_IS_OK(status)) {
3394 d.in.alias_handle = &alias_handle;
3395 d.out.alias_handle = &alias_handle;
3396 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3397 if (!NT_STATUS_IS_OK(status)) {
3404 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3408 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3409 struct policy_handle *alias_handle)
3411 struct samr_DeleteDomAlias d;
3414 printf("Testing DeleteAlias\n");
3416 d.in.alias_handle = alias_handle;
3417 d.out.alias_handle = alias_handle;
3419 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3420 if (!NT_STATUS_IS_OK(status)) {
3421 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3428 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3429 struct policy_handle *domain_handle,
3430 struct policy_handle *alias_handle,
3431 const struct dom_sid *domain_sid)
3434 struct samr_CreateDomAlias r;
3435 struct lsa_String name;
3439 init_lsa_String(&name, TEST_ALIASNAME);
3440 r.in.domain_handle = domain_handle;
3441 r.in.alias_name = &name;
3442 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3443 r.out.alias_handle = alias_handle;
3446 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3448 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3450 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3451 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3452 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3455 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
3461 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3462 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3465 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3468 if (!NT_STATUS_IS_OK(status)) {
3469 printf("CreateAlias failed - %s\n", nt_errstr(status));
3473 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3480 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3481 const char *acct_name,
3482 struct policy_handle *domain_handle, char **password)
3490 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3494 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3498 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3502 /* test what happens when setting the old password again */
3503 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3508 char simple_pass[9];
3509 char *v = generate_random_str(mem_ctx, 1);
3511 ZERO_STRUCT(simple_pass);
3512 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3514 /* test what happens when picking a simple password */
3515 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3520 /* set samr_SetDomainInfo level 1 with min_length 5 */
3522 struct samr_QueryDomainInfo r;
3523 union samr_DomainInfo *info = NULL;
3524 struct samr_SetDomainInfo s;
3525 uint16_t len_old, len;
3526 uint32_t pwd_prop_old;
3527 int64_t min_pwd_age_old;
3532 r.in.domain_handle = domain_handle;
3536 printf("testing samr_QueryDomainInfo level 1\n");
3537 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3538 if (!NT_STATUS_IS_OK(status)) {
3542 s.in.domain_handle = domain_handle;
3546 /* remember the old min length, so we can reset it */
3547 len_old = s.in.info->info1.min_password_length;
3548 s.in.info->info1.min_password_length = len;
3549 pwd_prop_old = s.in.info->info1.password_properties;
3550 /* turn off password complexity checks for this test */
3551 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3553 min_pwd_age_old = s.in.info->info1.min_password_age;
3554 s.in.info->info1.min_password_age = 0;
3556 printf("testing samr_SetDomainInfo level 1\n");
3557 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3558 if (!NT_STATUS_IS_OK(status)) {
3562 printf("calling test_ChangePasswordUser3 with too short password\n");
3564 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3568 s.in.info->info1.min_password_length = len_old;
3569 s.in.info->info1.password_properties = pwd_prop_old;
3570 s.in.info->info1.min_password_age = min_pwd_age_old;
3572 printf("testing samr_SetDomainInfo level 1\n");
3573 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3574 if (!NT_STATUS_IS_OK(status)) {
3582 struct samr_OpenUser r;
3583 struct samr_QueryUserInfo q;
3584 union samr_UserInfo *info;
3585 struct samr_LookupNames n;
3586 struct policy_handle user_handle;
3587 struct samr_Ids rids, types;
3589 n.in.domain_handle = domain_handle;
3591 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3592 n.in.names[0].string = acct_name;
3594 n.out.types = &types;
3596 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3597 if (!NT_STATUS_IS_OK(status)) {
3598 printf("LookupNames failed - %s\n", nt_errstr(status));
3602 r.in.domain_handle = domain_handle;
3603 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3604 r.in.rid = n.out.rids->ids[0];
3605 r.out.user_handle = &user_handle;
3607 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3608 if (!NT_STATUS_IS_OK(status)) {
3609 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3613 q.in.user_handle = &user_handle;
3617 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3618 if (!NT_STATUS_IS_OK(status)) {
3619 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3623 printf("calling test_ChangePasswordUser3 with too early password change\n");
3625 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
3626 info->info5.last_password_change, true)) {
3631 /* we change passwords twice - this has the effect of verifying
3632 they were changed correctly for the final call */
3633 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3637 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3644 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3645 struct policy_handle *domain_handle,
3646 struct policy_handle *user_handle_out,
3647 struct dom_sid *domain_sid,
3648 enum torture_samr_choice which_ops)
3651 TALLOC_CTX *user_ctx;
3654 struct samr_CreateUser r;
3655 struct samr_QueryUserInfo q;
3656 union samr_UserInfo *info;
3657 struct samr_DeleteUser d;
3660 /* This call creates a 'normal' account - check that it really does */
3661 const uint32_t acct_flags = ACB_NORMAL;
3662 struct lsa_String name;
3665 struct policy_handle user_handle;
3666 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3667 init_lsa_String(&name, TEST_ACCOUNT_NAME);
3669 r.in.domain_handle = domain_handle;
3670 r.in.account_name = &name;
3671 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3672 r.out.user_handle = &user_handle;
3675 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3677 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3679 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3680 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3681 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3684 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3690 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3691 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3692 talloc_free(user_ctx);
3695 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3697 if (!NT_STATUS_IS_OK(status)) {
3698 talloc_free(user_ctx);
3699 printf("CreateUser failed - %s\n", nt_errstr(status));
3702 q.in.user_handle = &user_handle;
3706 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3707 if (!NT_STATUS_IS_OK(status)) {
3708 printf("QueryUserInfo level %u failed - %s\n",
3709 q.in.level, nt_errstr(status));
3712 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3713 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3714 info->info16.acct_flags,
3720 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3721 acct_flags, name.string, which_ops)) {
3725 if (user_handle_out) {
3726 *user_handle_out = user_handle;
3728 printf("Testing DeleteUser (createuser test)\n");
3730 d.in.user_handle = &user_handle;
3731 d.out.user_handle = &user_handle;
3733 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3734 if (!NT_STATUS_IS_OK(status)) {
3735 printf("DeleteUser failed - %s\n", nt_errstr(status));
3742 talloc_free(user_ctx);
3748 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3749 struct policy_handle *domain_handle,
3750 struct dom_sid *domain_sid,
3751 enum torture_samr_choice which_ops)
3754 struct samr_CreateUser2 r;
3755 struct samr_QueryUserInfo q;
3756 union samr_UserInfo *info;
3757 struct samr_DeleteUser d;
3758 struct policy_handle user_handle;
3760 struct lsa_String name;
3765 uint32_t acct_flags;
3766 const char *account_name;
3768 } account_types[] = {
3769 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3770 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3771 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3772 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3773 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3774 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3775 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3776 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3777 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3778 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
3779 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3780 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
3781 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3782 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3783 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
3786 for (i = 0; account_types[i].account_name; i++) {
3787 TALLOC_CTX *user_ctx;
3788 uint32_t acct_flags = account_types[i].acct_flags;
3789 uint32_t access_granted;
3790 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3791 init_lsa_String(&name, account_types[i].account_name);
3793 r.in.domain_handle = domain_handle;
3794 r.in.account_name = &name;
3795 r.in.acct_flags = acct_flags;
3796 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3797 r.out.user_handle = &user_handle;
3798 r.out.access_granted = &access_granted;
3801 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
3803 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3805 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3806 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3807 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3810 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
3817 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3818 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3819 talloc_free(user_ctx);
3823 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
3826 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
3827 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
3828 nt_errstr(status), nt_errstr(account_types[i].nt_status));
3832 if (NT_STATUS_IS_OK(status)) {
3833 q.in.user_handle = &user_handle;
3837 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3838 if (!NT_STATUS_IS_OK(status)) {
3839 printf("QueryUserInfo level %u failed - %s\n",
3840 q.in.level, nt_errstr(status));
3843 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3844 if (acct_flags == ACB_NORMAL) {
3845 expected_flags |= ACB_PW_EXPIRED;
3847 if ((info->info5.acct_flags) != expected_flags) {
3848 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3849 info->info5.acct_flags,
3853 switch (acct_flags) {
3855 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
3856 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
3857 DOMAIN_RID_DCS, info->info5.primary_gid);
3862 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
3863 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
3864 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
3869 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
3870 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
3871 DOMAIN_RID_USERS, info->info5.primary_gid);
3878 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
3879 acct_flags, name.string, which_ops)) {
3883 printf("Testing DeleteUser (createuser2 test)\n");
3885 d.in.user_handle = &user_handle;
3886 d.out.user_handle = &user_handle;
3888 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3889 if (!NT_STATUS_IS_OK(status)) {
3890 printf("DeleteUser failed - %s\n", nt_errstr(status));
3894 talloc_free(user_ctx);
3900 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3901 struct policy_handle *handle)
3904 struct samr_QueryAliasInfo r;
3905 union samr_AliasInfo *info;
3906 uint16_t levels[] = {1, 2, 3};
3910 for (i=0;i<ARRAY_SIZE(levels);i++) {
3911 printf("Testing QueryAliasInfo level %u\n", levels[i]);
3913 r.in.alias_handle = handle;
3914 r.in.level = levels[i];
3917 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
3918 if (!NT_STATUS_IS_OK(status)) {
3919 printf("QueryAliasInfo level %u failed - %s\n",
3920 levels[i], nt_errstr(status));
3928 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3929 struct policy_handle *handle)
3932 struct samr_QueryGroupInfo r;
3933 union samr_GroupInfo *info;
3934 uint16_t levels[] = {1, 2, 3, 4, 5};
3938 for (i=0;i<ARRAY_SIZE(levels);i++) {
3939 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3941 r.in.group_handle = handle;
3942 r.in.level = levels[i];
3945 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3946 if (!NT_STATUS_IS_OK(status)) {
3947 printf("QueryGroupInfo level %u failed - %s\n",
3948 levels[i], nt_errstr(status));
3956 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3957 struct policy_handle *handle)
3960 struct samr_QueryGroupMember r;
3961 struct samr_RidTypeArray *rids = NULL;
3964 printf("Testing QueryGroupMember\n");
3966 r.in.group_handle = handle;
3969 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3970 if (!NT_STATUS_IS_OK(status)) {
3971 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3979 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3980 struct policy_handle *handle)
3983 struct samr_QueryGroupInfo r;
3984 union samr_GroupInfo *info;
3985 struct samr_SetGroupInfo s;
3986 uint16_t levels[] = {1, 2, 3, 4};
3987 uint16_t set_ok[] = {0, 1, 1, 1};
3991 for (i=0;i<ARRAY_SIZE(levels);i++) {
3992 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3994 r.in.group_handle = handle;
3995 r.in.level = levels[i];
3998 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3999 if (!NT_STATUS_IS_OK(status)) {
4000 printf("QueryGroupInfo level %u failed - %s\n",
4001 levels[i], nt_errstr(status));
4005 printf("Testing SetGroupInfo level %u\n", levels[i]);
4007 s.in.group_handle = handle;
4008 s.in.level = levels[i];
4009 s.in.info = *r.out.info;
4012 /* disabled this, as it changes the name only from the point of view of samr,
4013 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4014 the name is still reserved, so creating the old name fails, but deleting by the old name
4016 if (s.in.level == 2) {
4017 init_lsa_String(&s.in.info->string, "NewName");
4021 if (s.in.level == 4) {
4022 init_lsa_String(&s.in.info->description, "test description");
4025 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4027 if (!NT_STATUS_IS_OK(status)) {
4028 printf("SetGroupInfo level %u failed - %s\n",
4029 r.in.level, nt_errstr(status));
4034 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4035 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4036 r.in.level, nt_errstr(status));
4046 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4047 struct policy_handle *handle)
4050 struct samr_QueryUserInfo r;
4051 union samr_UserInfo *info;
4052 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4053 11, 12, 13, 14, 16, 17, 20, 21};
4057 for (i=0;i<ARRAY_SIZE(levels);i++) {
4058 printf("Testing QueryUserInfo level %u\n", levels[i]);
4060 r.in.user_handle = handle;
4061 r.in.level = levels[i];
4064 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4065 if (!NT_STATUS_IS_OK(status)) {
4066 printf("QueryUserInfo level %u failed - %s\n",
4067 levels[i], nt_errstr(status));
4075 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4076 struct policy_handle *handle)
4079 struct samr_QueryUserInfo2 r;
4080 union samr_UserInfo *info;
4081 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4082 11, 12, 13, 14, 16, 17, 20, 21};
4086 for (i=0;i<ARRAY_SIZE(levels);i++) {
4087 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4089 r.in.user_handle = handle;
4090 r.in.level = levels[i];
4093 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4094 if (!NT_STATUS_IS_OK(status)) {
4095 printf("QueryUserInfo2 level %u failed - %s\n",
4096 levels[i], nt_errstr(status));
4104 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4105 struct policy_handle *handle, uint32_t rid)
4108 struct samr_OpenUser r;
4109 struct policy_handle user_handle;
4112 printf("Testing OpenUser(%u)\n", rid);
4114 r.in.domain_handle = handle;
4115 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4117 r.out.user_handle = &user_handle;
4119 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4120 if (!NT_STATUS_IS_OK(status)) {
4121 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4125 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4129 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4133 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4137 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4141 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4145 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4152 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4153 struct policy_handle *handle, uint32_t rid)
4156 struct samr_OpenGroup r;
4157 struct policy_handle group_handle;
4160 printf("Testing OpenGroup(%u)\n", rid);
4162 r.in.domain_handle = handle;
4163 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4165 r.out.group_handle = &group_handle;
4167 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4168 if (!NT_STATUS_IS_OK(status)) {
4169 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4173 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4177 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4181 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4185 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4192 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4193 struct policy_handle *handle, uint32_t rid)
4196 struct samr_OpenAlias r;
4197 struct policy_handle alias_handle;
4200 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4202 r.in.domain_handle = handle;
4203 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4205 r.out.alias_handle = &alias_handle;
4207 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4208 if (!NT_STATUS_IS_OK(status)) {
4209 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4213 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4217 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4221 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4225 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4232 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4233 struct policy_handle *handle, uint32_t rid,
4234 uint32_t acct_flag_mask)
4237 struct samr_OpenUser r;
4238 struct samr_QueryUserInfo q;
4239 union samr_UserInfo *info;
4240 struct policy_handle user_handle;
4243 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4245 r.in.domain_handle = handle;
4246 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4248 r.out.user_handle = &user_handle;
4250 status = dcerpc_samr_OpenUser(p, tctx, &r);
4251 if (!NT_STATUS_IS_OK(status)) {
4252 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4256 q.in.user_handle = &user_handle;
4260 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4261 if (!NT_STATUS_IS_OK(status)) {
4262 printf("QueryUserInfo level 16 failed - %s\n",
4266 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4267 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4268 acct_flag_mask, info->info16.acct_flags, rid);
4273 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4280 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4281 struct policy_handle *handle)
4283 NTSTATUS status = STATUS_MORE_ENTRIES;
4284 struct samr_EnumDomainUsers r;
4285 uint32_t mask, resume_handle=0;
4288 struct samr_LookupNames n;
4289 struct samr_LookupRids lr ;
4290 struct lsa_Strings names;
4291 struct samr_Ids rids, types;
4292 struct samr_SamArray *sam = NULL;
4293 uint32_t num_entries = 0;
4295 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4296 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4297 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4300 printf("Testing EnumDomainUsers\n");
4302 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4303 r.in.domain_handle = handle;
4304 r.in.resume_handle = &resume_handle;
4305 r.in.acct_flags = mask = masks[mask_idx];
4306 r.in.max_size = (uint32_t)-1;
4307 r.out.resume_handle = &resume_handle;
4308 r.out.num_entries = &num_entries;
4311 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4312 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4313 !NT_STATUS_IS_OK(status)) {
4314 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4318 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4320 if (sam->count == 0) {
4324 for (i=0;i<sam->count;i++) {
4326 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4329 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4335 printf("Testing LookupNames\n");
4336 n.in.domain_handle = handle;
4337 n.in.num_names = sam->count;
4338 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4340 n.out.types = &types;
4341 for (i=0;i<sam->count;i++) {
4342 n.in.names[i].string = sam->entries[i].name.string;
4344 status = dcerpc_samr_LookupNames(p, tctx, &n);
4345 if (!NT_STATUS_IS_OK(status)) {
4346 printf("LookupNames failed - %s\n", nt_errstr(status));
4351 printf("Testing LookupRids\n");
4352 lr.in.domain_handle = handle;
4353 lr.in.num_rids = sam->count;
4354 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4355 lr.out.names = &names;
4356 lr.out.types = &types;
4357 for (i=0;i<sam->count;i++) {
4358 lr.in.rids[i] = sam->entries[i].idx;
4360 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4361 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4367 try blasting the server with a bunch of sync requests
4369 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4370 struct policy_handle *handle)
4373 struct samr_EnumDomainUsers r;
4374 uint32_t resume_handle=0;
4376 #define ASYNC_COUNT 100
4377 struct rpc_request *req[ASYNC_COUNT];
4379 if (!torture_setting_bool(tctx, "dangerous", false)) {
4380 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4383 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4385 r.in.domain_handle = handle;
4386 r.in.resume_handle = &resume_handle;
4387 r.in.acct_flags = 0;
4388 r.in.max_size = (uint32_t)-1;
4389 r.out.resume_handle = &resume_handle;
4391 for (i=0;i<ASYNC_COUNT;i++) {
4392 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4395 for (i=0;i<ASYNC_COUNT;i++) {
4396 status = dcerpc_ndr_request_recv(req[i]);
4397 if (!NT_STATUS_IS_OK(status)) {
4398 printf("EnumDomainUsers[%d] failed - %s\n",
4399 i, nt_errstr(status));
4404 torture_comment(tctx, "%d async requests OK\n", i);
4409 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4410 struct policy_handle *handle)
4413 struct samr_EnumDomainGroups r;
4414 uint32_t resume_handle=0;
4415 struct samr_SamArray *sam = NULL;
4416 uint32_t num_entries = 0;
4420 printf("Testing EnumDomainGroups\n");
4422 r.in.domain_handle = handle;
4423 r.in.resume_handle = &resume_handle;
4424 r.in.max_size = (uint32_t)-1;
4425 r.out.resume_handle = &resume_handle;
4426 r.out.num_entries = &num_entries;
4429 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4430 if (!NT_STATUS_IS_OK(status)) {
4431 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4439 for (i=0;i<sam->count;i++) {
4440 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4448 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4449 struct policy_handle *handle)
4452 struct samr_EnumDomainAliases r;
4453 uint32_t resume_handle=0;
4454 struct samr_SamArray *sam = NULL;
4455 uint32_t num_entries = 0;
4459 printf("Testing EnumDomainAliases\n");
4461 r.in.domain_handle = handle;
4462 r.in.resume_handle = &resume_handle;
4463 r.in.max_size = (uint32_t)-1;
4465 r.out.num_entries = &num_entries;
4466 r.out.resume_handle = &resume_handle;
4468 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4469 if (!NT_STATUS_IS_OK(status)) {
4470 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4478 for (i=0;i<sam->count;i++) {
4479 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4487 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4488 struct policy_handle *handle)
4491 struct samr_GetDisplayEnumerationIndex r;
4493 uint16_t levels[] = {1, 2, 3, 4, 5};
4494 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4495 struct lsa_String name;
4499 for (i=0;i<ARRAY_SIZE(levels);i++) {
4500 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4502 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4504 r.in.domain_handle = handle;
4505 r.in.level = levels[i];
4509 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4512 !NT_STATUS_IS_OK(status) &&
4513 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4514 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4515 levels[i], nt_errstr(status));
4519 init_lsa_String(&name, "zzzzzzzz");
4521 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4523 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4524 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
4525 levels[i], nt_errstr(status));
4533 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4534 struct policy_handle *handle)
4537 struct samr_GetDisplayEnumerationIndex2 r;
4539 uint16_t levels[] = {1, 2, 3, 4, 5};
4540 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4541 struct lsa_String name;
4545 for (i=0;i<ARRAY_SIZE(levels);i++) {
4546 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4548 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4550 r.in.domain_handle = handle;
4551 r.in.level = levels[i];
4555 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4557 !NT_STATUS_IS_OK(status) &&
4558 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4559 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4560 levels[i], nt_errstr(status));
4564 init_lsa_String(&name, "zzzzzzzz");
4566 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4567 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4568 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
4569 levels[i], nt_errstr(status));
4577 #define STRING_EQUAL_QUERY(s1, s2, user) \
4578 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4579 /* odd, but valid */ \
4580 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4581 printf("%s mismatch for %s: %s != %s (%s)\n", \
4582 #s1, user.string, s1.string, s2.string, __location__); \
4585 #define INT_EQUAL_QUERY(s1, s2, user) \
4587 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4588 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4592 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4593 struct samr_QueryDisplayInfo *querydisplayinfo,
4594 bool *seen_testuser)
4596 struct samr_OpenUser r;
4597 struct samr_QueryUserInfo q;
4598 union samr_UserInfo *info;
4599 struct policy_handle user_handle;
4602 r.in.domain_handle = querydisplayinfo->in.domain_handle;
4603 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4604 for (i = 0; ; i++) {
4605 switch (querydisplayinfo->in.level) {
4607 if (i >= querydisplayinfo->out.info->info1.count) {
4610 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4613 if (i >= querydisplayinfo->out.info->info2.count) {
4616 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4622 /* Not interested in validating just the account name */
4626 r.out.user_handle = &user_handle;
4628 switch (querydisplayinfo->in.level) {
4631 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4632 if (!NT_STATUS_IS_OK(status)) {
4633 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4638 q.in.user_handle = &user_handle;
4641 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4642 if (!NT_STATUS_IS_OK(status)) {
4643 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4647 switch (querydisplayinfo->in.level) {
4649 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4650 *seen_testuser = true;
4652 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4653 info->info21.full_name, info->info21.account_name);
4654 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4655 info->info21.account_name, info->info21.account_name);
4656 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4657 info->info21.description, info->info21.account_name);
4658 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4659 info->info21.rid, info->info21.account_name);
4660 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4661 info->info21.acct_flags, info->info21.account_name);
4665 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4666 info->info21.account_name, info->info21.account_name);
4667 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4668 info->info21.description, info->info21.account_name);
4669 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4670 info->info21.rid, info->info21.account_name);
4671 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4672 info->info21.acct_flags, info->info21.account_name);
4674 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4675 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
4676 info->info21.account_name.string);
4679 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4680 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4681 info->info21.account_name.string,
4682 querydisplayinfo->out.info->info2.entries[i].acct_flags,
4683 info->info21.acct_flags);
4690 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4697 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4698 struct policy_handle *handle)
4701 struct samr_QueryDisplayInfo r;
4702 struct samr_QueryDomainInfo dom_info;
4703 union samr_DomainInfo *info = NULL;
4705 uint16_t levels[] = {1, 2, 3, 4, 5};
4707 bool seen_testuser = false;
4708 uint32_t total_size;
4709 uint32_t returned_size;
4710 union samr_DispInfo disp_info;
4713 for (i=0;i<ARRAY_SIZE(levels);i++) {
4714 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4717 status = STATUS_MORE_ENTRIES;
4718 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4719 r.in.domain_handle = handle;
4720 r.in.level = levels[i];
4721 r.in.max_entries = 2;
4722 r.in.buf_size = (uint32_t)-1;
4723 r.out.total_size = &total_size;
4724 r.out.returned_size = &returned_size;
4725 r.out.info = &disp_info;
4727 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4728 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4729 printf("QueryDisplayInfo level %u failed - %s\n",
4730 levels[i], nt_errstr(status));
4733 switch (r.in.level) {
4735 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4738 r.in.start_idx += r.out.info->info1.count;
4741 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4744 r.in.start_idx += r.out.info->info2.count;
4747 r.in.start_idx += r.out.info->info3.count;
4750 r.in.start_idx += r.out.info->info4.count;
4753 r.in.start_idx += r.out.info->info5.count;
4757 dom_info.in.domain_handle = handle;
4758 dom_info.in.level = 2;
4759 dom_info.out.info = &info;
4761 /* Check number of users returned is correct */
4762 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4763 if (!NT_STATUS_IS_OK(status)) {
4764 printf("QueryDomainInfo level %u failed - %s\n",
4765 r.in.level, nt_errstr(status));
4769 switch (r.in.level) {
4772 if (info->general.num_users < r.in.start_idx) {
4773 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4774 r.in.start_idx, info->general.num_groups,
4775 info->general.domain_name.string);
4778 if (!seen_testuser) {
4779 struct policy_handle user_handle;
4780 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
4781 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
4782 info->general.domain_name.string);
4784 test_samr_handle_Close(p, mem_ctx, &user_handle);
4790 if (info->general.num_groups != r.in.start_idx) {
4791 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
4792 r.in.start_idx, info->general.num_groups,
4793 info->general.domain_name.string);
4805 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4806 struct policy_handle *handle)
4809 struct samr_QueryDisplayInfo2 r;
4811 uint16_t levels[] = {1, 2, 3, 4, 5};
4813 uint32_t total_size;
4814 uint32_t returned_size;
4815 union samr_DispInfo info;
4817 for (i=0;i<ARRAY_SIZE(levels);i++) {
4818 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
4820 r.in.domain_handle = handle;
4821 r.in.level = levels[i];
4823 r.in.max_entries = 1000;
4824 r.in.buf_size = (uint32_t)-1;
4825 r.out.total_size = &total_size;
4826 r.out.returned_size = &returned_size;
4829 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
4830 if (!NT_STATUS_IS_OK(status)) {
4831 printf("QueryDisplayInfo2 level %u failed - %s\n",
4832 levels[i], nt_errstr(status));
4840 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
4841 struct policy_handle *handle)
4844 struct samr_QueryDisplayInfo3 r;
4846 uint16_t levels[] = {1, 2, 3, 4, 5};
4848 uint32_t total_size;
4849 uint32_t returned_size;
4850 union samr_DispInfo info;
4852 for (i=0;i<ARRAY_SIZE(levels);i++) {
4853 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
4855 r.in.domain_handle = handle;
4856 r.in.level = levels[i];
4858 r.in.max_entries = 1000;
4859 r.in.buf_size = (uint32_t)-1;
4860 r.out.total_size = &total_size;
4861 r.out.returned_size = &returned_size;
4864 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
4865 if (!NT_STATUS_IS_OK(status)) {
4866 printf("QueryDisplayInfo3 level %u failed - %s\n",
4867 levels[i], nt_errstr(status));
4876 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4877 struct policy_handle *handle)
4880 struct samr_QueryDisplayInfo r;
4882 uint32_t total_size;
4883 uint32_t returned_size;
4884 union samr_DispInfo info;
4886 printf("Testing QueryDisplayInfo continuation\n");
4888 r.in.domain_handle = handle;
4891 r.in.max_entries = 1;
4892 r.in.buf_size = (uint32_t)-1;
4893 r.out.total_size = &total_size;
4894 r.out.returned_size = &returned_size;
4898 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4899 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
4900 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
4901 printf("expected idx %d but got %d\n",
4903 r.out.info->info1.entries[0].idx);
4907 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4908 !NT_STATUS_IS_OK(status)) {
4909 printf("QueryDisplayInfo level %u failed - %s\n",
4910 r.in.level, nt_errstr(status));
4915 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
4916 NT_STATUS_IS_OK(status)) &&
4917 *r.out.returned_size != 0);
4922 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
4923 struct policy_handle *handle)
4926 struct samr_QueryDomainInfo r;
4927 union samr_DomainInfo *info = NULL;
4928 struct samr_SetDomainInfo s;
4929 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4930 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
4933 const char *domain_comment = talloc_asprintf(tctx,
4934 "Tortured by Samba4 RPC-SAMR: %s",
4935 timestring(tctx, time(NULL)));
4937 s.in.domain_handle = handle;
4939 s.in.info = talloc(tctx, union samr_DomainInfo);
4941 s.in.info->oem.oem_information.string = domain_comment;
4942 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4943 if (!NT_STATUS_IS_OK(status)) {
4944 printf("SetDomainInfo level %u (set comment) failed - %s\n",
4945 r.in.level, nt_errstr(status));
4949 for (i=0;i<ARRAY_SIZE(levels);i++) {
4950 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
4952 r.in.domain_handle = handle;
4953 r.in.level = levels[i];
4956 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4957 if (!NT_STATUS_IS_OK(status)) {
4958 printf("QueryDomainInfo level %u failed - %s\n",
4959 r.in.level, nt_errstr(status));
4964 switch (levels[i]) {
4966 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
4967 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4968 levels[i], info->general.oem_information.string, domain_comment);
4971 if (!info->general.primary.string) {
4972 printf("QueryDomainInfo level %u returned no PDC name\n",
4975 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
4976 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
4977 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
4978 levels[i], info->general.primary.string, dcerpc_server_name(p));
4983 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
4984 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
4985 levels[i], info->oem.oem_information.string, domain_comment);
4990 if (!info->info6.primary.string) {
4991 printf("QueryDomainInfo level %u returned no PDC name\n",
4997 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
4998 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
4999 levels[i], info->general2.general.oem_information.string, domain_comment);
5005 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5007 s.in.domain_handle = handle;
5008 s.in.level = levels[i];
5011 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5013 if (!NT_STATUS_IS_OK(status)) {
5014 printf("SetDomainInfo level %u failed - %s\n",
5015 r.in.level, nt_errstr(status));
5020 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5021 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5022 r.in.level, nt_errstr(status));
5028 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5029 if (!NT_STATUS_IS_OK(status)) {
5030 printf("QueryDomainInfo level %u failed - %s\n",
5031 r.in.level, nt_errstr(status));
5041 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5042 struct policy_handle *handle)
5045 struct samr_QueryDomainInfo2 r;
5046 union samr_DomainInfo *info = NULL;
5047 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5051 for (i=0;i<ARRAY_SIZE(levels);i++) {
5052 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5054 r.in.domain_handle = handle;
5055 r.in.level = levels[i];
5058 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5059 if (!NT_STATUS_IS_OK(status)) {
5060 printf("QueryDomainInfo2 level %u failed - %s\n",
5061 r.in.level, nt_errstr(status));
5070 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5071 set of group names. */
5072 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5073 struct policy_handle *handle)
5075 struct samr_EnumDomainGroups q1;
5076 struct samr_QueryDisplayInfo q2;
5078 uint32_t resume_handle=0;
5079 struct samr_SamArray *sam = NULL;
5080 uint32_t num_entries = 0;
5083 uint32_t total_size;
5084 uint32_t returned_size;
5085 union samr_DispInfo info;
5088 const char **names = NULL;
5090 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5092 q1.in.domain_handle = handle;
5093 q1.in.resume_handle = &resume_handle;
5095 q1.out.resume_handle = &resume_handle;
5096 q1.out.num_entries = &num_entries;
5099 status = STATUS_MORE_ENTRIES;
5100 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5101 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5103 if (!NT_STATUS_IS_OK(status) &&
5104 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5107 for (i=0; i<*q1.out.num_entries; i++) {
5108 add_string_to_array(tctx,
5109 sam->entries[i].name.string,
5110 &names, &num_names);
5114 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5116 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5118 q2.in.domain_handle = handle;
5120 q2.in.start_idx = 0;
5121 q2.in.max_entries = 5;
5122 q2.in.buf_size = (uint32_t)-1;
5123 q2.out.total_size = &total_size;
5124 q2.out.returned_size = &returned_size;
5125 q2.out.info = &info;
5127 status = STATUS_MORE_ENTRIES;
5128 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5129 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5131 if (!NT_STATUS_IS_OK(status) &&
5132 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5135 for (i=0; i<q2.out.info->info5.count; i++) {
5137 const char *name = q2.out.info->info5.entries[i].account_name.string;
5139 for (j=0; j<num_names; j++) {
5140 if (names[j] == NULL)
5142 if (strequal(names[j], name)) {
5150 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5155 q2.in.start_idx += q2.out.info->info5.count;
5158 if (!NT_STATUS_IS_OK(status)) {
5159 printf("QueryDisplayInfo level 5 failed - %s\n",
5164 for (i=0; i<num_names; i++) {
5165 if (names[i] != NULL) {
5166 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5175 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5176 struct policy_handle *group_handle)
5178 struct samr_DeleteDomainGroup d;
5181 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5183 d.in.group_handle = group_handle;
5184 d.out.group_handle = group_handle;
5186 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5187 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5192 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5193 struct policy_handle *domain_handle)
5195 struct samr_TestPrivateFunctionsDomain r;
5199 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5201 r.in.domain_handle = domain_handle;
5203 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5204 torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5209 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5210 struct dom_sid *domain_sid,
5211 struct policy_handle *domain_handle)
5213 struct samr_RidToSid r;
5216 struct dom_sid *calc_sid, *out_sid;
5217 int rids[] = { 0, 42, 512, 10200 };
5220 for (i=0;i<ARRAY_SIZE(rids);i++) {
5221 torture_comment(tctx, "Testing RidToSid\n");
5223 calc_sid = dom_sid_dup(tctx, domain_sid);
5224 r.in.domain_handle = domain_handle;
5226 r.out.sid = &out_sid;
5228 status = dcerpc_samr_RidToSid(p, tctx, &r);
5229 if (!NT_STATUS_IS_OK(status)) {
5230 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5233 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5235 if (!dom_sid_equal(calc_sid, out_sid)) {
5236 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5237 dom_sid_string(tctx, out_sid),
5238 dom_sid_string(tctx, calc_sid));
5247 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5248 struct policy_handle *domain_handle)
5250 struct samr_GetBootKeyInformation r;
5253 uint32_t unknown = 0;
5255 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5257 r.in.domain_handle = domain_handle;
5258 r.out.unknown = &unknown;
5260 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5261 if (!NT_STATUS_IS_OK(status)) {
5262 /* w2k3 seems to fail this sometimes and pass it sometimes */
5263 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5269 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5270 struct policy_handle *domain_handle,
5271 struct policy_handle *group_handle)
5274 struct samr_AddGroupMember r;
5275 struct samr_DeleteGroupMember d;
5276 struct samr_QueryGroupMember q;
5277 struct samr_RidTypeArray *rids = NULL;
5278 struct samr_SetMemberAttributesOfGroup s;
5281 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5282 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5284 r.in.group_handle = group_handle;
5286 r.in.flags = 0; /* ??? */
5288 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5290 d.in.group_handle = group_handle;
5293 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5294 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5296 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5297 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5299 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5300 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5302 if (torture_setting_bool(tctx, "samba4", false)) {
5303 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5305 /* this one is quite strange. I am using random inputs in the
5306 hope of triggering an error that might give us a clue */
5308 s.in.group_handle = group_handle;
5309 s.in.unknown1 = random();
5310 s.in.unknown2 = random();
5312 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5313 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5316 q.in.group_handle = group_handle;
5319 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5320 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5322 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5323 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5325 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5326 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5332 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5333 struct torture_context *tctx,
5334 struct policy_handle *domain_handle,
5335 struct policy_handle *group_handle,
5336 struct dom_sid *domain_sid)
5339 struct samr_CreateDomainGroup r;
5341 struct lsa_String name;
5344 init_lsa_String(&name, TEST_GROUPNAME);
5346 r.in.domain_handle = domain_handle;
5348 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5349 r.out.group_handle = group_handle;
5352 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5354 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5356 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5357 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5358 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5361 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5367 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5368 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5369 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5373 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5375 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5376 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5378 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5382 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5384 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5386 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5387 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5391 if (!test_SetGroupInfo(p, tctx, group_handle)) {
5400 its not totally clear what this does. It seems to accept any sid you like.
5402 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
5403 struct torture_context *tctx,
5404 struct policy_handle *domain_handle)
5407 struct samr_RemoveMemberFromForeignDomain r;
5409 r.in.domain_handle = domain_handle;
5410 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5412 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5413 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5420 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5421 struct policy_handle *handle);
5423 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5424 struct policy_handle *handle, struct dom_sid *sid,
5425 enum torture_samr_choice which_ops)
5428 struct samr_OpenDomain r;
5429 struct policy_handle domain_handle;
5430 struct policy_handle alias_handle;
5431 struct policy_handle user_handle;
5432 struct policy_handle group_handle;
5435 ZERO_STRUCT(alias_handle);
5436 ZERO_STRUCT(user_handle);
5437 ZERO_STRUCT(group_handle);
5438 ZERO_STRUCT(domain_handle);
5440 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5442 r.in.connect_handle = handle;
5443 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5445 r.out.domain_handle = &domain_handle;
5447 status = dcerpc_samr_OpenDomain(p, tctx, &r);
5448 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5450 /* run the domain tests with the main handle closed - this tests
5451 the servers reference counting */
5452 ret &= test_samr_handle_Close(p, tctx, handle);
5454 switch (which_ops) {
5455 case TORTURE_SAMR_USER_ATTRIBUTES:
5456 case TORTURE_SAMR_PASSWORDS:
5457 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5458 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5459 /* This test needs 'complex' users to validate */
5460 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5462 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5465 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5466 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
5467 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5469 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5472 case TORTURE_SAMR_OTHER:
5473 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
5475 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5477 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5478 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5479 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5480 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5481 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5482 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5483 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5484 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5485 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5486 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5487 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5488 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5489 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5491 if (torture_setting_bool(tctx, "samba4", false)) {
5492 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5494 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5495 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5497 ret &= test_GroupList(p, tctx, &domain_handle);
5498 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5499 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5500 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5502 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5507 if (!policy_handle_empty(&user_handle) &&
5508 !test_DeleteUser(p, tctx, &user_handle)) {
5512 if (!policy_handle_empty(&alias_handle) &&
5513 !test_DeleteAlias(p, tctx, &alias_handle)) {
5517 if (!policy_handle_empty(&group_handle) &&
5518 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5522 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5524 /* reconnect the main handle */
5525 ret &= test_Connect(p, tctx, handle);
5528 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5534 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5535 struct policy_handle *handle, const char *domain,
5536 enum torture_samr_choice which_ops)
5539 struct samr_LookupDomain r;
5540 struct dom_sid2 *sid = NULL;
5541 struct lsa_String n1;
5542 struct lsa_String n2;
5545 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5547 /* check for correct error codes */
5548 r.in.connect_handle = handle;
5549 r.in.domain_name = &n2;
5553 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5554 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5556 init_lsa_String(&n2, "xxNODOMAINxx");
5558 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5559 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5561 r.in.connect_handle = handle;
5563 init_lsa_String(&n1, domain);
5564 r.in.domain_name = &n1;
5566 status = dcerpc_samr_LookupDomain(p, tctx, &r);
5567 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5569 if (!test_GetDomPwInfo(p, tctx, &n1)) {
5573 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
5581 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5582 struct policy_handle *handle, enum torture_samr_choice which_ops)
5585 struct samr_EnumDomains r;
5586 uint32_t resume_handle = 0;
5587 uint32_t num_entries = 0;
5588 struct samr_SamArray *sam = NULL;
5592 r.in.connect_handle = handle;
5593 r.in.resume_handle = &resume_handle;
5594 r.in.buf_size = (uint32_t)-1;
5595 r.out.resume_handle = &resume_handle;
5596 r.out.num_entries = &num_entries;
5599 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5600 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5606 for (i=0;i<sam->count;i++) {
5607 if (!test_LookupDomain(p, tctx, handle,
5608 sam->entries[i].name.string, which_ops)) {
5613 status = dcerpc_samr_EnumDomains(p, tctx, &r);
5614 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5620 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5621 struct policy_handle *handle)
5624 struct samr_Connect r;
5625 struct samr_Connect2 r2;
5626 struct samr_Connect3 r3;
5627 struct samr_Connect4 r4;
5628 struct samr_Connect5 r5;
5629 union samr_ConnectInfo info;
5630 struct policy_handle h;
5631 uint32_t level_out = 0;
5632 bool ret = true, got_handle = false;
5634 torture_comment(tctx, "testing samr_Connect\n");
5636 r.in.system_name = 0;
5637 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5638 r.out.connect_handle = &h;
5640 status = dcerpc_samr_Connect(p, tctx, &r);
5641 if (!NT_STATUS_IS_OK(status)) {
5642 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5649 torture_comment(tctx, "testing samr_Connect2\n");
5651 r2.in.system_name = NULL;
5652 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5653 r2.out.connect_handle = &h;
5655 status = dcerpc_samr_Connect2(p, tctx, &r2);
5656 if (!NT_STATUS_IS_OK(status)) {
5657 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5661 test_samr_handle_Close(p, tctx, handle);
5667 torture_comment(tctx, "testing samr_Connect3\n");
5669 r3.in.system_name = NULL;
5671 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5672 r3.out.connect_handle = &h;
5674 status = dcerpc_samr_Connect3(p, tctx, &r3);
5675 if (!NT_STATUS_IS_OK(status)) {
5676 printf("Connect3 failed - %s\n", nt_errstr(status));
5680 test_samr_handle_Close(p, tctx, handle);
5686 torture_comment(tctx, "testing samr_Connect4\n");
5688 r4.in.system_name = "";
5689 r4.in.client_version = 0;
5690 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5691 r4.out.connect_handle = &h;
5693 status = dcerpc_samr_Connect4(p, tctx, &r4);
5694 if (!NT_STATUS_IS_OK(status)) {
5695 printf("Connect4 failed - %s\n", nt_errstr(status));
5699 test_samr_handle_Close(p, tctx, handle);
5705 torture_comment(tctx, "testing samr_Connect5\n");
5707 info.info1.client_version = 0;
5708 info.info1.unknown2 = 0;
5710 r5.in.system_name = "";
5711 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5713 r5.out.level_out = &level_out;
5714 r5.in.info_in = &info;
5715 r5.out.info_out = &info;
5716 r5.out.connect_handle = &h;
5718 status = dcerpc_samr_Connect5(p, tctx, &r5);
5719 if (!NT_STATUS_IS_OK(status)) {
5720 printf("Connect5 failed - %s\n", nt_errstr(status));
5724 test_samr_handle_Close(p, tctx, handle);
5734 bool torture_rpc_samr(struct torture_context *torture)
5737 struct dcerpc_pipe *p;
5739 struct policy_handle handle;
5741 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5742 if (!NT_STATUS_IS_OK(status)) {
5746 ret &= test_Connect(p, torture, &handle);
5748 ret &= test_QuerySecurity(p, torture, &handle);
5750 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
5752 ret &= test_SetDsrmPassword(p, torture, &handle);
5754 ret &= test_Shutdown(p, torture, &handle);
5756 ret &= test_samr_handle_Close(p, torture, &handle);
5762 bool torture_rpc_samr_users(struct torture_context *torture)
5765 struct dcerpc_pipe *p;
5767 struct policy_handle handle;
5769 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5770 if (!NT_STATUS_IS_OK(status)) {
5774 ret &= test_Connect(p, torture, &handle);
5776 ret &= test_QuerySecurity(p, torture, &handle);
5778 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
5780 ret &= test_SetDsrmPassword(p, torture, &handle);
5782 ret &= test_Shutdown(p, torture, &handle);
5784 ret &= test_samr_handle_Close(p, torture, &handle);
5790 bool torture_rpc_samr_passwords(struct torture_context *torture)
5793 struct dcerpc_pipe *p;
5795 struct policy_handle handle;
5797 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5798 if (!NT_STATUS_IS_OK(status)) {
5802 ret &= test_Connect(p, torture, &handle);
5804 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
5806 ret &= test_samr_handle_Close(p, torture, &handle);
5811 bool torture_rpc_samr_passwords_pwdlastset(struct torture_context *torture)
5814 struct dcerpc_pipe *p;
5816 struct policy_handle handle;
5818 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5819 if (!NT_STATUS_IS_OK(status)) {
5823 ret &= test_Connect(p, torture, &handle);
5825 ret &= test_EnumDomains(p, torture, &handle,
5826 TORTURE_SAMR_PASSWORDS_PWDLASTSET);
5828 ret &= test_samr_handle_Close(p, torture, &handle);