replace: Add don't include unistd.h directly and add uid_wrapper.
[Samba/gebeck_regimport.git] / source4 / torture / rpc / samr.c
blobcc2cdfc3526522ad9f27772f08afc1a996101d76
1 /*
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
7 Copyright (C) Guenther Deschner 2008-2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include <tevent.h>
26 #include "system/time.h"
27 #include "system/network.h"
28 #include "librpc/gen_ndr/lsa.h"
29 #include "librpc/gen_ndr/ndr_netlogon.h"
30 #include "librpc/gen_ndr/ndr_netlogon_c.h"
31 #include "librpc/gen_ndr/ndr_samr_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "../lib/crypto/crypto.h"
34 #include "libcli/auth/libcli_auth.h"
35 #include "libcli/security/security.h"
36 #include "torture/rpc/torture_rpc.h"
37 #include "param/param.h"
38 #include "auth/gensec/gensec.h"
39 #include "auth/gensec/schannel.h"
40 #include "auth/gensec/gensec_proto.h"
41 #include "../libcli/auth/schannel.h"
43 #define TEST_ACCOUNT_NAME "samrtorturetest"
44 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
45 #define TEST_ALIASNAME "samrtorturetestalias"
46 #define TEST_GROUPNAME "samrtorturetestgroup"
47 #define TEST_MACHINENAME "samrtestmach$"
48 #define TEST_DOMAINNAME "samrtestdom$"
50 enum torture_samr_choice {
51 TORTURE_SAMR_PASSWORDS,
52 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
53 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT,
54 TORTURE_SAMR_PASSWORDS_LOCKOUT,
55 TORTURE_SAMR_USER_ATTRIBUTES,
56 TORTURE_SAMR_USER_PRIVILEGES,
57 TORTURE_SAMR_OTHER,
58 TORTURE_SAMR_MANY_ACCOUNTS,
59 TORTURE_SAMR_MANY_GROUPS,
60 TORTURE_SAMR_MANY_ALIASES
63 struct torture_samr_context {
64 struct policy_handle handle;
65 struct cli_credentials *machine_credentials;
66 enum torture_samr_choice choice;
67 uint32_t num_objects_large_dc;
70 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
71 struct torture_context *tctx,
72 struct policy_handle *handle);
74 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
75 struct torture_context *tctx,
76 struct policy_handle *handle);
78 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
79 struct torture_context *tctx,
80 struct policy_handle *handle);
82 static bool test_ChangePassword(struct dcerpc_pipe *p,
83 struct torture_context *tctx,
84 const char *acct_name,
85 struct policy_handle *domain_handle, char **password);
87 static void init_lsa_String(struct lsa_String *string, const char *s)
89 string->string = s;
92 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
94 string->string = s;
97 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
99 string->length = length;
100 string->size = length;
101 string->array = (uint16_t *)discard_const(s);
104 bool test_samr_handle_Close(struct dcerpc_binding_handle *b,
105 struct torture_context *tctx,
106 struct policy_handle *handle)
108 struct samr_Close r;
110 r.in.handle = handle;
111 r.out.handle = handle;
113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Close_r(b, tctx, &r),
114 "Close failed");
115 torture_assert_ntstatus_ok(tctx, r.out.result, "Close failed");
117 return true;
120 static bool test_Shutdown(struct dcerpc_binding_handle *b,
121 struct torture_context *tctx,
122 struct policy_handle *handle)
124 struct samr_Shutdown r;
126 if (!torture_setting_bool(tctx, "dangerous", false)) {
127 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
128 return true;
131 r.in.connect_handle = handle;
133 torture_comment(tctx, "Testing samr_Shutdown\n");
135 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Shutdown_r(b, tctx, &r),
136 "Shutdown failed");
137 torture_assert_ntstatus_ok(tctx, r.out.result, "Shutdown failed");
139 return true;
142 static bool test_SetDsrmPassword(struct dcerpc_binding_handle *b,
143 struct torture_context *tctx,
144 struct policy_handle *handle)
146 struct samr_SetDsrmPassword r;
147 struct lsa_String string;
148 struct samr_Password hash;
150 if (!torture_setting_bool(tctx, "dangerous", false)) {
151 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
154 E_md4hash("TeSTDSRM123", hash.hash);
156 init_lsa_String(&string, "Administrator");
158 r.in.name = &string;
159 r.in.unknown = 0;
160 r.in.hash = &hash;
162 torture_comment(tctx, "Testing samr_SetDsrmPassword\n");
164 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDsrmPassword_r(b, tctx, &r),
165 "SetDsrmPassword failed");
166 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED, "SetDsrmPassword failed");
168 return true;
172 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
173 struct torture_context *tctx,
174 struct policy_handle *handle)
176 struct samr_QuerySecurity r;
177 struct samr_SetSecurity s;
178 struct sec_desc_buf *sdbuf = NULL;
180 r.in.handle = handle;
181 r.in.sec_info = 7;
182 r.out.sdbuf = &sdbuf;
184 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
185 "QuerySecurity failed");
186 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
188 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
190 s.in.handle = handle;
191 s.in.sec_info = 7;
192 s.in.sdbuf = sdbuf;
194 if (torture_setting_bool(tctx, "samba4", false)) {
195 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
198 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetSecurity_r(b, tctx, &s),
199 "SetSecurity failed");
200 torture_assert_ntstatus_ok(tctx, r.out.result, "SetSecurity failed");
202 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
203 "QuerySecurity failed");
204 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
206 return true;
210 static bool test_SetUserInfo(struct dcerpc_binding_handle *b, struct torture_context *tctx,
211 struct policy_handle *handle, uint32_t base_acct_flags,
212 const char *base_account_name)
214 struct samr_SetUserInfo s;
215 struct samr_SetUserInfo2 s2;
216 struct samr_QueryUserInfo q;
217 struct samr_QueryUserInfo q0;
218 union samr_UserInfo u;
219 union samr_UserInfo *info;
220 bool ret = true;
221 const char *test_account_name;
223 uint32_t user_extra_flags = 0;
225 if (!torture_setting_bool(tctx, "samba3", false)) {
226 if (base_acct_flags == ACB_NORMAL) {
227 /* When created, accounts are expired by default */
228 user_extra_flags = ACB_PW_EXPIRED;
232 s.in.user_handle = handle;
233 s.in.info = &u;
235 s2.in.user_handle = handle;
236 s2.in.info = &u;
238 q.in.user_handle = handle;
239 q.out.info = &info;
240 q0 = q;
242 #define TESTCALL(call, r) \
243 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
244 #call " failed"); \
245 if (!NT_STATUS_IS_OK(r.out.result)) { \
246 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
247 r.in.level, nt_errstr(r.out.result), __location__); \
248 ret = false; \
249 break; \
252 #define STRING_EQUAL(s1, s2, field) \
253 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
254 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
255 #field, s2, __location__); \
256 ret = false; \
257 break; \
260 #define MEM_EQUAL(s1, s2, length, field) \
261 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
262 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
263 #field, (const char *)s2, __location__); \
264 ret = false; \
265 break; \
268 #define INT_EQUAL(i1, i2, field) \
269 if (i1 != i2) { \
270 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
271 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
272 ret = false; \
273 break; \
276 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
277 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
278 q.in.level = lvl1; \
279 TESTCALL(QueryUserInfo, q) \
280 s.in.level = lvl1; \
281 s2.in.level = lvl1; \
282 u = *info; \
283 if (lvl1 == 21) { \
284 ZERO_STRUCT(u.info21); \
285 u.info21.fields_present = fpval; \
287 init_lsa_String(&u.info ## lvl1.field1, value); \
288 TESTCALL(SetUserInfo, s) \
289 TESTCALL(SetUserInfo2, s2) \
290 init_lsa_String(&u.info ## lvl1.field1, ""); \
291 TESTCALL(QueryUserInfo, q); \
292 u = *info; \
293 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
294 q.in.level = lvl2; \
295 TESTCALL(QueryUserInfo, q) \
296 u = *info; \
297 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
298 } while (0)
300 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
301 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
302 q.in.level = lvl1; \
303 TESTCALL(QueryUserInfo, q) \
304 s.in.level = lvl1; \
305 s2.in.level = lvl1; \
306 u = *info; \
307 if (lvl1 == 21) { \
308 ZERO_STRUCT(u.info21); \
309 u.info21.fields_present = fpval; \
311 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
312 TESTCALL(SetUserInfo, s) \
313 TESTCALL(SetUserInfo2, s2) \
314 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
315 TESTCALL(QueryUserInfo, q); \
316 u = *info; \
317 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
318 q.in.level = lvl2; \
319 TESTCALL(QueryUserInfo, q) \
320 u = *info; \
321 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
322 } while (0)
324 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
325 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
326 q.in.level = lvl1; \
327 TESTCALL(QueryUserInfo, q) \
328 s.in.level = lvl1; \
329 s2.in.level = lvl1; \
330 u = *info; \
331 if (lvl1 == 21) { \
332 uint8_t *bits = u.info21.logon_hours.bits; \
333 ZERO_STRUCT(u.info21); \
334 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
335 u.info21.logon_hours.units_per_week = 168; \
336 u.info21.logon_hours.bits = bits; \
338 u.info21.fields_present = fpval; \
340 u.info ## lvl1.field1 = value; \
341 TESTCALL(SetUserInfo, s) \
342 TESTCALL(SetUserInfo2, s2) \
343 u.info ## lvl1.field1 = 0; \
344 TESTCALL(QueryUserInfo, q); \
345 u = *info; \
346 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
347 q.in.level = lvl2; \
348 TESTCALL(QueryUserInfo, q) \
349 u = *info; \
350 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
351 } while (0)
353 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
354 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
355 } while (0)
357 q0.in.level = 12;
358 do { TESTCALL(QueryUserInfo, q0) } while (0);
360 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
361 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
362 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
363 SAMR_FIELD_COMMENT);
365 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
366 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
367 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
368 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
369 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
370 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
371 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
372 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
373 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
374 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
375 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
376 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
377 test_account_name = base_account_name;
378 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
379 SAMR_FIELD_ACCOUNT_NAME);
381 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
382 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
387 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
388 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
389 SAMR_FIELD_FULL_NAME);
391 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
392 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
393 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
394 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
395 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
396 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
397 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
398 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
399 SAMR_FIELD_FULL_NAME);
401 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
402 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
404 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
405 SAMR_FIELD_LOGON_SCRIPT);
407 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
408 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
410 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
411 SAMR_FIELD_PROFILE_PATH);
413 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
414 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
416 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
417 SAMR_FIELD_HOME_DIRECTORY);
418 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
419 SAMR_FIELD_HOME_DIRECTORY);
421 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
422 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
424 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
425 SAMR_FIELD_HOME_DRIVE);
426 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
427 SAMR_FIELD_HOME_DRIVE);
429 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
430 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
431 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
432 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
433 SAMR_FIELD_DESCRIPTION);
435 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
436 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
437 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
438 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
439 SAMR_FIELD_WORKSTATIONS);
440 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
441 SAMR_FIELD_WORKSTATIONS);
442 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
443 SAMR_FIELD_WORKSTATIONS);
444 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
445 SAMR_FIELD_WORKSTATIONS);
447 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
449 SAMR_FIELD_PARAMETERS);
450 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
451 SAMR_FIELD_PARAMETERS);
452 /* also empty user parameters are allowed */
453 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
454 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
455 SAMR_FIELD_PARAMETERS);
456 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
457 SAMR_FIELD_PARAMETERS);
459 /* Samba 3 cannot store country_code and code_page atm. - gd */
460 if (!torture_setting_bool(tctx, "samba3", false)) {
461 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
462 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
463 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
464 SAMR_FIELD_COUNTRY_CODE);
465 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
466 SAMR_FIELD_COUNTRY_CODE);
468 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
469 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
470 SAMR_FIELD_CODE_PAGE);
471 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
472 SAMR_FIELD_CODE_PAGE);
475 if (!torture_setting_bool(tctx, "samba3", false)) {
476 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
477 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
478 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
479 SAMR_FIELD_ACCT_EXPIRY);
480 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
481 SAMR_FIELD_ACCT_EXPIRY);
482 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
483 SAMR_FIELD_ACCT_EXPIRY);
484 } else {
485 /* Samba 3 can only store seconds / time_t in passdb - gd */
486 NTTIME nt;
487 unix_to_nt_time(&nt, time(NULL) + __LINE__);
488 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
489 unix_to_nt_time(&nt, time(NULL) + __LINE__);
490 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
491 unix_to_nt_time(&nt, time(NULL) + __LINE__);
492 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
493 unix_to_nt_time(&nt, time(NULL) + __LINE__);
494 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
495 unix_to_nt_time(&nt, time(NULL) + __LINE__);
496 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
499 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
500 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
501 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
502 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
503 SAMR_FIELD_LOGON_HOURS);
505 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
506 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
507 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
509 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
510 (base_acct_flags | ACB_DISABLED),
511 (base_acct_flags | ACB_DISABLED | user_extra_flags),
514 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
517 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
519 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
520 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
521 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
525 /* The 'autolock' flag doesn't stick - check this */
526 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
527 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
528 (base_acct_flags | ACB_DISABLED | user_extra_flags),
530 #if 0
531 /* Removing the 'disabled' flag doesn't stick - check this */
532 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
533 (base_acct_flags),
534 (base_acct_flags | ACB_DISABLED | user_extra_flags),
536 #endif
538 /* Samba3 cannot store these atm */
539 if (!torture_setting_bool(tctx, "samba3", false)) {
540 /* The 'store plaintext' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
542 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
543 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
545 /* The 'use DES' flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
547 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
548 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
550 /* The 'don't require kerberos pre-authentication flag does stick */
551 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
552 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
553 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
555 /* The 'no kerberos PAC required' flag sticks */
556 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
557 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
558 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
561 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
562 (base_acct_flags | ACB_DISABLED),
563 (base_acct_flags | ACB_DISABLED | user_extra_flags),
564 SAMR_FIELD_ACCT_FLAGS);
566 #if 0
567 /* these fail with win2003 - it appears you can't set the primary gid?
568 the set succeeds, but the gid isn't changed. Very weird! */
569 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
570 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
571 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
572 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
573 #endif
575 return ret;
579 generate a random password for password change tests
581 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
583 size_t len = MAX(8, min_len);
584 char *s = generate_random_password(mem_ctx, len, len+6);
585 return s;
588 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
590 char *s = samr_rand_pass_silent(mem_ctx, min_len);
591 printf("Generated password '%s'\n", s);
592 return s;
597 generate a random password for password change tests
599 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
601 int i;
602 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
603 generate_random_buffer(password.data, password.length);
605 for (i=0; i < len; i++) {
606 if (((uint16_t *)password.data)[i] == 0) {
607 ((uint16_t *)password.data)[i] = 1;
611 return password;
615 generate a random password for password change tests (fixed length)
617 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
619 char *s = generate_random_password(mem_ctx, len, len);
620 printf("Generated password '%s'\n", s);
621 return s;
624 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
625 struct policy_handle *handle, char **password)
627 NTSTATUS status;
628 struct samr_SetUserInfo s;
629 union samr_UserInfo u;
630 bool ret = true;
631 DATA_BLOB session_key;
632 char *newpass;
633 struct dcerpc_binding_handle *b = p->binding_handle;
634 struct samr_GetUserPwInfo pwp;
635 struct samr_PwInfo info;
636 int policy_min_pw_len = 0;
637 pwp.in.user_handle = handle;
638 pwp.out.info = &info;
640 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
641 "GetUserPwInfo failed");
642 if (NT_STATUS_IS_OK(pwp.out.result)) {
643 policy_min_pw_len = pwp.out.info->min_password_length;
645 newpass = samr_rand_pass(tctx, policy_min_pw_len);
647 s.in.user_handle = handle;
648 s.in.info = &u;
649 s.in.level = 24;
651 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
652 u.info24.password_expired = 0;
654 status = dcerpc_fetch_session_key(p, &session_key);
655 if (!NT_STATUS_IS_OK(status)) {
656 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
657 s.in.level, nt_errstr(status));
658 return false;
661 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
663 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
665 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
666 "SetUserInfo failed");
667 if (!NT_STATUS_IS_OK(s.out.result)) {
668 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
669 s.in.level, nt_errstr(s.out.result));
670 ret = false;
671 } else {
672 *password = newpass;
675 return ret;
679 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
680 struct policy_handle *handle, uint32_t fields_present,
681 char **password)
683 NTSTATUS status;
684 struct samr_SetUserInfo s;
685 union samr_UserInfo u;
686 bool ret = true;
687 DATA_BLOB session_key;
688 struct dcerpc_binding_handle *b = p->binding_handle;
689 char *newpass;
690 struct samr_GetUserPwInfo pwp;
691 struct samr_PwInfo info;
692 int policy_min_pw_len = 0;
693 pwp.in.user_handle = handle;
694 pwp.out.info = &info;
696 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
697 "GetUserPwInfo failed");
698 if (NT_STATUS_IS_OK(pwp.out.result)) {
699 policy_min_pw_len = pwp.out.info->min_password_length;
701 newpass = samr_rand_pass(tctx, policy_min_pw_len);
703 s.in.user_handle = handle;
704 s.in.info = &u;
705 s.in.level = 23;
707 ZERO_STRUCT(u);
709 u.info23.info.fields_present = fields_present;
711 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
713 status = dcerpc_fetch_session_key(p, &session_key);
714 if (!NT_STATUS_IS_OK(status)) {
715 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
716 s.in.level, nt_errstr(status));
717 return false;
720 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
722 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
724 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
725 "SetUserInfo failed");
726 if (!NT_STATUS_IS_OK(s.out.result)) {
727 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
728 s.in.level, nt_errstr(s.out.result));
729 ret = false;
730 } else {
731 *password = newpass;
734 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
736 status = dcerpc_fetch_session_key(p, &session_key);
737 if (!NT_STATUS_IS_OK(status)) {
738 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
739 s.in.level, nt_errstr(status));
740 return false;
743 /* This should break the key nicely */
744 session_key.length--;
745 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
747 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
749 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
750 "SetUserInfo failed");
751 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
752 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
753 s.in.level, nt_errstr(s.out.result));
754 ret = false;
757 return ret;
761 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
762 struct policy_handle *handle, bool makeshort,
763 char **password)
765 NTSTATUS status;
766 struct samr_SetUserInfo s;
767 union samr_UserInfo u;
768 bool ret = true;
769 DATA_BLOB session_key;
770 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
771 uint8_t confounder[16];
772 char *newpass;
773 struct dcerpc_binding_handle *b = p->binding_handle;
774 struct MD5Context ctx;
775 struct samr_GetUserPwInfo pwp;
776 struct samr_PwInfo info;
777 int policy_min_pw_len = 0;
778 pwp.in.user_handle = handle;
779 pwp.out.info = &info;
781 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
782 "GetUserPwInfo failed");
783 if (NT_STATUS_IS_OK(pwp.out.result)) {
784 policy_min_pw_len = pwp.out.info->min_password_length;
786 if (makeshort && policy_min_pw_len) {
787 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
788 } else {
789 newpass = samr_rand_pass(tctx, policy_min_pw_len);
792 s.in.user_handle = handle;
793 s.in.info = &u;
794 s.in.level = 26;
796 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
797 u.info26.password_expired = 0;
799 status = dcerpc_fetch_session_key(p, &session_key);
800 if (!NT_STATUS_IS_OK(status)) {
801 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
802 s.in.level, nt_errstr(status));
803 return false;
806 generate_random_buffer((uint8_t *)confounder, 16);
808 MD5Init(&ctx);
809 MD5Update(&ctx, confounder, 16);
810 MD5Update(&ctx, session_key.data, session_key.length);
811 MD5Final(confounded_session_key.data, &ctx);
813 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
814 memcpy(&u.info26.password.data[516], confounder, 16);
816 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
818 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
819 "SetUserInfo failed");
820 if (!NT_STATUS_IS_OK(s.out.result)) {
821 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
822 s.in.level, nt_errstr(s.out.result));
823 ret = false;
824 } else {
825 *password = newpass;
828 /* This should break the key nicely */
829 confounded_session_key.data[0]++;
831 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
832 memcpy(&u.info26.password.data[516], confounder, 16);
834 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
836 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
837 "SetUserInfo failed");
838 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
839 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
840 s.in.level, nt_errstr(s.out.result));
841 ret = false;
842 } else {
843 *password = newpass;
846 return ret;
849 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
850 struct policy_handle *handle, uint32_t fields_present,
851 char **password)
853 NTSTATUS status;
854 struct samr_SetUserInfo s;
855 union samr_UserInfo u;
856 bool ret = true;
857 DATA_BLOB session_key;
858 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
859 struct MD5Context ctx;
860 uint8_t confounder[16];
861 char *newpass;
862 struct dcerpc_binding_handle *b = p->binding_handle;
863 struct samr_GetUserPwInfo pwp;
864 struct samr_PwInfo info;
865 int policy_min_pw_len = 0;
866 pwp.in.user_handle = handle;
867 pwp.out.info = &info;
869 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
870 "GetUserPwInfo failed");
871 if (NT_STATUS_IS_OK(pwp.out.result)) {
872 policy_min_pw_len = pwp.out.info->min_password_length;
874 newpass = samr_rand_pass(tctx, policy_min_pw_len);
876 s.in.user_handle = handle;
877 s.in.info = &u;
878 s.in.level = 25;
880 ZERO_STRUCT(u);
882 u.info25.info.fields_present = fields_present;
884 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
886 status = dcerpc_fetch_session_key(p, &session_key);
887 if (!NT_STATUS_IS_OK(status)) {
888 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
889 s.in.level, nt_errstr(status));
890 return false;
893 generate_random_buffer((uint8_t *)confounder, 16);
895 MD5Init(&ctx);
896 MD5Update(&ctx, confounder, 16);
897 MD5Update(&ctx, session_key.data, session_key.length);
898 MD5Final(confounded_session_key.data, &ctx);
900 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
901 memcpy(&u.info25.password.data[516], confounder, 16);
903 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
905 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
906 "SetUserInfo failed");
907 if (!NT_STATUS_IS_OK(s.out.result)) {
908 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
909 s.in.level, nt_errstr(s.out.result));
910 ret = false;
911 } else {
912 *password = newpass;
915 /* This should break the key nicely */
916 confounded_session_key.data[0]++;
918 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
919 memcpy(&u.info25.password.data[516], confounder, 16);
921 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
924 "SetUserInfo failed");
925 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
926 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
927 s.in.level, nt_errstr(s.out.result));
928 ret = false;
931 return ret;
934 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
935 struct policy_handle *handle, char **password)
937 NTSTATUS status;
938 struct samr_SetUserInfo s;
939 union samr_UserInfo u;
940 bool ret = true;
941 DATA_BLOB session_key;
942 char *newpass;
943 struct dcerpc_binding_handle *b = p->binding_handle;
944 struct samr_GetUserPwInfo pwp;
945 struct samr_PwInfo info;
946 int policy_min_pw_len = 0;
947 uint8_t lm_hash[16], nt_hash[16];
949 pwp.in.user_handle = handle;
950 pwp.out.info = &info;
952 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
953 "GetUserPwInfo failed");
954 if (NT_STATUS_IS_OK(pwp.out.result)) {
955 policy_min_pw_len = pwp.out.info->min_password_length;
957 newpass = samr_rand_pass(tctx, policy_min_pw_len);
959 s.in.user_handle = handle;
960 s.in.info = &u;
961 s.in.level = 18;
963 ZERO_STRUCT(u);
965 u.info18.nt_pwd_active = true;
966 u.info18.lm_pwd_active = true;
968 E_md4hash(newpass, nt_hash);
969 E_deshash(newpass, lm_hash);
971 status = dcerpc_fetch_session_key(p, &session_key);
972 if (!NT_STATUS_IS_OK(status)) {
973 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
974 s.in.level, nt_errstr(status));
975 return false;
979 DATA_BLOB in,out;
980 in = data_blob_const(nt_hash, 16);
981 out = data_blob_talloc_zero(tctx, 16);
982 sess_crypt_blob(&out, &in, &session_key, true);
983 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
986 DATA_BLOB in,out;
987 in = data_blob_const(lm_hash, 16);
988 out = data_blob_talloc_zero(tctx, 16);
989 sess_crypt_blob(&out, &in, &session_key, true);
990 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
993 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
995 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
996 "SetUserInfo failed");
997 if (!NT_STATUS_IS_OK(s.out.result)) {
998 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
999 s.in.level, nt_errstr(s.out.result));
1000 ret = false;
1001 } else {
1002 *password = newpass;
1005 return ret;
1008 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
1009 struct policy_handle *handle, uint32_t fields_present,
1010 char **password)
1012 NTSTATUS status;
1013 struct samr_SetUserInfo s;
1014 union samr_UserInfo u;
1015 bool ret = true;
1016 DATA_BLOB session_key;
1017 char *newpass;
1018 struct dcerpc_binding_handle *b = p->binding_handle;
1019 struct samr_GetUserPwInfo pwp;
1020 struct samr_PwInfo info;
1021 int policy_min_pw_len = 0;
1022 uint8_t lm_hash[16], nt_hash[16];
1024 pwp.in.user_handle = handle;
1025 pwp.out.info = &info;
1027 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1028 "GetUserPwInfo failed");
1029 if (NT_STATUS_IS_OK(pwp.out.result)) {
1030 policy_min_pw_len = pwp.out.info->min_password_length;
1032 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1034 s.in.user_handle = handle;
1035 s.in.info = &u;
1036 s.in.level = 21;
1038 E_md4hash(newpass, nt_hash);
1039 E_deshash(newpass, lm_hash);
1041 ZERO_STRUCT(u);
1043 u.info21.fields_present = fields_present;
1045 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1046 u.info21.lm_owf_password.length = 16;
1047 u.info21.lm_owf_password.size = 16;
1048 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1049 u.info21.lm_password_set = true;
1052 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1053 u.info21.nt_owf_password.length = 16;
1054 u.info21.nt_owf_password.size = 16;
1055 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1056 u.info21.nt_password_set = true;
1059 status = dcerpc_fetch_session_key(p, &session_key);
1060 if (!NT_STATUS_IS_OK(status)) {
1061 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1062 s.in.level, nt_errstr(status));
1063 return false;
1066 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1067 DATA_BLOB in,out;
1068 in = data_blob_const(u.info21.lm_owf_password.array,
1069 u.info21.lm_owf_password.length);
1070 out = data_blob_talloc_zero(tctx, 16);
1071 sess_crypt_blob(&out, &in, &session_key, true);
1072 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1075 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1076 DATA_BLOB in,out;
1077 in = data_blob_const(u.info21.nt_owf_password.array,
1078 u.info21.nt_owf_password.length);
1079 out = data_blob_talloc_zero(tctx, 16);
1080 sess_crypt_blob(&out, &in, &session_key, true);
1081 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1084 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1086 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1087 "SetUserInfo failed");
1088 if (!NT_STATUS_IS_OK(s.out.result)) {
1089 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1090 s.in.level, nt_errstr(s.out.result));
1091 ret = false;
1092 } else {
1093 *password = newpass;
1096 /* try invalid length */
1097 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1099 u.info21.nt_owf_password.length++;
1101 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1102 "SetUserInfo failed");
1103 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1104 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1105 s.in.level, nt_errstr(s.out.result));
1106 ret = false;
1110 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1112 u.info21.lm_owf_password.length++;
1114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1115 "SetUserInfo failed");
1116 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1117 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1118 s.in.level, nt_errstr(s.out.result));
1119 ret = false;
1123 return ret;
1126 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1127 struct torture_context *tctx,
1128 struct policy_handle *handle,
1129 uint16_t level,
1130 uint32_t fields_present,
1131 char **password, uint8_t password_expired,
1132 bool use_setinfo2,
1133 bool *matched_expected_error)
1135 NTSTATUS status;
1136 NTSTATUS expected_error = NT_STATUS_OK;
1137 struct samr_SetUserInfo s;
1138 struct samr_SetUserInfo2 s2;
1139 union samr_UserInfo u;
1140 bool ret = true;
1141 DATA_BLOB session_key;
1142 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1143 struct MD5Context ctx;
1144 uint8_t confounder[16];
1145 char *newpass;
1146 struct dcerpc_binding_handle *b = p->binding_handle;
1147 struct samr_GetUserPwInfo pwp;
1148 struct samr_PwInfo info;
1149 int policy_min_pw_len = 0;
1150 const char *comment = NULL;
1151 uint8_t lm_hash[16], nt_hash[16];
1153 pwp.in.user_handle = handle;
1154 pwp.out.info = &info;
1156 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1157 "GetUserPwInfo failed");
1158 if (NT_STATUS_IS_OK(pwp.out.result)) {
1159 policy_min_pw_len = pwp.out.info->min_password_length;
1161 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1163 if (use_setinfo2) {
1164 s2.in.user_handle = handle;
1165 s2.in.info = &u;
1166 s2.in.level = level;
1167 } else {
1168 s.in.user_handle = handle;
1169 s.in.info = &u;
1170 s.in.level = level;
1173 if (fields_present & SAMR_FIELD_COMMENT) {
1174 comment = talloc_asprintf(tctx, "comment: %ld\n", (long int) time(NULL));
1177 ZERO_STRUCT(u);
1179 switch (level) {
1180 case 18:
1181 E_md4hash(newpass, nt_hash);
1182 E_deshash(newpass, lm_hash);
1184 u.info18.nt_pwd_active = true;
1185 u.info18.lm_pwd_active = true;
1186 u.info18.password_expired = password_expired;
1188 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1189 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1191 break;
1192 case 21:
1193 E_md4hash(newpass, nt_hash);
1194 E_deshash(newpass, lm_hash);
1196 u.info21.fields_present = fields_present;
1197 u.info21.password_expired = password_expired;
1198 u.info21.comment.string = comment;
1200 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1201 u.info21.lm_owf_password.length = 16;
1202 u.info21.lm_owf_password.size = 16;
1203 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1204 u.info21.lm_password_set = true;
1207 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1208 u.info21.nt_owf_password.length = 16;
1209 u.info21.nt_owf_password.size = 16;
1210 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1211 u.info21.nt_password_set = true;
1214 break;
1215 case 23:
1216 u.info23.info.fields_present = fields_present;
1217 u.info23.info.password_expired = password_expired;
1218 u.info23.info.comment.string = comment;
1220 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1222 break;
1223 case 24:
1224 u.info24.password_expired = password_expired;
1226 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1228 break;
1229 case 25:
1230 u.info25.info.fields_present = fields_present;
1231 u.info25.info.password_expired = password_expired;
1232 u.info25.info.comment.string = comment;
1234 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1236 break;
1237 case 26:
1238 u.info26.password_expired = password_expired;
1240 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1242 break;
1245 status = dcerpc_fetch_session_key(p, &session_key);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1248 s.in.level, nt_errstr(status));
1249 return false;
1252 generate_random_buffer((uint8_t *)confounder, 16);
1254 MD5Init(&ctx);
1255 MD5Update(&ctx, confounder, 16);
1256 MD5Update(&ctx, session_key.data, session_key.length);
1257 MD5Final(confounded_session_key.data, &ctx);
1259 switch (level) {
1260 case 18:
1262 DATA_BLOB in,out;
1263 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1264 out = data_blob_talloc_zero(tctx, 16);
1265 sess_crypt_blob(&out, &in, &session_key, true);
1266 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1269 DATA_BLOB in,out;
1270 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1271 out = data_blob_talloc_zero(tctx, 16);
1272 sess_crypt_blob(&out, &in, &session_key, true);
1273 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1276 break;
1277 case 21:
1278 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1279 DATA_BLOB in,out;
1280 in = data_blob_const(u.info21.lm_owf_password.array,
1281 u.info21.lm_owf_password.length);
1282 out = data_blob_talloc_zero(tctx, 16);
1283 sess_crypt_blob(&out, &in, &session_key, true);
1284 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1286 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1287 DATA_BLOB in,out;
1288 in = data_blob_const(u.info21.nt_owf_password.array,
1289 u.info21.nt_owf_password.length);
1290 out = data_blob_talloc_zero(tctx, 16);
1291 sess_crypt_blob(&out, &in, &session_key, true);
1292 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1294 break;
1295 case 23:
1296 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1297 break;
1298 case 24:
1299 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1300 break;
1301 case 25:
1302 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1303 memcpy(&u.info25.password.data[516], confounder, 16);
1304 break;
1305 case 26:
1306 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1307 memcpy(&u.info26.password.data[516], confounder, 16);
1308 break;
1311 if (use_setinfo2) {
1312 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
1313 "SetUserInfo2 failed");
1314 status = s2.out.result;
1315 } else {
1316 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1317 "SetUserInfo failed");
1318 status = s.out.result;
1321 if (!NT_STATUS_IS_OK(status)) {
1322 if (fields_present == 0) {
1323 expected_error = NT_STATUS_INVALID_PARAMETER;
1325 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1326 expected_error = NT_STATUS_ACCESS_DENIED;
1330 if (!NT_STATUS_IS_OK(expected_error)) {
1331 if (use_setinfo2) {
1332 torture_assert_ntstatus_equal(tctx,
1333 s2.out.result,
1334 expected_error, "SetUserInfo2 failed");
1335 } else {
1336 torture_assert_ntstatus_equal(tctx,
1337 s.out.result,
1338 expected_error, "SetUserInfo failed");
1340 *matched_expected_error = true;
1341 return true;
1344 if (!NT_STATUS_IS_OK(status)) {
1345 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1346 use_setinfo2 ? "2":"", level, nt_errstr(status));
1347 ret = false;
1348 } else {
1349 *password = newpass;
1352 return ret;
1355 static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
1356 struct torture_context *tctx,
1357 struct policy_handle *handle)
1359 struct samr_SetAliasInfo r;
1360 struct samr_QueryAliasInfo q;
1361 union samr_AliasInfo *info;
1362 uint16_t levels[] = {2, 3};
1363 int i;
1364 bool ret = true;
1366 /* Ignoring switch level 1, as that includes the number of members for the alias
1367 * and setting this to a wrong value might have negative consequences
1370 for (i=0;i<ARRAY_SIZE(levels);i++) {
1371 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1373 r.in.alias_handle = handle;
1374 r.in.level = levels[i];
1375 r.in.info = talloc(tctx, union samr_AliasInfo);
1376 switch (r.in.level) {
1377 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1378 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1379 "Test Description, should test I18N as well"); break;
1380 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1383 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
1384 "SetAliasInfo failed");
1385 if (!NT_STATUS_IS_OK(r.out.result)) {
1386 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1387 levels[i], nt_errstr(r.out.result));
1388 ret = false;
1391 q.in.alias_handle = handle;
1392 q.in.level = levels[i];
1393 q.out.info = &info;
1395 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
1396 "QueryAliasInfo failed");
1397 if (!NT_STATUS_IS_OK(q.out.result)) {
1398 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1399 levels[i], nt_errstr(q.out.result));
1400 ret = false;
1404 return ret;
1407 static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
1408 struct torture_context *tctx,
1409 struct policy_handle *user_handle)
1411 struct samr_GetGroupsForUser r;
1412 struct samr_RidWithAttributeArray *rids = NULL;
1414 torture_comment(tctx, "Testing GetGroupsForUser\n");
1416 r.in.user_handle = user_handle;
1417 r.out.rids = &rids;
1419 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
1420 "GetGroupsForUser failed");
1421 torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
1423 return true;
1427 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1428 struct lsa_String *domain_name)
1430 struct samr_GetDomPwInfo r;
1431 struct samr_PwInfo info;
1432 struct dcerpc_binding_handle *b = p->binding_handle;
1434 r.in.domain_name = domain_name;
1435 r.out.info = &info;
1437 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1439 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1440 "GetDomPwInfo failed");
1441 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1443 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1444 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1446 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1447 "GetDomPwInfo failed");
1448 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1450 r.in.domain_name->string = "\\\\__NONAME__";
1451 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1453 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1454 "GetDomPwInfo failed");
1455 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1457 r.in.domain_name->string = "\\\\Builtin";
1458 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1460 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1461 "GetDomPwInfo failed");
1462 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1464 return true;
1467 static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
1468 struct torture_context *tctx,
1469 struct policy_handle *handle)
1471 struct samr_GetUserPwInfo r;
1472 struct samr_PwInfo info;
1474 torture_comment(tctx, "Testing GetUserPwInfo\n");
1476 r.in.user_handle = handle;
1477 r.out.info = &info;
1479 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
1480 "GetUserPwInfo failed");
1481 torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
1483 return true;
1486 static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
1487 struct torture_context *tctx,
1488 struct policy_handle *domain_handle, const char *name,
1489 uint32_t *rid)
1491 NTSTATUS status;
1492 struct samr_LookupNames n;
1493 struct lsa_String sname[2];
1494 struct samr_Ids rids, types;
1496 init_lsa_String(&sname[0], name);
1498 n.in.domain_handle = domain_handle;
1499 n.in.num_names = 1;
1500 n.in.names = sname;
1501 n.out.rids = &rids;
1502 n.out.types = &types;
1503 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1504 if (!NT_STATUS_IS_OK(status)) {
1505 return status;
1507 if (NT_STATUS_IS_OK(n.out.result)) {
1508 *rid = n.out.rids->ids[0];
1509 } else {
1510 return n.out.result;
1513 init_lsa_String(&sname[1], "xxNONAMExx");
1514 n.in.num_names = 2;
1515 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1516 if (!NT_STATUS_IS_OK(status)) {
1517 return status;
1519 if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
1520 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
1521 if (NT_STATUS_IS_OK(n.out.result)) {
1522 return NT_STATUS_UNSUCCESSFUL;
1524 return n.out.result;
1527 n.in.num_names = 0;
1528 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1529 if (!NT_STATUS_IS_OK(status)) {
1530 return status;
1532 if (!NT_STATUS_IS_OK(n.out.result)) {
1533 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1534 return n.out.result;
1537 init_lsa_String(&sname[0], "xxNONAMExx");
1538 n.in.num_names = 1;
1539 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1540 if (!NT_STATUS_IS_OK(status)) {
1541 return status;
1543 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1544 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
1545 if (NT_STATUS_IS_OK(n.out.result)) {
1546 return NT_STATUS_UNSUCCESSFUL;
1548 return n.out.result;
1551 init_lsa_String(&sname[0], "xxNONAMExx");
1552 init_lsa_String(&sname[1], "xxNONAME2xx");
1553 n.in.num_names = 2;
1554 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1555 if (!NT_STATUS_IS_OK(status)) {
1556 return status;
1558 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1559 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
1560 if (NT_STATUS_IS_OK(n.out.result)) {
1561 return NT_STATUS_UNSUCCESSFUL;
1563 return n.out.result;
1566 return NT_STATUS_OK;
1569 static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
1570 struct torture_context *tctx,
1571 struct policy_handle *domain_handle,
1572 const char *name, struct policy_handle *user_handle)
1574 NTSTATUS status;
1575 struct samr_OpenUser r;
1576 uint32_t rid;
1578 status = test_LookupName(b, tctx, domain_handle, name, &rid);
1579 if (!NT_STATUS_IS_OK(status)) {
1580 return status;
1583 r.in.domain_handle = domain_handle;
1584 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1585 r.in.rid = rid;
1586 r.out.user_handle = user_handle;
1587 status = dcerpc_samr_OpenUser_r(b, tctx, &r);
1588 if (!NT_STATUS_IS_OK(status)) {
1589 return status;
1591 if (!NT_STATUS_IS_OK(r.out.result)) {
1592 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
1595 return r.out.result;
1598 #if 0
1599 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1600 struct torture_context *tctx,
1601 struct policy_handle *handle)
1603 NTSTATUS status;
1604 struct samr_ChangePasswordUser r;
1605 bool ret = true;
1606 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1607 struct policy_handle user_handle;
1608 char *oldpass = "test";
1609 char *newpass = "test2";
1610 uint8_t old_nt_hash[16], new_nt_hash[16];
1611 uint8_t old_lm_hash[16], new_lm_hash[16];
1613 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 return false;
1618 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1620 torture_comment(tctx, "old password: %s\n", oldpass);
1621 torture_comment(tctx, "new password: %s\n", newpass);
1623 E_md4hash(oldpass, old_nt_hash);
1624 E_md4hash(newpass, new_nt_hash);
1625 E_deshash(oldpass, old_lm_hash);
1626 E_deshash(newpass, new_lm_hash);
1628 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1629 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1630 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1631 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1632 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1633 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1635 r.in.handle = &user_handle;
1636 r.in.lm_present = 1;
1637 r.in.old_lm_crypted = &hash1;
1638 r.in.new_lm_crypted = &hash2;
1639 r.in.nt_present = 1;
1640 r.in.old_nt_crypted = &hash3;
1641 r.in.new_nt_crypted = &hash4;
1642 r.in.cross1_present = 1;
1643 r.in.nt_cross = &hash5;
1644 r.in.cross2_present = 1;
1645 r.in.lm_cross = &hash6;
1647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1648 "ChangePasswordUser failed");
1649 if (!NT_STATUS_IS_OK(r.out.result)) {
1650 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1651 ret = false;
1654 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1655 ret = false;
1658 return ret;
1660 #endif
1662 static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
1663 struct torture_context *tctx,
1664 const char *acct_name,
1665 struct policy_handle *handle, char **password)
1667 NTSTATUS status;
1668 struct samr_ChangePasswordUser r;
1669 bool ret = true;
1670 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1671 struct policy_handle user_handle;
1672 char *oldpass;
1673 uint8_t old_nt_hash[16], new_nt_hash[16];
1674 uint8_t old_lm_hash[16], new_lm_hash[16];
1675 bool changed = true;
1677 char *newpass;
1678 struct samr_GetUserPwInfo pwp;
1679 struct samr_PwInfo info;
1680 int policy_min_pw_len = 0;
1682 status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
1683 if (!NT_STATUS_IS_OK(status)) {
1684 return false;
1686 pwp.in.user_handle = &user_handle;
1687 pwp.out.info = &info;
1689 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1690 "GetUserPwInfo failed");
1691 if (NT_STATUS_IS_OK(pwp.out.result)) {
1692 policy_min_pw_len = pwp.out.info->min_password_length;
1694 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1696 torture_comment(tctx, "Testing ChangePasswordUser\n");
1698 torture_assert(tctx, *password != NULL,
1699 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1701 oldpass = *password;
1703 E_md4hash(oldpass, old_nt_hash);
1704 E_md4hash(newpass, new_nt_hash);
1705 E_deshash(oldpass, old_lm_hash);
1706 E_deshash(newpass, new_lm_hash);
1708 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1709 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1710 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1711 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1712 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1713 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1715 r.in.user_handle = &user_handle;
1716 r.in.lm_present = 1;
1717 /* Break the LM hash */
1718 hash1.hash[0]++;
1719 r.in.old_lm_crypted = &hash1;
1720 r.in.new_lm_crypted = &hash2;
1721 r.in.nt_present = 1;
1722 r.in.old_nt_crypted = &hash3;
1723 r.in.new_nt_crypted = &hash4;
1724 r.in.cross1_present = 1;
1725 r.in.nt_cross = &hash5;
1726 r.in.cross2_present = 1;
1727 r.in.lm_cross = &hash6;
1729 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1730 "ChangePasswordUser failed");
1731 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1732 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1734 /* Unbreak the LM hash */
1735 hash1.hash[0]--;
1737 r.in.user_handle = &user_handle;
1738 r.in.lm_present = 1;
1739 r.in.old_lm_crypted = &hash1;
1740 r.in.new_lm_crypted = &hash2;
1741 /* Break the NT hash */
1742 hash3.hash[0]--;
1743 r.in.nt_present = 1;
1744 r.in.old_nt_crypted = &hash3;
1745 r.in.new_nt_crypted = &hash4;
1746 r.in.cross1_present = 1;
1747 r.in.nt_cross = &hash5;
1748 r.in.cross2_present = 1;
1749 r.in.lm_cross = &hash6;
1751 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1752 "ChangePasswordUser failed");
1753 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1754 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1756 /* Unbreak the NT hash */
1757 hash3.hash[0]--;
1759 r.in.user_handle = &user_handle;
1760 r.in.lm_present = 1;
1761 r.in.old_lm_crypted = &hash1;
1762 r.in.new_lm_crypted = &hash2;
1763 r.in.nt_present = 1;
1764 r.in.old_nt_crypted = &hash3;
1765 r.in.new_nt_crypted = &hash4;
1766 r.in.cross1_present = 1;
1767 r.in.nt_cross = &hash5;
1768 r.in.cross2_present = 1;
1769 /* Break the LM cross */
1770 hash6.hash[0]++;
1771 r.in.lm_cross = &hash6;
1773 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1774 "ChangePasswordUser failed");
1775 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1776 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(r.out.result));
1777 ret = false;
1780 /* Unbreak the LM cross */
1781 hash6.hash[0]--;
1783 r.in.user_handle = &user_handle;
1784 r.in.lm_present = 1;
1785 r.in.old_lm_crypted = &hash1;
1786 r.in.new_lm_crypted = &hash2;
1787 r.in.nt_present = 1;
1788 r.in.old_nt_crypted = &hash3;
1789 r.in.new_nt_crypted = &hash4;
1790 r.in.cross1_present = 1;
1791 /* Break the NT cross */
1792 hash5.hash[0]++;
1793 r.in.nt_cross = &hash5;
1794 r.in.cross2_present = 1;
1795 r.in.lm_cross = &hash6;
1797 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1798 "ChangePasswordUser failed");
1799 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1800 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(r.out.result));
1801 ret = false;
1804 /* Unbreak the NT cross */
1805 hash5.hash[0]--;
1808 /* Reset the hashes to not broken values */
1809 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1810 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1811 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1812 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1813 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1814 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1816 r.in.user_handle = &user_handle;
1817 r.in.lm_present = 1;
1818 r.in.old_lm_crypted = &hash1;
1819 r.in.new_lm_crypted = &hash2;
1820 r.in.nt_present = 1;
1821 r.in.old_nt_crypted = &hash3;
1822 r.in.new_nt_crypted = &hash4;
1823 r.in.cross1_present = 1;
1824 r.in.nt_cross = &hash5;
1825 r.in.cross2_present = 0;
1826 r.in.lm_cross = NULL;
1828 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1829 "ChangePasswordUser failed");
1830 if (NT_STATUS_IS_OK(r.out.result)) {
1831 changed = true;
1832 *password = newpass;
1833 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1834 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1835 ret = false;
1838 oldpass = newpass;
1839 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1841 E_md4hash(oldpass, old_nt_hash);
1842 E_md4hash(newpass, new_nt_hash);
1843 E_deshash(oldpass, old_lm_hash);
1844 E_deshash(newpass, new_lm_hash);
1847 /* Reset the hashes to not broken values */
1848 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1849 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1850 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1851 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1852 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1853 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1855 r.in.user_handle = &user_handle;
1856 r.in.lm_present = 1;
1857 r.in.old_lm_crypted = &hash1;
1858 r.in.new_lm_crypted = &hash2;
1859 r.in.nt_present = 1;
1860 r.in.old_nt_crypted = &hash3;
1861 r.in.new_nt_crypted = &hash4;
1862 r.in.cross1_present = 0;
1863 r.in.nt_cross = NULL;
1864 r.in.cross2_present = 1;
1865 r.in.lm_cross = &hash6;
1867 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1868 "ChangePasswordUser failed");
1869 if (NT_STATUS_IS_OK(r.out.result)) {
1870 changed = true;
1871 *password = newpass;
1872 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1873 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1874 ret = false;
1877 oldpass = newpass;
1878 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1880 E_md4hash(oldpass, old_nt_hash);
1881 E_md4hash(newpass, new_nt_hash);
1882 E_deshash(oldpass, old_lm_hash);
1883 E_deshash(newpass, new_lm_hash);
1886 /* Reset the hashes to not broken values */
1887 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1888 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1889 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1890 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1891 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1892 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1894 r.in.user_handle = &user_handle;
1895 r.in.lm_present = 1;
1896 r.in.old_lm_crypted = &hash1;
1897 r.in.new_lm_crypted = &hash2;
1898 r.in.nt_present = 1;
1899 r.in.old_nt_crypted = &hash3;
1900 r.in.new_nt_crypted = &hash4;
1901 r.in.cross1_present = 1;
1902 r.in.nt_cross = &hash5;
1903 r.in.cross2_present = 1;
1904 r.in.lm_cross = &hash6;
1906 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1907 "ChangePasswordUser failed");
1908 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1909 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1910 } else if (!NT_STATUS_IS_OK(r.out.result)) {
1911 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1912 ret = false;
1913 } else {
1914 changed = true;
1915 *password = newpass;
1918 r.in.user_handle = &user_handle;
1919 r.in.lm_present = 1;
1920 r.in.old_lm_crypted = &hash1;
1921 r.in.new_lm_crypted = &hash2;
1922 r.in.nt_present = 1;
1923 r.in.old_nt_crypted = &hash3;
1924 r.in.new_nt_crypted = &hash4;
1925 r.in.cross1_present = 1;
1926 r.in.nt_cross = &hash5;
1927 r.in.cross2_present = 1;
1928 r.in.lm_cross = &hash6;
1930 if (changed) {
1931 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1932 "ChangePasswordUser failed");
1933 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1934 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1935 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1936 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
1937 ret = false;
1942 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
1943 ret = false;
1946 return ret;
1950 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
1951 struct torture_context *tctx,
1952 const char *acct_name,
1953 struct policy_handle *handle, char **password)
1955 struct samr_OemChangePasswordUser2 r;
1956 bool ret = true;
1957 struct samr_Password lm_verifier;
1958 struct samr_CryptPassword lm_pass;
1959 struct lsa_AsciiString server, account, account_bad;
1960 char *oldpass;
1961 char *newpass;
1962 struct dcerpc_binding_handle *b = p->binding_handle;
1963 uint8_t old_lm_hash[16], new_lm_hash[16];
1965 struct samr_GetDomPwInfo dom_pw_info;
1966 struct samr_PwInfo info;
1967 int policy_min_pw_len = 0;
1969 struct lsa_String domain_name;
1971 domain_name.string = "";
1972 dom_pw_info.in.domain_name = &domain_name;
1973 dom_pw_info.out.info = &info;
1975 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1977 torture_assert(tctx, *password != NULL,
1978 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1980 oldpass = *password;
1982 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
1983 "GetDomPwInfo failed");
1984 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
1985 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1988 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1990 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1991 account.string = acct_name;
1993 E_deshash(oldpass, old_lm_hash);
1994 E_deshash(newpass, new_lm_hash);
1996 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1997 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1998 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2000 r.in.server = &server;
2001 r.in.account = &account;
2002 r.in.password = &lm_pass;
2003 r.in.hash = &lm_verifier;
2005 /* Break the verification */
2006 lm_verifier.hash[0]++;
2008 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2009 "OemChangePasswordUser2 failed");
2011 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2012 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2013 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2014 nt_errstr(r.out.result));
2015 ret = false;
2018 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2019 /* Break the old password */
2020 old_lm_hash[0]++;
2021 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2022 /* unbreak it for the next operation */
2023 old_lm_hash[0]--;
2024 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2026 r.in.server = &server;
2027 r.in.account = &account;
2028 r.in.password = &lm_pass;
2029 r.in.hash = &lm_verifier;
2031 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2032 "OemChangePasswordUser2 failed");
2034 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2035 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2036 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2037 nt_errstr(r.out.result));
2038 ret = false;
2041 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2042 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2044 r.in.server = &server;
2045 r.in.account = &account;
2046 r.in.password = &lm_pass;
2047 r.in.hash = NULL;
2049 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2050 "OemChangePasswordUser2 failed");
2052 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2053 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2054 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2055 nt_errstr(r.out.result));
2056 ret = false;
2059 /* This shouldn't be a valid name */
2060 account_bad.string = TEST_ACCOUNT_NAME "XX";
2061 r.in.account = &account_bad;
2063 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2064 "OemChangePasswordUser2 failed");
2066 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2067 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2068 nt_errstr(r.out.result));
2069 ret = false;
2072 /* This shouldn't be a valid name */
2073 account_bad.string = TEST_ACCOUNT_NAME "XX";
2074 r.in.account = &account_bad;
2075 r.in.password = &lm_pass;
2076 r.in.hash = &lm_verifier;
2078 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2079 "OemChangePasswordUser2 failed");
2081 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2082 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2083 nt_errstr(r.out.result));
2084 ret = false;
2087 /* This shouldn't be a valid name */
2088 account_bad.string = TEST_ACCOUNT_NAME "XX";
2089 r.in.account = &account_bad;
2090 r.in.password = NULL;
2091 r.in.hash = &lm_verifier;
2093 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2094 "OemChangePasswordUser2 failed");
2096 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2097 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2098 nt_errstr(r.out.result));
2099 ret = false;
2102 E_deshash(oldpass, old_lm_hash);
2103 E_deshash(newpass, new_lm_hash);
2105 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2106 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2107 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2109 r.in.server = &server;
2110 r.in.account = &account;
2111 r.in.password = &lm_pass;
2112 r.in.hash = &lm_verifier;
2114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2115 "OemChangePasswordUser2 failed");
2117 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2118 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2119 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2120 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2121 ret = false;
2122 } else {
2123 *password = newpass;
2126 return ret;
2130 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2131 const char *acct_name,
2132 char **password,
2133 char *newpass, bool allow_password_restriction)
2135 struct samr_ChangePasswordUser2 r;
2136 bool ret = true;
2137 struct lsa_String server, account;
2138 struct samr_CryptPassword nt_pass, lm_pass;
2139 struct samr_Password nt_verifier, lm_verifier;
2140 char *oldpass;
2141 struct dcerpc_binding_handle *b = p->binding_handle;
2142 uint8_t old_nt_hash[16], new_nt_hash[16];
2143 uint8_t old_lm_hash[16], new_lm_hash[16];
2145 struct samr_GetDomPwInfo dom_pw_info;
2146 struct samr_PwInfo info;
2148 struct lsa_String domain_name;
2150 domain_name.string = "";
2151 dom_pw_info.in.domain_name = &domain_name;
2152 dom_pw_info.out.info = &info;
2154 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2156 torture_assert(tctx, *password != NULL,
2157 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2158 oldpass = *password;
2160 if (!newpass) {
2161 int policy_min_pw_len = 0;
2162 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2163 "GetDomPwInfo failed");
2164 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2165 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2168 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2171 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2172 init_lsa_String(&account, acct_name);
2174 E_md4hash(oldpass, old_nt_hash);
2175 E_md4hash(newpass, new_nt_hash);
2177 E_deshash(oldpass, old_lm_hash);
2178 E_deshash(newpass, new_lm_hash);
2180 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2181 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2182 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2184 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2185 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2186 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2188 r.in.server = &server;
2189 r.in.account = &account;
2190 r.in.nt_password = &nt_pass;
2191 r.in.nt_verifier = &nt_verifier;
2192 r.in.lm_change = 1;
2193 r.in.lm_password = &lm_pass;
2194 r.in.lm_verifier = &lm_verifier;
2196 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2197 "ChangePasswordUser2 failed");
2199 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2200 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2201 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2202 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2203 ret = false;
2204 } else {
2205 *password = newpass;
2208 return ret;
2212 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2213 const char *account_string,
2214 int policy_min_pw_len,
2215 char **password,
2216 const char *newpass,
2217 NTTIME last_password_change,
2218 bool handle_reject_reason)
2220 struct samr_ChangePasswordUser3 r;
2221 bool ret = true;
2222 struct lsa_String server, account, account_bad;
2223 struct samr_CryptPassword nt_pass, lm_pass;
2224 struct samr_Password nt_verifier, lm_verifier;
2225 char *oldpass;
2226 struct dcerpc_binding_handle *b = p->binding_handle;
2227 uint8_t old_nt_hash[16], new_nt_hash[16];
2228 uint8_t old_lm_hash[16], new_lm_hash[16];
2229 NTTIME t;
2230 struct samr_DomInfo1 *dominfo = NULL;
2231 struct userPwdChangeFailureInformation *reject = NULL;
2233 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2235 if (newpass == NULL) {
2236 do {
2237 if (policy_min_pw_len == 0) {
2238 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2239 } else {
2240 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2242 } while (check_password_quality(newpass) == false);
2243 } else {
2244 torture_comment(tctx, "Using password '%s'\n", newpass);
2247 torture_assert(tctx, *password != NULL,
2248 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2250 oldpass = *password;
2251 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2252 init_lsa_String(&account, account_string);
2254 E_md4hash(oldpass, old_nt_hash);
2255 E_md4hash(newpass, new_nt_hash);
2257 E_deshash(oldpass, old_lm_hash);
2258 E_deshash(newpass, new_lm_hash);
2260 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2261 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2262 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2264 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2265 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2266 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2268 /* Break the verification */
2269 nt_verifier.hash[0]++;
2271 r.in.server = &server;
2272 r.in.account = &account;
2273 r.in.nt_password = &nt_pass;
2274 r.in.nt_verifier = &nt_verifier;
2275 r.in.lm_change = 1;
2276 r.in.lm_password = &lm_pass;
2277 r.in.lm_verifier = &lm_verifier;
2278 r.in.password3 = NULL;
2279 r.out.dominfo = &dominfo;
2280 r.out.reject = &reject;
2282 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2283 "ChangePasswordUser3 failed");
2284 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2285 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2286 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2287 nt_errstr(r.out.result));
2288 ret = false;
2291 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2292 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2293 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2295 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2296 /* Break the NT hash */
2297 old_nt_hash[0]++;
2298 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2299 /* Unbreak it again */
2300 old_nt_hash[0]--;
2301 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2303 r.in.server = &server;
2304 r.in.account = &account;
2305 r.in.nt_password = &nt_pass;
2306 r.in.nt_verifier = &nt_verifier;
2307 r.in.lm_change = 1;
2308 r.in.lm_password = &lm_pass;
2309 r.in.lm_verifier = &lm_verifier;
2310 r.in.password3 = NULL;
2311 r.out.dominfo = &dominfo;
2312 r.out.reject = &reject;
2314 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2315 "ChangePasswordUser3 failed");
2316 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2317 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2318 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2319 nt_errstr(r.out.result));
2320 ret = false;
2323 /* This shouldn't be a valid name */
2324 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2326 r.in.account = &account_bad;
2327 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2328 "ChangePasswordUser3 failed");
2329 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2330 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2331 nt_errstr(r.out.result));
2332 ret = false;
2335 E_md4hash(oldpass, old_nt_hash);
2336 E_md4hash(newpass, new_nt_hash);
2338 E_deshash(oldpass, old_lm_hash);
2339 E_deshash(newpass, new_lm_hash);
2341 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2342 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2343 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2345 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2346 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2347 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2349 r.in.server = &server;
2350 r.in.account = &account;
2351 r.in.nt_password = &nt_pass;
2352 r.in.nt_verifier = &nt_verifier;
2353 r.in.lm_change = 1;
2354 r.in.lm_password = &lm_pass;
2355 r.in.lm_verifier = &lm_verifier;
2356 r.in.password3 = NULL;
2357 r.out.dominfo = &dominfo;
2358 r.out.reject = &reject;
2360 unix_to_nt_time(&t, time(NULL));
2362 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2363 "ChangePasswordUser3 failed");
2365 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2366 && dominfo
2367 && reject
2368 && handle_reject_reason
2369 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2370 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2372 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2373 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2374 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2375 return false;
2379 /* We tested the order of precendence which is as follows:
2381 * pwd min_age
2382 * pwd length
2383 * pwd complexity
2384 * pwd history
2386 Guenther */
2388 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2389 (last_password_change + dominfo->min_password_age > t)) {
2391 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2392 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2393 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2394 return false;
2397 } else if ((dominfo->min_password_length > 0) &&
2398 (strlen(newpass) < dominfo->min_password_length)) {
2400 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2401 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2402 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2403 return false;
2406 } else if ((dominfo->password_history_length > 0) &&
2407 strequal(oldpass, newpass)) {
2409 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2410 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2411 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2412 return false;
2414 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2416 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2417 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2418 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2419 return false;
2424 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2425 /* retry with adjusted size */
2426 return test_ChangePasswordUser3(p, tctx, account_string,
2427 dominfo->min_password_length,
2428 password, NULL, 0, false);
2432 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2433 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2434 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2435 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2436 return false;
2438 /* Perhaps the server has a 'min password age' set? */
2440 } else {
2441 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2443 *password = talloc_strdup(tctx, newpass);
2446 return ret;
2449 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2450 const char *account_string,
2451 struct policy_handle *handle,
2452 char **password)
2454 NTSTATUS status;
2455 struct samr_ChangePasswordUser3 r;
2456 struct samr_SetUserInfo s;
2457 union samr_UserInfo u;
2458 DATA_BLOB session_key;
2459 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2460 uint8_t confounder[16];
2461 struct MD5Context ctx;
2463 bool ret = true;
2464 struct lsa_String server, account;
2465 struct samr_CryptPassword nt_pass;
2466 struct samr_Password nt_verifier;
2467 DATA_BLOB new_random_pass;
2468 char *newpass;
2469 char *oldpass;
2470 struct dcerpc_binding_handle *b = p->binding_handle;
2471 uint8_t old_nt_hash[16], new_nt_hash[16];
2472 NTTIME t;
2473 struct samr_DomInfo1 *dominfo = NULL;
2474 struct userPwdChangeFailureInformation *reject = NULL;
2476 new_random_pass = samr_very_rand_pass(tctx, 128);
2478 torture_assert(tctx, *password != NULL,
2479 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2481 oldpass = *password;
2482 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2483 init_lsa_String(&account, account_string);
2485 s.in.user_handle = handle;
2486 s.in.info = &u;
2487 s.in.level = 25;
2489 ZERO_STRUCT(u);
2491 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2493 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2495 status = dcerpc_fetch_session_key(p, &session_key);
2496 if (!NT_STATUS_IS_OK(status)) {
2497 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2498 s.in.level, nt_errstr(status));
2499 return false;
2502 generate_random_buffer((uint8_t *)confounder, 16);
2504 MD5Init(&ctx);
2505 MD5Update(&ctx, confounder, 16);
2506 MD5Update(&ctx, session_key.data, session_key.length);
2507 MD5Final(confounded_session_key.data, &ctx);
2509 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2510 memcpy(&u.info25.password.data[516], confounder, 16);
2512 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2514 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2515 "SetUserInfo failed");
2516 if (!NT_STATUS_IS_OK(s.out.result)) {
2517 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2518 s.in.level, nt_errstr(s.out.result));
2519 ret = false;
2522 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2524 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2526 new_random_pass = samr_very_rand_pass(tctx, 128);
2528 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2530 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2531 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2532 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2534 r.in.server = &server;
2535 r.in.account = &account;
2536 r.in.nt_password = &nt_pass;
2537 r.in.nt_verifier = &nt_verifier;
2538 r.in.lm_change = 0;
2539 r.in.lm_password = NULL;
2540 r.in.lm_verifier = NULL;
2541 r.in.password3 = NULL;
2542 r.out.dominfo = &dominfo;
2543 r.out.reject = &reject;
2545 unix_to_nt_time(&t, time(NULL));
2547 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2548 "ChangePasswordUser3 failed");
2550 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2551 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2552 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2553 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2554 return false;
2556 /* Perhaps the server has a 'min password age' set? */
2558 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2559 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2560 ret = false;
2563 newpass = samr_rand_pass(tctx, 128);
2565 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2567 E_md4hash(newpass, new_nt_hash);
2569 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2570 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2571 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2573 r.in.server = &server;
2574 r.in.account = &account;
2575 r.in.nt_password = &nt_pass;
2576 r.in.nt_verifier = &nt_verifier;
2577 r.in.lm_change = 0;
2578 r.in.lm_password = NULL;
2579 r.in.lm_verifier = NULL;
2580 r.in.password3 = NULL;
2581 r.out.dominfo = &dominfo;
2582 r.out.reject = &reject;
2584 unix_to_nt_time(&t, time(NULL));
2586 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2587 "ChangePasswordUser3 failed");
2589 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2590 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2591 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2592 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2593 return false;
2595 /* Perhaps the server has a 'min password age' set? */
2597 } else {
2598 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2599 *password = talloc_strdup(tctx, newpass);
2602 return ret;
2606 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2607 struct torture_context *tctx,
2608 struct policy_handle *alias_handle)
2610 struct samr_GetMembersInAlias r;
2611 struct lsa_SidArray sids;
2613 torture_comment(tctx, "Testing GetMembersInAlias\n");
2615 r.in.alias_handle = alias_handle;
2616 r.out.sids = &sids;
2618 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2619 "GetMembersInAlias failed");
2620 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2622 return true;
2625 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2626 struct torture_context *tctx,
2627 struct policy_handle *alias_handle,
2628 const struct dom_sid *domain_sid)
2630 struct samr_AddAliasMember r;
2631 struct samr_DeleteAliasMember d;
2632 struct dom_sid *sid;
2634 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2636 torture_comment(tctx, "Testing AddAliasMember\n");
2637 r.in.alias_handle = alias_handle;
2638 r.in.sid = sid;
2640 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2641 "AddAliasMember failed");
2642 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2644 d.in.alias_handle = alias_handle;
2645 d.in.sid = sid;
2647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2648 "DeleteAliasMember failed");
2649 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2651 return true;
2654 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2655 struct torture_context *tctx,
2656 struct policy_handle *alias_handle)
2658 struct samr_AddMultipleMembersToAlias a;
2659 struct samr_RemoveMultipleMembersFromAlias r;
2660 struct lsa_SidArray sids;
2662 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2663 a.in.alias_handle = alias_handle;
2664 a.in.sids = &sids;
2666 sids.num_sids = 3;
2667 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2669 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2670 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2671 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2673 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2674 "AddMultipleMembersToAlias failed");
2675 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2678 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2679 r.in.alias_handle = alias_handle;
2680 r.in.sids = &sids;
2682 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2683 "RemoveMultipleMembersFromAlias failed");
2684 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2686 /* strange! removing twice doesn't give any error */
2687 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2688 "RemoveMultipleMembersFromAlias failed");
2689 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2691 /* but removing an alias that isn't there does */
2692 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2694 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2695 "RemoveMultipleMembersFromAlias failed");
2696 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2698 return true;
2701 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2702 struct torture_context *tctx,
2703 struct policy_handle *domain_handle)
2705 struct samr_GetAliasMembership r;
2706 struct lsa_SidArray sids;
2707 struct samr_Ids rids;
2709 torture_comment(tctx, "Testing GetAliasMembership\n");
2711 r.in.domain_handle = domain_handle;
2712 r.in.sids = &sids;
2713 r.out.rids = &rids;
2715 sids.num_sids = 0;
2716 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2718 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2719 "GetAliasMembership failed");
2720 torture_assert_ntstatus_ok(tctx, r.out.result,
2721 "samr_GetAliasMembership failed");
2723 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2724 "protocol misbehaviour");
2726 sids.num_sids = 1;
2727 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2728 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2730 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2731 "samr_GetAliasMembership failed");
2732 torture_assert_ntstatus_ok(tctx, r.out.result,
2733 "samr_GetAliasMembership failed");
2735 #if 0
2736 /* only true for w2k8 it seems
2737 * win7, xp, w2k3 will return a 0 length array pointer */
2739 if (rids.ids && (rids.count == 0)) {
2740 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2742 #endif
2743 if (!rids.ids && rids.count) {
2744 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2747 return true;
2750 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2751 struct torture_context *tctx,
2752 struct policy_handle *user_handle)
2754 struct samr_TestPrivateFunctionsUser r;
2756 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2758 r.in.user_handle = user_handle;
2760 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2761 "TestPrivateFunctionsUser failed");
2762 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2764 return true;
2767 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2768 struct torture_context *tctx,
2769 struct policy_handle *handle,
2770 bool use_info2,
2771 NTTIME *pwdlastset)
2773 NTSTATUS status;
2774 uint16_t levels[] = { /* 3, */ 5, 21 };
2775 int i;
2776 NTTIME pwdlastset3 = 0;
2777 NTTIME pwdlastset5 = 0;
2778 NTTIME pwdlastset21 = 0;
2780 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2781 use_info2 ? "2":"");
2783 for (i=0; i<ARRAY_SIZE(levels); i++) {
2785 struct samr_QueryUserInfo r;
2786 struct samr_QueryUserInfo2 r2;
2787 union samr_UserInfo *info;
2789 if (use_info2) {
2790 r2.in.user_handle = handle;
2791 r2.in.level = levels[i];
2792 r2.out.info = &info;
2793 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2794 "QueryUserInfo2 failed");
2795 status = r2.out.result;
2797 } else {
2798 r.in.user_handle = handle;
2799 r.in.level = levels[i];
2800 r.out.info = &info;
2801 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2802 "QueryUserInfo failed");
2803 status = r.out.result;
2806 if (!NT_STATUS_IS_OK(status) &&
2807 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2808 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2809 use_info2 ? "2":"", levels[i], nt_errstr(status));
2810 return false;
2813 switch (levels[i]) {
2814 case 3:
2815 pwdlastset3 = info->info3.last_password_change;
2816 break;
2817 case 5:
2818 pwdlastset5 = info->info5.last_password_change;
2819 break;
2820 case 21:
2821 pwdlastset21 = info->info21.last_password_change;
2822 break;
2823 default:
2824 return false;
2827 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2828 "pwdlastset mixup"); */
2829 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2830 "pwdlastset mixup");
2832 *pwdlastset = pwdlastset21;
2834 torture_comment(tctx, "(pwdlastset: %llu)\n",
2835 (unsigned long long) *pwdlastset);
2837 return true;
2840 static bool test_SamLogon(struct torture_context *tctx,
2841 struct dcerpc_pipe *p,
2842 struct cli_credentials *test_credentials,
2843 NTSTATUS expected_result,
2844 bool interactive)
2846 NTSTATUS status;
2847 struct netr_LogonSamLogonEx r;
2848 union netr_LogonLevel logon;
2849 union netr_Validation validation;
2850 uint8_t authoritative;
2851 struct netr_IdentityInfo identity;
2852 struct netr_NetworkInfo ninfo;
2853 struct netr_PasswordInfo pinfo;
2854 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2855 int flags = CLI_CRED_NTLM_AUTH;
2856 uint32_t samlogon_flags = 0;
2857 struct netlogon_creds_CredentialState *creds;
2858 struct netr_Authenticator a;
2859 struct dcerpc_binding_handle *b = p->binding_handle;
2861 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2863 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
2864 flags |= CLI_CRED_LANMAN_AUTH;
2867 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
2868 flags |= CLI_CRED_NTLMv2_AUTH;
2871 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2872 &identity.account_name.string,
2873 &identity.domain_name.string);
2875 identity.parameter_control =
2876 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2877 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2878 identity.logon_id_low = 0;
2879 identity.logon_id_high = 0;
2880 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2882 if (interactive) {
2883 netlogon_creds_client_authenticator(creds, &a);
2885 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2886 ZERO_STRUCT(pinfo.lmpassword.hash);
2888 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2890 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2891 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2892 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2893 } else {
2894 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2895 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2898 pinfo.identity_info = identity;
2899 logon.password = &pinfo;
2901 r.in.logon_level = NetlogonInteractiveInformation;
2902 } else {
2903 generate_random_buffer(ninfo.challenge,
2904 sizeof(ninfo.challenge));
2905 chal = data_blob_const(ninfo.challenge,
2906 sizeof(ninfo.challenge));
2908 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2909 cli_credentials_get_domain(test_credentials));
2911 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2912 &flags,
2913 chal,
2914 names_blob,
2915 &lm_resp, &nt_resp,
2916 NULL, NULL);
2917 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2919 ninfo.lm.data = lm_resp.data;
2920 ninfo.lm.length = lm_resp.length;
2922 ninfo.nt.data = nt_resp.data;
2923 ninfo.nt.length = nt_resp.length;
2925 ninfo.identity_info = identity;
2926 logon.network = &ninfo;
2928 r.in.logon_level = NetlogonNetworkInformation;
2931 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2932 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2933 r.in.logon = &logon;
2934 r.in.flags = &samlogon_flags;
2935 r.out.flags = &samlogon_flags;
2936 r.out.validation = &validation;
2937 r.out.authoritative = &authoritative;
2939 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2941 r.in.validation_level = 6;
2943 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2944 "netr_LogonSamLogonEx failed");
2945 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
2946 r.in.validation_level = 3;
2947 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2948 "netr_LogonSamLogonEx failed");
2950 if (!NT_STATUS_IS_OK(r.out.result)) {
2951 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
2952 return true;
2953 } else {
2954 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
2957 return true;
2960 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2961 struct dcerpc_pipe *p,
2962 struct cli_credentials *machine_creds,
2963 const char *acct_name,
2964 const char *password,
2965 NTSTATUS expected_samlogon_result,
2966 bool interactive)
2968 bool ret = true;
2969 struct cli_credentials *test_credentials;
2971 test_credentials = cli_credentials_init(tctx);
2973 cli_credentials_set_workstation(test_credentials,
2974 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2975 cli_credentials_set_domain(test_credentials,
2976 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2977 cli_credentials_set_username(test_credentials,
2978 acct_name, CRED_SPECIFIED);
2979 cli_credentials_set_password(test_credentials,
2980 password, CRED_SPECIFIED);
2982 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
2983 interactive ? "interactive" : "network", acct_name, password);
2985 if (!test_SamLogon(tctx, p, test_credentials,
2986 expected_samlogon_result, interactive)) {
2987 torture_warning(tctx, "new password did not work\n");
2988 ret = false;
2991 return ret;
2994 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2995 struct dcerpc_pipe *np,
2996 struct torture_context *tctx,
2997 struct policy_handle *handle,
2998 uint16_t level,
2999 uint32_t fields_present,
3000 uint8_t password_expired,
3001 bool *matched_expected_error,
3002 bool use_setinfo2,
3003 const char *acct_name,
3004 char **password,
3005 struct cli_credentials *machine_creds,
3006 bool use_queryinfo2,
3007 NTTIME *pwdlastset,
3008 NTSTATUS expected_samlogon_result)
3010 const char *fields = NULL;
3011 bool ret = true;
3012 struct dcerpc_binding_handle *b = p->binding_handle;
3014 switch (level) {
3015 case 21:
3016 case 23:
3017 case 25:
3018 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3019 fields_present);
3020 break;
3021 default:
3022 break;
3025 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3026 "(password_expired: %d) %s\n",
3027 use_setinfo2 ? "2":"", level, password_expired,
3028 fields ? fields : "");
3030 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3031 fields_present,
3032 password,
3033 password_expired,
3034 use_setinfo2,
3035 matched_expected_error)) {
3036 ret = false;
3039 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3040 use_queryinfo2,
3041 pwdlastset)) {
3042 ret = false;
3045 if (*matched_expected_error == true) {
3046 return ret;
3049 if (!test_SamLogon_with_creds(tctx, np,
3050 machine_creds,
3051 acct_name,
3052 *password,
3053 expected_samlogon_result,
3054 false)) {
3055 ret = false;
3058 return ret;
3061 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3062 struct cli_credentials *credentials,
3063 struct dcerpc_pipe **p)
3065 struct dcerpc_binding *b;
3067 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3068 "failed to get rpc binding");
3070 /* We have to use schannel, otherwise the SamLogonEx fails
3071 * with INTERNAL_ERROR */
3073 b->flags &= ~DCERPC_AUTH_OPTIONS;
3074 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
3076 torture_assert_ntstatus_ok(tctx,
3077 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3078 credentials, tctx->ev, tctx->lp_ctx),
3079 "failed to bind to netlogon");
3081 return true;
3084 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3085 struct torture_context *tctx,
3086 uint32_t acct_flags,
3087 const char *acct_name,
3088 struct policy_handle *handle,
3089 char **password,
3090 struct cli_credentials *machine_credentials)
3092 int s = 0, q = 0, f = 0, l = 0, z = 0;
3093 bool ret = true;
3094 int delay = 50000;
3095 bool set_levels[] = { false, true };
3096 bool query_levels[] = { false, true };
3097 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3098 uint32_t nonzeros[] = { 1, 24 };
3099 uint32_t fields_present[] = {
3101 SAMR_FIELD_EXPIRED_FLAG,
3102 SAMR_FIELD_LAST_PWD_CHANGE,
3103 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3104 SAMR_FIELD_COMMENT,
3105 SAMR_FIELD_NT_PASSWORD_PRESENT,
3106 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3107 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3108 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3109 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3110 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3111 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3113 struct dcerpc_pipe *np = NULL;
3115 if (torture_setting_bool(tctx, "samba3", false) ||
3116 torture_setting_bool(tctx, "samba4", false)) {
3117 delay = 999999;
3118 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3119 delay);
3122 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3124 /* set to 1 to enable testing for all possible opcode
3125 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3126 combinations */
3127 #if 0
3128 #define TEST_ALL_LEVELS 1
3129 #define TEST_SET_LEVELS 1
3130 #define TEST_QUERY_LEVELS 1
3131 #endif
3132 #ifdef TEST_ALL_LEVELS
3133 for (l=0; l<ARRAY_SIZE(levels); l++) {
3134 #else
3135 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3136 #endif
3137 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3138 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3139 #ifdef TEST_SET_LEVELS
3140 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3141 #endif
3142 #ifdef TEST_QUERY_LEVELS
3143 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3144 #endif
3145 NTTIME pwdlastset_old = 0;
3146 NTTIME pwdlastset_new = 0;
3147 bool matched_expected_error = false;
3148 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3150 torture_comment(tctx, "------------------------------\n"
3151 "Testing pwdLastSet attribute for flags: 0x%08x "
3152 "(s: %d (l: %d), q: %d)\n",
3153 acct_flags, s, levels[l], q);
3155 switch (levels[l]) {
3156 case 21:
3157 case 23:
3158 case 25:
3159 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3160 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3161 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3163 break;
3167 /* set #1 */
3169 /* set a password and force password change (pwdlastset 0) by
3170 * setting the password expired flag to a non-0 value */
3172 if (!test_SetPassword_level(p, np, tctx, handle,
3173 levels[l],
3174 fields_present[f],
3175 nonzeros[z],
3176 &matched_expected_error,
3177 set_levels[s],
3178 acct_name,
3179 password,
3180 machine_credentials,
3181 query_levels[q],
3182 &pwdlastset_new,
3183 expected_samlogon_result)) {
3184 ret = false;
3187 if (matched_expected_error == true) {
3188 /* skipping on expected failure */
3189 continue;
3192 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3193 * set without the SAMR_FIELD_EXPIRED_FLAG */
3195 switch (levels[l]) {
3196 case 21:
3197 case 23:
3198 case 25:
3199 if ((pwdlastset_new != 0) &&
3200 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3201 torture_comment(tctx, "not considering a non-0 "
3202 "pwdLastSet as a an error as the "
3203 "SAMR_FIELD_EXPIRED_FLAG has not "
3204 "been set\n");
3205 break;
3207 break;
3208 default:
3209 if (pwdlastset_new != 0) {
3210 torture_warning(tctx, "pwdLastSet test failed: "
3211 "expected pwdLastSet 0 but got %llu\n",
3212 (unsigned long long) pwdlastset_old);
3213 ret = false;
3215 break;
3218 switch (levels[l]) {
3219 case 21:
3220 case 23:
3221 case 25:
3222 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3223 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3224 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3225 (pwdlastset_old >= pwdlastset_new)) {
3226 torture_warning(tctx, "pwdlastset not increasing\n");
3227 ret = false;
3229 break;
3232 pwdlastset_old = pwdlastset_new;
3234 usleep(delay);
3236 /* set #2 */
3238 /* set a password, pwdlastset needs to get updated (increased
3239 * value), password_expired value used here is 0 */
3241 if (!test_SetPassword_level(p, np, tctx, handle,
3242 levels[l],
3243 fields_present[f],
3245 &matched_expected_error,
3246 set_levels[s],
3247 acct_name,
3248 password,
3249 machine_credentials,
3250 query_levels[q],
3251 &pwdlastset_new,
3252 expected_samlogon_result)) {
3253 ret = false;
3256 /* when a password has been changed, pwdlastset must not be 0 afterwards
3257 * and must be larger then the old value */
3259 switch (levels[l]) {
3260 case 21:
3261 case 23:
3262 case 25:
3263 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3264 * password has been changed, old and new pwdlastset
3265 * need to be the same value */
3267 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3268 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3269 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3271 torture_assert_int_equal(tctx, pwdlastset_old,
3272 pwdlastset_new, "pwdlastset must be equal");
3273 break;
3275 break;
3276 default:
3277 if (pwdlastset_old >= pwdlastset_new) {
3278 torture_warning(tctx, "pwdLastSet test failed: "
3279 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3280 (unsigned long long) pwdlastset_old,
3281 (unsigned long long) pwdlastset_new);
3282 ret = false;
3284 if (pwdlastset_new == 0) {
3285 torture_warning(tctx, "pwdLastSet test failed: "
3286 "expected non-0 pwdlastset, got: %llu\n",
3287 (unsigned long long) pwdlastset_new);
3288 ret = false;
3290 break;
3293 switch (levels[l]) {
3294 case 21:
3295 case 23:
3296 case 25:
3297 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3298 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3299 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3300 (pwdlastset_old >= pwdlastset_new)) {
3301 torture_warning(tctx, "pwdlastset not increasing\n");
3302 ret = false;
3304 break;
3307 pwdlastset_old = pwdlastset_new;
3309 usleep(delay);
3311 /* set #2b */
3313 /* set a password, pwdlastset needs to get updated (increased
3314 * value), password_expired value used here is 0 */
3316 if (!test_SetPassword_level(p, np, tctx, handle,
3317 levels[l],
3318 fields_present[f],
3320 &matched_expected_error,
3321 set_levels[s],
3322 acct_name,
3323 password,
3324 machine_credentials,
3325 query_levels[q],
3326 &pwdlastset_new,
3327 expected_samlogon_result)) {
3328 ret = false;
3331 /* when a password has been changed, pwdlastset must not be 0 afterwards
3332 * and must be larger then the old value */
3334 switch (levels[l]) {
3335 case 21:
3336 case 23:
3337 case 25:
3339 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3340 * password has been changed, old and new pwdlastset
3341 * need to be the same value */
3343 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3344 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3345 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3347 torture_assert_int_equal(tctx, pwdlastset_old,
3348 pwdlastset_new, "pwdlastset must be equal");
3349 break;
3351 break;
3352 default:
3353 if (pwdlastset_old >= pwdlastset_new) {
3354 torture_warning(tctx, "pwdLastSet test failed: "
3355 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3356 (unsigned long long) pwdlastset_old,
3357 (unsigned long long) pwdlastset_new);
3358 ret = false;
3360 if (pwdlastset_new == 0) {
3361 torture_warning(tctx, "pwdLastSet test failed: "
3362 "expected non-0 pwdlastset, got: %llu\n",
3363 (unsigned long long) pwdlastset_new);
3364 ret = false;
3366 break;
3369 switch (levels[l]) {
3370 case 21:
3371 case 23:
3372 case 25:
3373 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3374 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3375 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3376 (pwdlastset_old >= pwdlastset_new)) {
3377 torture_warning(tctx, "pwdlastset not increasing\n");
3378 ret = false;
3380 break;
3383 pwdlastset_old = pwdlastset_new;
3385 usleep(delay);
3387 /* set #3 */
3389 /* set a password and force password change (pwdlastset 0) by
3390 * setting the password expired flag to a non-0 value */
3392 if (!test_SetPassword_level(p, np, tctx, handle,
3393 levels[l],
3394 fields_present[f],
3395 nonzeros[z],
3396 &matched_expected_error,
3397 set_levels[s],
3398 acct_name,
3399 password,
3400 machine_credentials,
3401 query_levels[q],
3402 &pwdlastset_new,
3403 expected_samlogon_result)) {
3404 ret = false;
3407 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3408 * set without the SAMR_FIELD_EXPIRED_FLAG */
3410 switch (levels[l]) {
3411 case 21:
3412 case 23:
3413 case 25:
3414 if ((pwdlastset_new != 0) &&
3415 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3416 torture_comment(tctx, "not considering a non-0 "
3417 "pwdLastSet as a an error as the "
3418 "SAMR_FIELD_EXPIRED_FLAG has not "
3419 "been set\n");
3420 break;
3423 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3424 * password has been changed, old and new pwdlastset
3425 * need to be the same value */
3427 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3428 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3429 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3431 torture_assert_int_equal(tctx, pwdlastset_old,
3432 pwdlastset_new, "pwdlastset must be equal");
3433 break;
3435 break;
3436 default:
3437 if (pwdlastset_new != 0) {
3438 torture_warning(tctx, "pwdLastSet test failed: "
3439 "expected pwdLastSet 0, got %llu\n",
3440 (unsigned long long) pwdlastset_old);
3441 ret = false;
3443 break;
3446 switch (levels[l]) {
3447 case 21:
3448 case 23:
3449 case 25:
3450 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3451 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3452 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3453 (pwdlastset_old >= pwdlastset_new)) {
3454 torture_warning(tctx, "pwdlastset not increasing\n");
3455 ret = false;
3457 break;
3460 /* if the level we are testing does not have a fields_present
3461 * field, skip all fields present tests by setting f to to
3462 * arraysize */
3463 switch (levels[l]) {
3464 case 18:
3465 case 24:
3466 case 26:
3467 f = ARRAY_SIZE(fields_present);
3468 break;
3471 #ifdef TEST_QUERY_LEVELS
3473 #endif
3474 #ifdef TEST_SET_LEVELS
3476 #endif
3477 } /* fields present */
3478 } /* nonzeros */
3479 } /* levels */
3481 #undef TEST_SET_LEVELS
3482 #undef TEST_QUERY_LEVELS
3484 talloc_free(np);
3486 return ret;
3489 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3490 struct torture_context *tctx,
3491 struct policy_handle *handle,
3492 uint32_t *badpwdcount)
3494 union samr_UserInfo *info;
3495 struct samr_QueryUserInfo r;
3497 r.in.user_handle = handle;
3498 r.in.level = 3;
3499 r.out.info = &info;
3501 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3503 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3504 "failed to query userinfo");
3505 torture_assert_ntstatus_ok(tctx, r.out.result,
3506 "failed to query userinfo");
3508 *badpwdcount = info->info3.bad_password_count;
3510 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3512 return true;
3515 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3516 struct torture_context *tctx,
3517 struct policy_handle *user_handle,
3518 uint32_t acct_flags)
3520 struct samr_SetUserInfo r;
3521 union samr_UserInfo user_info;
3523 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3525 user_info.info16.acct_flags = acct_flags;
3527 r.in.user_handle = user_handle;
3528 r.in.level = 16;
3529 r.in.info = &user_info;
3531 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3532 "failed to set account flags");
3533 torture_assert_ntstatus_ok(tctx, r.out.result,
3534 "failed to set account flags");
3536 return true;
3539 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3540 struct torture_context *tctx,
3541 struct policy_handle *user_handle,
3542 uint32_t acct_flags,
3543 char **password)
3545 struct dcerpc_binding_handle *b = p->binding_handle;
3547 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3548 "failed to set password");
3550 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3552 torture_assert(tctx,
3553 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3554 acct_flags & ~ACB_DISABLED),
3555 "failed to enable user");
3557 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3558 "failed to set password");
3560 return true;
3563 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3564 struct torture_context *tctx,
3565 struct policy_handle *domain_handle,
3566 enum samr_DomainInfoClass level,
3567 union samr_DomainInfo *info)
3569 struct samr_SetDomainInfo r;
3571 r.in.domain_handle = domain_handle;
3572 r.in.level = level;
3573 r.in.info = info;
3575 torture_assert_ntstatus_ok(tctx,
3576 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3577 "failed to set domain info");
3578 torture_assert_ntstatus_ok(tctx, r.out.result,
3579 "failed to set domain info");
3581 return true;
3584 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3585 struct torture_context *tctx,
3586 struct policy_handle *domain_handle,
3587 enum samr_DomainInfoClass level,
3588 union samr_DomainInfo *info,
3589 NTSTATUS expected)
3591 struct samr_SetDomainInfo r;
3593 r.in.domain_handle = domain_handle;
3594 r.in.level = level;
3595 r.in.info = info;
3597 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3598 "SetDomainInfo failed");
3599 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3601 return true;
3604 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3605 struct torture_context *tctx,
3606 struct policy_handle *domain_handle,
3607 enum samr_DomainInfoClass level,
3608 union samr_DomainInfo **q_info)
3610 struct samr_QueryDomainInfo2 r;
3612 r.in.domain_handle = domain_handle;
3613 r.in.level = level;
3614 r.out.info = q_info;
3616 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3617 "failed to query domain info");
3618 torture_assert_ntstatus_ok(tctx, r.out.result,
3619 "failed to query domain info");
3621 return true;
3624 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3625 struct dcerpc_pipe *np,
3626 struct torture_context *tctx,
3627 uint32_t acct_flags,
3628 const char *acct_name,
3629 struct policy_handle *domain_handle,
3630 struct policy_handle *user_handle,
3631 char **password,
3632 struct cli_credentials *machine_credentials,
3633 const char *comment,
3634 bool disable,
3635 bool interactive,
3636 NTSTATUS expected_success_status,
3637 struct samr_DomInfo1 *info1,
3638 struct samr_DomInfo12 *info12)
3640 union samr_DomainInfo info;
3641 char **passwords;
3642 int i;
3643 uint32_t badpwdcount, tmp;
3644 uint32_t password_history_length = 12;
3645 uint32_t lockout_threshold = 15;
3646 struct dcerpc_binding_handle *b = p->binding_handle;
3648 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3650 torture_assert(tctx, password_history_length < lockout_threshold,
3651 "password history length needs to be smaller than account lockout threshold for this test");
3654 /* set policies */
3656 info.info1 = *info1;
3657 info.info1.password_history_length = password_history_length;
3659 torture_assert(tctx,
3660 test_SetDomainInfo(b, tctx, domain_handle,
3661 DomainPasswordInformation, &info),
3662 "failed to set password history length");
3664 info.info12 = *info12;
3665 info.info12.lockout_threshold = lockout_threshold;
3667 torture_assert(tctx,
3668 test_SetDomainInfo(b, tctx, domain_handle,
3669 DomainLockoutInformation, &info),
3670 "failed to set lockout threshold");
3672 /* reset bad pwd count */
3674 torture_assert(tctx,
3675 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3678 /* enable or disable account */
3679 if (disable) {
3680 torture_assert(tctx,
3681 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3682 acct_flags | ACB_DISABLED),
3683 "failed to disable user");
3684 } else {
3685 torture_assert(tctx,
3686 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3687 acct_flags & ~ACB_DISABLED),
3688 "failed to enable user");
3692 /* setup password history */
3694 passwords = talloc_array(tctx, char *, password_history_length);
3696 for (i=0; i < password_history_length; i++) {
3698 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3699 "failed to set password");
3700 passwords[i] = talloc_strdup(tctx, *password);
3702 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3703 acct_name, passwords[i],
3704 expected_success_status, interactive)) {
3705 torture_fail(tctx, "failed to auth with latest password");
3708 torture_assert(tctx,
3709 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3711 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3715 /* test with wrong password */
3717 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3718 acct_name, "random_crap",
3719 NT_STATUS_WRONG_PASSWORD, interactive)) {
3720 torture_fail(tctx, "succeeded to authenticate with wrong password");
3723 torture_assert(tctx,
3724 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3726 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3729 /* test with latest good password */
3731 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3732 passwords[password_history_length-1],
3733 expected_success_status, interactive)) {
3734 torture_fail(tctx, "succeeded to authenticate with wrong password");
3737 torture_assert(tctx,
3738 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3740 if (disable) {
3741 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3742 } else {
3743 /* only enabled accounts get the bad pwd count reset upon
3744 * successful logon */
3745 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3748 tmp = badpwdcount;
3751 /* test password history */
3753 for (i=0; i < password_history_length; i++) {
3755 torture_comment(tctx, "Testing bad password count behavior with "
3756 "password #%d of #%d\n", i, password_history_length);
3758 /* - network samlogon will succeed auth and not
3759 * increase badpwdcount for 2 last entries
3760 * - interactive samlogon only for the last one */
3762 if (i == password_history_length - 1 ||
3763 (i == password_history_length - 2 && !interactive)) {
3765 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3766 acct_name, passwords[i],
3767 expected_success_status, interactive)) {
3768 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3771 torture_assert(tctx,
3772 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3774 if (disable) {
3775 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3776 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3777 } else {
3778 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3779 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3782 tmp = badpwdcount;
3784 continue;
3787 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3788 acct_name, passwords[i],
3789 NT_STATUS_WRONG_PASSWORD, interactive)) {
3790 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3793 torture_assert(tctx,
3794 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3796 /* - network samlogon will fail auth but not increase
3797 * badpwdcount for 3rd last entry
3798 * - interactive samlogon for 3rd and 2nd last entry */
3800 if (i == password_history_length - 3 ||
3801 (i == password_history_length - 2 && interactive)) {
3802 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3803 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3804 } else {
3805 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3806 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3809 tmp = badpwdcount;
3812 return true;
3815 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3816 struct torture_context *tctx,
3817 uint32_t acct_flags,
3818 const char *acct_name,
3819 struct policy_handle *domain_handle,
3820 struct policy_handle *user_handle,
3821 char **password,
3822 struct cli_credentials *machine_credentials)
3824 union samr_DomainInfo *q_info, s_info;
3825 struct samr_DomInfo1 info1, _info1;
3826 struct samr_DomInfo12 info12, _info12;
3827 bool ret = true;
3828 struct dcerpc_binding_handle *b = p->binding_handle;
3829 struct dcerpc_pipe *np;
3830 int i;
3832 struct {
3833 const char *comment;
3834 bool disabled;
3835 bool interactive;
3836 NTSTATUS expected_success_status;
3837 } creds[] = {
3839 .comment = "network logon (disabled account)",
3840 .disabled = true,
3841 .interactive = false,
3842 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3845 .comment = "network logon (enabled account)",
3846 .disabled = false,
3847 .interactive = false,
3848 .expected_success_status= NT_STATUS_OK
3851 .comment = "interactive logon (disabled account)",
3852 .disabled = true,
3853 .interactive = true,
3854 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3857 .comment = "interactive logon (enabled account)",
3858 .disabled = false,
3859 .interactive = true,
3860 .expected_success_status= NT_STATUS_OK
3864 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3866 /* backup old policies */
3868 torture_assert(tctx,
3869 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3870 DomainPasswordInformation, &q_info),
3871 "failed to query domain info level 1");
3873 info1 = q_info->info1;
3874 _info1 = info1;
3876 torture_assert(tctx,
3877 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3878 DomainLockoutInformation, &q_info),
3879 "failed to query domain info level 12");
3881 info12 = q_info->info12;
3882 _info12 = info12;
3884 /* run tests */
3886 for (i=0; i < ARRAY_SIZE(creds); i++) {
3888 /* skip trust tests for now */
3889 if (acct_flags & ACB_WSTRUST ||
3890 acct_flags & ACB_SVRTRUST ||
3891 acct_flags & ACB_DOMTRUST) {
3892 continue;
3895 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3896 domain_handle, user_handle, password,
3897 machine_credentials,
3898 creds[i].comment,
3899 creds[i].disabled,
3900 creds[i].interactive,
3901 creds[i].expected_success_status,
3902 &_info1, &_info12);
3903 if (!ret) {
3904 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3905 } else {
3906 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3910 /* restore policies */
3912 s_info.info1 = info1;
3914 torture_assert(tctx,
3915 test_SetDomainInfo(b, tctx, domain_handle,
3916 DomainPasswordInformation, &s_info),
3917 "failed to set password information");
3919 s_info.info12 = info12;
3921 torture_assert(tctx,
3922 test_SetDomainInfo(b, tctx, domain_handle,
3923 DomainLockoutInformation, &s_info),
3924 "failed to set lockout information");
3926 return ret;
3929 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3930 struct torture_context *tctx,
3931 struct policy_handle *handle,
3932 uint32_t *acct_flags)
3934 union samr_UserInfo *info;
3935 struct samr_QueryUserInfo r;
3937 r.in.user_handle = handle;
3938 r.in.level = 16;
3939 r.out.info = &info;
3941 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3943 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3944 "failed to query userinfo");
3945 torture_assert_ntstatus_ok(tctx, r.out.result,
3946 "failed to query userinfo");
3948 *acct_flags = info->info16.acct_flags;
3950 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3952 return true;
3955 static bool test_Password_lockout(struct dcerpc_pipe *p,
3956 struct dcerpc_pipe *np,
3957 struct torture_context *tctx,
3958 uint32_t acct_flags,
3959 const char *acct_name,
3960 struct policy_handle *domain_handle,
3961 struct policy_handle *user_handle,
3962 char **password,
3963 struct cli_credentials *machine_credentials,
3964 const char *comment,
3965 bool disable,
3966 bool interactive,
3967 NTSTATUS expected_success_status,
3968 struct samr_DomInfo1 *info1,
3969 struct samr_DomInfo12 *info12)
3971 union samr_DomainInfo info;
3972 uint32_t badpwdcount;
3973 uint32_t password_history_length = 1;
3974 uint64_t lockout_threshold = 1;
3975 uint32_t lockout_seconds = 5;
3976 uint64_t delta_time_factor = 10 * 1000 * 1000;
3977 struct dcerpc_binding_handle *b = p->binding_handle;
3979 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3981 /* set policies */
3983 info.info1 = *info1;
3985 torture_comment(tctx, "setting password history length.\n");
3986 info.info1.password_history_length = password_history_length;
3988 torture_assert(tctx,
3989 test_SetDomainInfo(b, tctx, domain_handle,
3990 DomainPasswordInformation, &info),
3991 "failed to set password history length");
3993 info.info12 = *info12;
3994 info.info12.lockout_threshold = lockout_threshold;
3996 /* set lockout duration < lockout window: should fail */
3997 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3998 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4000 torture_assert(tctx,
4001 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4002 DomainLockoutInformation, &info,
4003 NT_STATUS_INVALID_PARAMETER),
4004 "setting lockout duration < lockout window gave unexpected result");
4006 info.info12.lockout_duration = 0;
4007 info.info12.lockout_window = 0;
4009 torture_assert(tctx,
4010 test_SetDomainInfo(b, tctx, domain_handle,
4011 DomainLockoutInformation, &info),
4012 "failed to set lockout window and duration to 0");
4015 /* set lockout duration of 5 seconds */
4016 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4017 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4019 torture_assert(tctx,
4020 test_SetDomainInfo(b, tctx, domain_handle,
4021 DomainLockoutInformation, &info),
4022 "failed to set lockout window and duration to 5 seconds");
4024 /* reset bad pwd count */
4026 torture_assert(tctx,
4027 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4030 /* enable or disable account */
4032 if (disable) {
4033 torture_assert(tctx,
4034 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4035 acct_flags | ACB_DISABLED),
4036 "failed to disable user");
4037 } else {
4038 torture_assert(tctx,
4039 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4040 acct_flags & ~ACB_DISABLED),
4041 "failed to enable user");
4045 /* test logon with right password */
4047 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4048 acct_name, *password,
4049 expected_success_status, interactive)) {
4050 torture_fail(tctx, "failed to auth with latest password");
4053 torture_assert(tctx,
4054 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4055 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4058 /* test with wrong password ==> lockout */
4060 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4061 acct_name, "random_crap",
4062 NT_STATUS_WRONG_PASSWORD, interactive)) {
4063 torture_fail(tctx, "succeeded to authenticate with wrong password");
4066 torture_assert(tctx,
4067 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4068 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4070 torture_assert(tctx,
4071 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4072 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4073 "expected account to be locked");
4076 /* test with good password */
4078 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4079 *password,
4080 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4082 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4085 /* bad pwd count should not get updated */
4086 torture_assert(tctx,
4087 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4088 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4090 /* curiously, windows does _not_ set the autlock flag */
4091 torture_assert(tctx,
4092 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4093 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4094 "expected account to be locked");
4097 /* with bad password */
4099 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4100 acct_name, "random_crap2",
4101 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4103 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4106 /* bad pwd count should not get updated */
4107 torture_assert(tctx,
4108 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4109 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4111 /* curiously, windows does _not_ set the autlock flag */
4112 torture_assert(tctx,
4113 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4114 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4115 "expected account to be locked");
4118 /* let lockout duration expire ==> unlock */
4120 torture_comment(tctx, "let lockout duration expire...\n");
4121 sleep(lockout_seconds + 1);
4123 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4124 *password,
4125 expected_success_status, interactive))
4127 torture_fail(tctx, "failed to authenticate after lockout expired");
4130 torture_assert(tctx,
4131 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4132 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4133 "expected account not to be locked");
4135 return true;
4138 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4139 struct torture_context *tctx,
4140 uint32_t acct_flags,
4141 const char *acct_name,
4142 struct policy_handle *domain_handle,
4143 struct policy_handle *user_handle,
4144 char **password,
4145 struct cli_credentials *machine_credentials)
4147 union samr_DomainInfo *q_info, s_info;
4148 struct samr_DomInfo1 info1, _info1;
4149 struct samr_DomInfo12 info12, _info12;
4150 bool ret = true;
4151 struct dcerpc_binding_handle *b = p->binding_handle;
4152 struct dcerpc_pipe *np;
4153 int i;
4155 struct {
4156 const char *comment;
4157 bool disabled;
4158 bool interactive;
4159 NTSTATUS expected_success_status;
4160 } creds[] = {
4162 .comment = "network logon (disabled account)",
4163 .disabled = true,
4164 .interactive = false,
4165 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4168 .comment = "network logon (enabled account)",
4169 .disabled = false,
4170 .interactive = false,
4171 .expected_success_status= NT_STATUS_OK
4174 .comment = "interactive logon (disabled account)",
4175 .disabled = true,
4176 .interactive = true,
4177 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4180 .comment = "interactive logon (enabled account)",
4181 .disabled = false,
4182 .interactive = true,
4183 .expected_success_status= NT_STATUS_OK
4187 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4189 /* backup old policies */
4191 torture_assert(tctx,
4192 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4193 DomainPasswordInformation, &q_info),
4194 "failed to query domain info level 1");
4196 info1 = q_info->info1;
4197 _info1 = info1;
4199 torture_assert(tctx,
4200 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4201 DomainLockoutInformation, &q_info),
4202 "failed to query domain info level 12");
4204 info12 = q_info->info12;
4205 _info12 = info12;
4207 /* run tests */
4209 for (i=0; i < ARRAY_SIZE(creds); i++) {
4211 /* skip trust tests for now */
4212 if (acct_flags & ACB_WSTRUST ||
4213 acct_flags & ACB_SVRTRUST ||
4214 acct_flags & ACB_DOMTRUST) {
4215 continue;
4218 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4219 domain_handle, user_handle, password,
4220 machine_credentials,
4221 creds[i].comment,
4222 creds[i].disabled,
4223 creds[i].interactive,
4224 creds[i].expected_success_status,
4225 &_info1, &_info12);
4226 if (!ret) {
4227 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4228 } else {
4229 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4233 /* restore policies */
4235 s_info.info1 = info1;
4237 torture_assert(tctx,
4238 test_SetDomainInfo(b, tctx, domain_handle,
4239 DomainPasswordInformation, &s_info),
4240 "failed to set password information");
4242 s_info.info12 = info12;
4244 torture_assert(tctx,
4245 test_SetDomainInfo(b, tctx, domain_handle,
4246 DomainLockoutInformation, &s_info),
4247 "failed to set lockout information");
4249 return ret;
4252 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4253 struct dcerpc_pipe *lp,
4254 struct torture_context *tctx,
4255 struct policy_handle *domain_handle,
4256 struct policy_handle *lsa_handle,
4257 struct policy_handle *user_handle,
4258 const struct dom_sid *domain_sid,
4259 uint32_t rid,
4260 struct cli_credentials *machine_credentials)
4262 bool ret = true;
4263 struct dcerpc_binding_handle *b = p->binding_handle;
4264 struct dcerpc_binding_handle *lb = lp->binding_handle;
4266 struct policy_handle lsa_acct_handle;
4267 struct dom_sid *user_sid;
4269 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4272 struct lsa_EnumAccountRights r;
4273 struct lsa_RightSet rights;
4275 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4277 r.in.handle = lsa_handle;
4278 r.in.sid = user_sid;
4279 r.out.rights = &rights;
4281 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4282 "lsa_EnumAccountRights failed");
4283 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4284 "Expected enum rights for account to fail");
4288 struct lsa_RightSet rights;
4289 struct lsa_StringLarge names[2];
4290 struct lsa_AddAccountRights r;
4292 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4294 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4295 init_lsa_StringLarge(&names[1], NULL);
4297 rights.count = 1;
4298 rights.names = names;
4300 r.in.handle = lsa_handle;
4301 r.in.sid = user_sid;
4302 r.in.rights = &rights;
4304 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4305 "lsa_AddAccountRights failed");
4306 torture_assert_ntstatus_ok(tctx, r.out.result,
4307 "Failed to add privileges");
4311 struct lsa_EnumAccounts r;
4312 uint32_t resume_handle = 0;
4313 struct lsa_SidArray lsa_sid_array;
4314 int i;
4315 bool found_sid = false;
4317 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4319 r.in.handle = lsa_handle;
4320 r.in.num_entries = 0x1000;
4321 r.in.resume_handle = &resume_handle;
4322 r.out.sids = &lsa_sid_array;
4323 r.out.resume_handle = &resume_handle;
4325 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4326 "lsa_EnumAccounts failed");
4327 torture_assert_ntstatus_ok(tctx, r.out.result,
4328 "Failed to enum accounts");
4330 for (i=0; i < lsa_sid_array.num_sids; i++) {
4331 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4332 found_sid = true;
4336 torture_assert(tctx, found_sid,
4337 "failed to list privileged account");
4341 struct lsa_EnumAccountRights r;
4342 struct lsa_RightSet user_rights;
4344 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4346 r.in.handle = lsa_handle;
4347 r.in.sid = user_sid;
4348 r.out.rights = &user_rights;
4350 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4351 "lsa_EnumAccountRights failed");
4352 torture_assert_ntstatus_ok(tctx, r.out.result,
4353 "Failed to enum rights for account");
4355 if (user_rights.count < 1) {
4356 torture_warning(tctx, "failed to find newly added rights");
4357 return false;
4362 struct lsa_OpenAccount r;
4364 torture_comment(tctx, "Testing LSA OpenAccount\n");
4366 r.in.handle = lsa_handle;
4367 r.in.sid = user_sid;
4368 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4369 r.out.acct_handle = &lsa_acct_handle;
4371 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4372 "lsa_OpenAccount failed");
4373 torture_assert_ntstatus_ok(tctx, r.out.result,
4374 "Failed to open lsa account");
4378 struct lsa_GetSystemAccessAccount r;
4379 uint32_t access_mask;
4381 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4383 r.in.handle = &lsa_acct_handle;
4384 r.out.access_mask = &access_mask;
4386 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4387 "lsa_GetSystemAccessAccount failed");
4388 torture_assert_ntstatus_ok(tctx, r.out.result,
4389 "Failed to get lsa system access account");
4393 struct lsa_Close r;
4395 torture_comment(tctx, "Testing LSA Close\n");
4397 r.in.handle = &lsa_acct_handle;
4398 r.out.handle = &lsa_acct_handle;
4400 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4401 "lsa_Close failed");
4402 torture_assert_ntstatus_ok(tctx, r.out.result,
4403 "Failed to close lsa");
4407 struct samr_DeleteUser r;
4409 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4411 r.in.user_handle = user_handle;
4412 r.out.user_handle = user_handle;
4414 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4415 "DeleteUser failed");
4416 torture_assert_ntstatus_ok(tctx, r.out.result,
4417 "DeleteUser failed");
4421 struct lsa_EnumAccounts r;
4422 uint32_t resume_handle = 0;
4423 struct lsa_SidArray lsa_sid_array;
4424 int i;
4425 bool found_sid = false;
4427 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4429 r.in.handle = lsa_handle;
4430 r.in.num_entries = 0x1000;
4431 r.in.resume_handle = &resume_handle;
4432 r.out.sids = &lsa_sid_array;
4433 r.out.resume_handle = &resume_handle;
4435 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4436 "lsa_EnumAccounts failed");
4437 torture_assert_ntstatus_ok(tctx, r.out.result,
4438 "Failed to enum accounts");
4440 for (i=0; i < lsa_sid_array.num_sids; i++) {
4441 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4442 found_sid = true;
4446 torture_assert(tctx, found_sid,
4447 "failed to list privileged account");
4451 struct lsa_EnumAccountRights r;
4452 struct lsa_RightSet user_rights;
4454 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4456 r.in.handle = lsa_handle;
4457 r.in.sid = user_sid;
4458 r.out.rights = &user_rights;
4460 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4461 "lsa_EnumAccountRights failed");
4462 torture_assert_ntstatus_ok(tctx, r.out.result,
4463 "Failed to enum rights for account");
4465 if (user_rights.count < 1) {
4466 torture_warning(tctx, "failed to find newly added rights");
4467 return false;
4472 struct lsa_OpenAccount r;
4474 torture_comment(tctx, "Testing LSA OpenAccount\n");
4476 r.in.handle = lsa_handle;
4477 r.in.sid = user_sid;
4478 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4479 r.out.acct_handle = &lsa_acct_handle;
4481 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4482 "lsa_OpenAccount failed");
4483 torture_assert_ntstatus_ok(tctx, r.out.result,
4484 "Failed to open lsa account");
4488 struct lsa_GetSystemAccessAccount r;
4489 uint32_t access_mask;
4491 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4493 r.in.handle = &lsa_acct_handle;
4494 r.out.access_mask = &access_mask;
4496 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4497 "lsa_GetSystemAccessAccount failed");
4498 torture_assert_ntstatus_ok(tctx, r.out.result,
4499 "Failed to get lsa system access account");
4503 struct lsa_DeleteObject r;
4505 torture_comment(tctx, "Testing LSA DeleteObject\n");
4507 r.in.handle = &lsa_acct_handle;
4508 r.out.handle = &lsa_acct_handle;
4510 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4511 "lsa_DeleteObject failed");
4512 torture_assert_ntstatus_ok(tctx, r.out.result,
4513 "Failed to delete object");
4517 struct lsa_EnumAccounts r;
4518 uint32_t resume_handle = 0;
4519 struct lsa_SidArray lsa_sid_array;
4520 int i;
4521 bool found_sid = false;
4523 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4525 r.in.handle = lsa_handle;
4526 r.in.num_entries = 0x1000;
4527 r.in.resume_handle = &resume_handle;
4528 r.out.sids = &lsa_sid_array;
4529 r.out.resume_handle = &resume_handle;
4531 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4532 "lsa_EnumAccounts failed");
4533 torture_assert_ntstatus_ok(tctx, r.out.result,
4534 "Failed to enum accounts");
4536 for (i=0; i < lsa_sid_array.num_sids; i++) {
4537 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4538 found_sid = true;
4542 torture_assert(tctx, !found_sid,
4543 "should not have listed privileged account");
4547 struct lsa_EnumAccountRights r;
4548 struct lsa_RightSet user_rights;
4550 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4552 r.in.handle = lsa_handle;
4553 r.in.sid = user_sid;
4554 r.out.rights = &user_rights;
4556 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4557 "lsa_EnumAccountRights failed");
4558 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4559 "Failed to enum rights for account");
4562 return ret;
4565 static bool test_user_ops(struct dcerpc_pipe *p,
4566 struct torture_context *tctx,
4567 struct policy_handle *user_handle,
4568 struct policy_handle *domain_handle,
4569 const struct dom_sid *domain_sid,
4570 uint32_t base_acct_flags,
4571 const char *base_acct_name, enum torture_samr_choice which_ops,
4572 struct cli_credentials *machine_credentials)
4574 char *password = NULL;
4575 struct samr_QueryUserInfo q;
4576 union samr_UserInfo *info;
4577 NTSTATUS status;
4578 struct dcerpc_binding_handle *b = p->binding_handle;
4580 bool ret = true;
4581 int i;
4582 uint32_t rid;
4583 const uint32_t password_fields[] = {
4584 SAMR_FIELD_NT_PASSWORD_PRESENT,
4585 SAMR_FIELD_LM_PASSWORD_PRESENT,
4586 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4590 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4591 if (!NT_STATUS_IS_OK(status)) {
4592 ret = false;
4595 switch (which_ops) {
4596 case TORTURE_SAMR_USER_ATTRIBUTES:
4597 if (!test_QuerySecurity(b, tctx, user_handle)) {
4598 ret = false;
4601 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4602 ret = false;
4605 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4606 ret = false;
4609 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4610 base_acct_name)) {
4611 ret = false;
4614 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4615 ret = false;
4618 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4619 ret = false;
4622 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4623 ret = false;
4625 break;
4626 case TORTURE_SAMR_PASSWORDS:
4627 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4628 char simple_pass[9];
4629 char *v = generate_random_str(tctx, 1);
4631 ZERO_STRUCT(simple_pass);
4632 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4634 torture_comment(tctx, "Testing machine account password policy rules\n");
4636 /* Workstation trust accounts don't seem to need to honour password quality policy */
4637 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4638 ret = false;
4641 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4642 ret = false;
4645 /* reset again, to allow another 'user' password change */
4646 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4647 ret = false;
4650 /* Try a 'short' password */
4651 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4652 ret = false;
4655 /* Try a compleatly random password */
4656 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4657 ret = false;
4661 for (i = 0; password_fields[i]; i++) {
4662 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4663 ret = false;
4666 /* check it was set right */
4667 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4668 ret = false;
4672 for (i = 0; password_fields[i]; i++) {
4673 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4674 ret = false;
4677 /* check it was set right */
4678 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4679 ret = false;
4683 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4684 ret = false;
4687 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4688 ret = false;
4691 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4692 ret = false;
4695 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4696 ret = false;
4699 for (i = 0; password_fields[i]; i++) {
4701 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4702 /* we need to skip as that would break
4703 * the ChangePasswordUser3 verify */
4704 continue;
4707 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4708 ret = false;
4711 /* check it was set right */
4712 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4713 ret = false;
4717 q.in.user_handle = user_handle;
4718 q.in.level = 5;
4719 q.out.info = &info;
4721 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4722 "QueryUserInfo failed");
4723 if (!NT_STATUS_IS_OK(q.out.result)) {
4724 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4725 q.in.level, nt_errstr(q.out.result));
4726 ret = false;
4727 } else {
4728 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4729 if ((info->info5.acct_flags) != expected_flags) {
4730 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4731 info->info5.acct_flags,
4732 expected_flags);
4733 /* FIXME: GD */
4734 if (!torture_setting_bool(tctx, "samba3", false)) {
4735 ret = false;
4738 if (info->info5.rid != rid) {
4739 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4740 info->info5.rid, rid);
4745 break;
4747 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4749 /* test last password change timestamp behaviour */
4750 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4751 base_acct_name,
4752 user_handle, &password,
4753 machine_credentials)) {
4754 ret = false;
4757 if (ret == true) {
4758 torture_comment(tctx, "pwdLastSet test succeeded\n");
4759 } else {
4760 torture_warning(tctx, "pwdLastSet test failed\n");
4763 break;
4765 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4767 /* test bad pwd count change behaviour */
4768 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4769 base_acct_name,
4770 domain_handle,
4771 user_handle, &password,
4772 machine_credentials)) {
4773 ret = false;
4776 if (ret == true) {
4777 torture_comment(tctx, "badPwdCount test succeeded\n");
4778 } else {
4779 torture_warning(tctx, "badPwdCount test failed\n");
4782 break;
4784 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4786 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4787 base_acct_name,
4788 domain_handle,
4789 user_handle, &password,
4790 machine_credentials))
4792 ret = false;
4795 if (ret == true) {
4796 torture_comment(tctx, "lockout test succeeded\n");
4797 } else {
4798 torture_warning(tctx, "lockout test failed\n");
4801 break;
4804 case TORTURE_SAMR_USER_PRIVILEGES: {
4806 struct dcerpc_pipe *lp;
4807 struct policy_handle *lsa_handle;
4808 struct dcerpc_binding_handle *lb;
4810 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4811 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4812 lb = lp->binding_handle;
4814 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4815 ret = false;
4818 if (!test_DeleteUser_with_privs(p, lp, tctx,
4819 domain_handle, lsa_handle, user_handle,
4820 domain_sid, rid,
4821 machine_credentials)) {
4822 ret = false;
4825 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4826 ret = false;
4829 if (!ret) {
4830 torture_warning(tctx, "privileged user delete test failed\n");
4833 break;
4835 case TORTURE_SAMR_OTHER:
4836 case TORTURE_SAMR_MANY_ACCOUNTS:
4837 case TORTURE_SAMR_MANY_GROUPS:
4838 case TORTURE_SAMR_MANY_ALIASES:
4839 /* We just need the account to exist */
4840 break;
4842 return ret;
4845 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4846 struct torture_context *tctx,
4847 struct policy_handle *alias_handle,
4848 const struct dom_sid *domain_sid)
4850 bool ret = true;
4852 if (!torture_setting_bool(tctx, "samba3", false)) {
4853 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4854 ret = false;
4858 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4859 ret = false;
4862 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4863 ret = false;
4866 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4867 ret = false;
4870 if (torture_setting_bool(tctx, "samba3", false) ||
4871 torture_setting_bool(tctx, "samba4", false)) {
4872 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4873 return ret;
4876 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
4877 ret = false;
4880 return ret;
4884 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
4885 struct torture_context *tctx,
4886 struct policy_handle *user_handle)
4888 struct samr_DeleteUser d;
4889 torture_comment(tctx, "Testing DeleteUser\n");
4891 d.in.user_handle = user_handle;
4892 d.out.user_handle = user_handle;
4894 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4895 "DeleteUser failed");
4896 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
4898 return true;
4901 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
4902 struct torture_context *tctx,
4903 struct policy_handle *handle, const char *name)
4905 NTSTATUS status;
4906 struct samr_DeleteUser d;
4907 struct policy_handle user_handle;
4908 uint32_t rid;
4910 status = test_LookupName(b, tctx, handle, name, &rid);
4911 if (!NT_STATUS_IS_OK(status)) {
4912 goto failed;
4915 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
4916 if (!NT_STATUS_IS_OK(status)) {
4917 goto failed;
4920 d.in.user_handle = &user_handle;
4921 d.out.user_handle = &user_handle;
4922 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4923 "DeleteUser failed");
4924 if (!NT_STATUS_IS_OK(d.out.result)) {
4925 status = d.out.result;
4926 goto failed;
4929 return true;
4931 failed:
4932 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4933 return false;
4937 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
4938 struct torture_context *tctx,
4939 struct policy_handle *handle, const char *name)
4941 NTSTATUS status;
4942 struct samr_OpenGroup r;
4943 struct samr_DeleteDomainGroup d;
4944 struct policy_handle group_handle;
4945 uint32_t rid;
4947 status = test_LookupName(b, tctx, handle, name, &rid);
4948 if (!NT_STATUS_IS_OK(status)) {
4949 goto failed;
4952 r.in.domain_handle = handle;
4953 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4954 r.in.rid = rid;
4955 r.out.group_handle = &group_handle;
4956 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
4957 "OpenGroup failed");
4958 if (!NT_STATUS_IS_OK(r.out.result)) {
4959 status = r.out.result;
4960 goto failed;
4963 d.in.group_handle = &group_handle;
4964 d.out.group_handle = &group_handle;
4965 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
4966 "DeleteDomainGroup failed");
4967 if (!NT_STATUS_IS_OK(d.out.result)) {
4968 status = d.out.result;
4969 goto failed;
4972 return true;
4974 failed:
4975 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4976 return false;
4980 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
4981 struct torture_context *tctx,
4982 struct policy_handle *domain_handle,
4983 const char *name)
4985 NTSTATUS status;
4986 struct samr_OpenAlias r;
4987 struct samr_DeleteDomAlias d;
4988 struct policy_handle alias_handle;
4989 uint32_t rid;
4991 torture_comment(tctx, "Testing DeleteAlias_byname\n");
4993 status = test_LookupName(b, tctx, domain_handle, name, &rid);
4994 if (!NT_STATUS_IS_OK(status)) {
4995 goto failed;
4998 r.in.domain_handle = domain_handle;
4999 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5000 r.in.rid = rid;
5001 r.out.alias_handle = &alias_handle;
5002 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5003 "OpenAlias failed");
5004 if (!NT_STATUS_IS_OK(r.out.result)) {
5005 status = r.out.result;
5006 goto failed;
5009 d.in.alias_handle = &alias_handle;
5010 d.out.alias_handle = &alias_handle;
5011 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5012 "DeleteDomAlias failed");
5013 if (!NT_STATUS_IS_OK(d.out.result)) {
5014 status = d.out.result;
5015 goto failed;
5018 return true;
5020 failed:
5021 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5022 return false;
5025 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5026 struct torture_context *tctx,
5027 struct policy_handle *alias_handle)
5029 struct samr_DeleteDomAlias d;
5030 bool ret = true;
5032 torture_comment(tctx, "Testing DeleteAlias\n");
5034 d.in.alias_handle = alias_handle;
5035 d.out.alias_handle = alias_handle;
5037 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5038 "DeleteDomAlias failed");
5039 if (!NT_STATUS_IS_OK(d.out.result)) {
5040 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5041 ret = false;
5044 return ret;
5047 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5048 struct torture_context *tctx,
5049 struct policy_handle *domain_handle,
5050 const char *alias_name,
5051 struct policy_handle *alias_handle,
5052 const struct dom_sid *domain_sid,
5053 bool test_alias)
5055 struct samr_CreateDomAlias r;
5056 struct lsa_String name;
5057 uint32_t rid;
5058 bool ret = true;
5060 init_lsa_String(&name, alias_name);
5061 r.in.domain_handle = domain_handle;
5062 r.in.alias_name = &name;
5063 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5064 r.out.alias_handle = alias_handle;
5065 r.out.rid = &rid;
5067 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5069 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5070 "CreateDomAlias failed");
5072 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5073 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5074 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5075 return true;
5076 } else {
5077 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5078 nt_errstr(r.out.result));
5079 return false;
5083 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5084 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5085 return false;
5087 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5088 "CreateDomAlias failed");
5091 if (!NT_STATUS_IS_OK(r.out.result)) {
5092 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5093 return false;
5096 if (!test_alias) {
5097 return ret;
5100 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5101 ret = false;
5104 return ret;
5107 static bool test_ChangePassword(struct dcerpc_pipe *p,
5108 struct torture_context *tctx,
5109 const char *acct_name,
5110 struct policy_handle *domain_handle, char **password)
5112 bool ret = true;
5113 struct dcerpc_binding_handle *b = p->binding_handle;
5115 if (!*password) {
5116 return false;
5119 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5120 ret = false;
5123 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5124 ret = false;
5127 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5128 ret = false;
5131 /* test what happens when setting the old password again */
5132 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5133 ret = false;
5137 char simple_pass[9];
5138 char *v = generate_random_str(tctx, 1);
5140 ZERO_STRUCT(simple_pass);
5141 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5143 /* test what happens when picking a simple password */
5144 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5145 ret = false;
5149 /* set samr_SetDomainInfo level 1 with min_length 5 */
5151 struct samr_QueryDomainInfo r;
5152 union samr_DomainInfo *info = NULL;
5153 struct samr_SetDomainInfo s;
5154 uint16_t len_old, len;
5155 uint32_t pwd_prop_old;
5156 int64_t min_pwd_age_old;
5158 len = 5;
5160 r.in.domain_handle = domain_handle;
5161 r.in.level = 1;
5162 r.out.info = &info;
5164 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5165 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5166 "QueryDomainInfo failed");
5167 if (!NT_STATUS_IS_OK(r.out.result)) {
5168 return false;
5171 s.in.domain_handle = domain_handle;
5172 s.in.level = 1;
5173 s.in.info = info;
5175 /* remember the old min length, so we can reset it */
5176 len_old = s.in.info->info1.min_password_length;
5177 s.in.info->info1.min_password_length = len;
5178 pwd_prop_old = s.in.info->info1.password_properties;
5179 /* turn off password complexity checks for this test */
5180 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5182 min_pwd_age_old = s.in.info->info1.min_password_age;
5183 s.in.info->info1.min_password_age = 0;
5185 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5186 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5187 "SetDomainInfo failed");
5188 if (!NT_STATUS_IS_OK(s.out.result)) {
5189 return false;
5192 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5194 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5195 ret = false;
5198 s.in.info->info1.min_password_length = len_old;
5199 s.in.info->info1.password_properties = pwd_prop_old;
5200 s.in.info->info1.min_password_age = min_pwd_age_old;
5202 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5203 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5204 "SetDomainInfo failed");
5205 if (!NT_STATUS_IS_OK(s.out.result)) {
5206 return false;
5212 struct samr_OpenUser r;
5213 struct samr_QueryUserInfo q;
5214 union samr_UserInfo *info;
5215 struct samr_LookupNames n;
5216 struct policy_handle user_handle;
5217 struct samr_Ids rids, types;
5219 n.in.domain_handle = domain_handle;
5220 n.in.num_names = 1;
5221 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5222 n.in.names[0].string = acct_name;
5223 n.out.rids = &rids;
5224 n.out.types = &types;
5226 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5227 "LookupNames failed");
5228 if (!NT_STATUS_IS_OK(n.out.result)) {
5229 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5230 return false;
5233 r.in.domain_handle = domain_handle;
5234 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5235 r.in.rid = n.out.rids->ids[0];
5236 r.out.user_handle = &user_handle;
5238 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5239 "OpenUser failed");
5240 if (!NT_STATUS_IS_OK(r.out.result)) {
5241 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5242 return false;
5245 q.in.user_handle = &user_handle;
5246 q.in.level = 5;
5247 q.out.info = &info;
5249 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5250 "QueryUserInfo failed");
5251 if (!NT_STATUS_IS_OK(q.out.result)) {
5252 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5253 return false;
5256 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5258 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5259 info->info5.last_password_change, true)) {
5260 ret = false;
5264 /* we change passwords twice - this has the effect of verifying
5265 they were changed correctly for the final call */
5266 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5267 ret = false;
5270 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5271 ret = false;
5274 return ret;
5277 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5278 struct policy_handle *domain_handle,
5279 const char *user_name,
5280 struct policy_handle *user_handle_out,
5281 struct dom_sid *domain_sid,
5282 enum torture_samr_choice which_ops,
5283 struct cli_credentials *machine_credentials,
5284 bool test_user)
5287 TALLOC_CTX *user_ctx;
5289 struct samr_CreateUser r;
5290 struct samr_QueryUserInfo q;
5291 union samr_UserInfo *info;
5292 struct samr_DeleteUser d;
5293 uint32_t rid;
5295 /* This call creates a 'normal' account - check that it really does */
5296 const uint32_t acct_flags = ACB_NORMAL;
5297 struct lsa_String name;
5298 bool ret = true;
5299 struct dcerpc_binding_handle *b = p->binding_handle;
5301 struct policy_handle user_handle;
5302 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5303 init_lsa_String(&name, user_name);
5305 r.in.domain_handle = domain_handle;
5306 r.in.account_name = &name;
5307 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5308 r.out.user_handle = &user_handle;
5309 r.out.rid = &rid;
5311 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5313 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5314 "CreateUser failed");
5316 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5317 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5318 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5319 return true;
5320 } else {
5321 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5322 nt_errstr(r.out.result));
5323 return false;
5327 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5328 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5329 talloc_free(user_ctx);
5330 return false;
5332 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5333 "CreateUser failed");
5336 if (!NT_STATUS_IS_OK(r.out.result)) {
5337 talloc_free(user_ctx);
5338 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5339 return false;
5342 if (!test_user) {
5343 if (user_handle_out) {
5344 *user_handle_out = user_handle;
5346 return ret;
5350 q.in.user_handle = &user_handle;
5351 q.in.level = 16;
5352 q.out.info = &info;
5354 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5355 "QueryUserInfo failed");
5356 if (!NT_STATUS_IS_OK(q.out.result)) {
5357 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5358 q.in.level, nt_errstr(q.out.result));
5359 ret = false;
5360 } else {
5361 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5362 torture_warning(tctx, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5363 info->info16.acct_flags,
5364 acct_flags);
5365 ret = false;
5369 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5370 domain_sid, acct_flags, name.string, which_ops,
5371 machine_credentials)) {
5372 ret = false;
5375 if (user_handle_out) {
5376 *user_handle_out = user_handle;
5377 } else {
5378 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5380 d.in.user_handle = &user_handle;
5381 d.out.user_handle = &user_handle;
5383 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5384 "DeleteUser failed");
5385 if (!NT_STATUS_IS_OK(d.out.result)) {
5386 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5387 ret = false;
5393 talloc_free(user_ctx);
5395 return ret;
5399 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5400 struct policy_handle *domain_handle,
5401 struct dom_sid *domain_sid,
5402 enum torture_samr_choice which_ops,
5403 struct cli_credentials *machine_credentials)
5405 struct samr_CreateUser2 r;
5406 struct samr_QueryUserInfo q;
5407 union samr_UserInfo *info;
5408 struct samr_DeleteUser d;
5409 struct policy_handle user_handle;
5410 uint32_t rid;
5411 struct lsa_String name;
5412 bool ret = true;
5413 int i;
5414 struct dcerpc_binding_handle *b = p->binding_handle;
5416 struct {
5417 uint32_t acct_flags;
5418 const char *account_name;
5419 NTSTATUS nt_status;
5420 } account_types[] = {
5421 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5422 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5423 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5424 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5425 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5426 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5427 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5428 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5429 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5430 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5431 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5432 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5433 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5434 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5435 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5438 for (i = 0; account_types[i].account_name; i++) {
5439 TALLOC_CTX *user_ctx;
5440 uint32_t acct_flags = account_types[i].acct_flags;
5441 uint32_t access_granted;
5442 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5443 init_lsa_String(&name, account_types[i].account_name);
5445 r.in.domain_handle = domain_handle;
5446 r.in.account_name = &name;
5447 r.in.acct_flags = acct_flags;
5448 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5449 r.out.user_handle = &user_handle;
5450 r.out.access_granted = &access_granted;
5451 r.out.rid = &rid;
5453 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5455 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5456 "CreateUser2 failed");
5458 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5459 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5460 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5461 continue;
5462 } else {
5463 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5464 nt_errstr(r.out.result));
5465 ret = false;
5466 continue;
5470 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5471 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5472 talloc_free(user_ctx);
5473 ret = false;
5474 continue;
5476 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5477 "CreateUser2 failed");
5480 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5481 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5482 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5483 ret = false;
5486 if (NT_STATUS_IS_OK(r.out.result)) {
5487 q.in.user_handle = &user_handle;
5488 q.in.level = 5;
5489 q.out.info = &info;
5491 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5492 "QueryUserInfo failed");
5493 if (!NT_STATUS_IS_OK(q.out.result)) {
5494 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5495 q.in.level, nt_errstr(q.out.result));
5496 ret = false;
5497 } else {
5498 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5499 if (acct_flags == ACB_NORMAL) {
5500 expected_flags |= ACB_PW_EXPIRED;
5502 if ((info->info5.acct_flags) != expected_flags) {
5503 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5504 info->info5.acct_flags,
5505 expected_flags);
5506 ret = false;
5508 switch (acct_flags) {
5509 case ACB_SVRTRUST:
5510 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5511 torture_warning(tctx, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5512 DOMAIN_RID_DCS, info->info5.primary_gid);
5513 ret = false;
5515 break;
5516 case ACB_WSTRUST:
5517 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5518 torture_warning(tctx, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5519 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5520 ret = false;
5522 break;
5523 case ACB_NORMAL:
5524 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5525 torture_warning(tctx, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5526 DOMAIN_RID_USERS, info->info5.primary_gid);
5527 ret = false;
5529 break;
5533 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5534 domain_sid, acct_flags, name.string, which_ops,
5535 machine_credentials)) {
5536 ret = false;
5539 if (!policy_handle_empty(&user_handle)) {
5540 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5542 d.in.user_handle = &user_handle;
5543 d.out.user_handle = &user_handle;
5545 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5546 "DeleteUser failed");
5547 if (!NT_STATUS_IS_OK(d.out.result)) {
5548 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5549 ret = false;
5553 talloc_free(user_ctx);
5556 return ret;
5559 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5560 struct torture_context *tctx,
5561 struct policy_handle *handle)
5563 struct samr_QueryAliasInfo r;
5564 union samr_AliasInfo *info;
5565 uint16_t levels[] = {1, 2, 3};
5566 int i;
5567 bool ret = true;
5569 for (i=0;i<ARRAY_SIZE(levels);i++) {
5570 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5572 r.in.alias_handle = handle;
5573 r.in.level = levels[i];
5574 r.out.info = &info;
5576 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5577 "QueryAliasInfo failed");
5578 if (!NT_STATUS_IS_OK(r.out.result)) {
5579 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5580 levels[i], nt_errstr(r.out.result));
5581 ret = false;
5585 return ret;
5588 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5589 struct torture_context *tctx,
5590 struct policy_handle *handle)
5592 struct samr_QueryGroupInfo r;
5593 union samr_GroupInfo *info;
5594 uint16_t levels[] = {1, 2, 3, 4, 5};
5595 int i;
5596 bool ret = true;
5598 for (i=0;i<ARRAY_SIZE(levels);i++) {
5599 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5601 r.in.group_handle = handle;
5602 r.in.level = levels[i];
5603 r.out.info = &info;
5605 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5606 "QueryGroupInfo failed");
5607 if (!NT_STATUS_IS_OK(r.out.result)) {
5608 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5609 levels[i], nt_errstr(r.out.result));
5610 ret = false;
5614 return ret;
5617 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5618 struct torture_context *tctx,
5619 struct policy_handle *handle)
5621 struct samr_QueryGroupMember r;
5622 struct samr_RidAttrArray *rids = NULL;
5623 bool ret = true;
5625 torture_comment(tctx, "Testing QueryGroupMember\n");
5627 r.in.group_handle = handle;
5628 r.out.rids = &rids;
5630 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5631 "QueryGroupMember failed");
5632 if (!NT_STATUS_IS_OK(r.out.result)) {
5633 torture_warning(tctx, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
5634 ret = false;
5637 return ret;
5641 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5642 struct torture_context *tctx,
5643 struct policy_handle *handle)
5645 struct samr_QueryGroupInfo r;
5646 union samr_GroupInfo *info;
5647 struct samr_SetGroupInfo s;
5648 uint16_t levels[] = {1, 2, 3, 4};
5649 uint16_t set_ok[] = {0, 1, 1, 1};
5650 int i;
5651 bool ret = true;
5653 for (i=0;i<ARRAY_SIZE(levels);i++) {
5654 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5656 r.in.group_handle = handle;
5657 r.in.level = levels[i];
5658 r.out.info = &info;
5660 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5661 "QueryGroupInfo failed");
5662 if (!NT_STATUS_IS_OK(r.out.result)) {
5663 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5664 levels[i], nt_errstr(r.out.result));
5665 ret = false;
5668 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5670 s.in.group_handle = handle;
5671 s.in.level = levels[i];
5672 s.in.info = *r.out.info;
5674 #if 0
5675 /* disabled this, as it changes the name only from the point of view of samr,
5676 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5677 the name is still reserved, so creating the old name fails, but deleting by the old name
5678 also fails */
5679 if (s.in.level == 2) {
5680 init_lsa_String(&s.in.info->string, "NewName");
5682 #endif
5684 if (s.in.level == 4) {
5685 init_lsa_String(&s.in.info->description, "test description");
5688 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5689 "SetGroupInfo failed");
5690 if (set_ok[i]) {
5691 if (!NT_STATUS_IS_OK(s.out.result)) {
5692 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5693 r.in.level, nt_errstr(s.out.result));
5694 ret = false;
5695 continue;
5697 } else {
5698 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5699 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5700 r.in.level, nt_errstr(s.out.result));
5701 ret = false;
5702 continue;
5707 return ret;
5710 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5711 struct torture_context *tctx,
5712 struct policy_handle *handle)
5714 struct samr_QueryUserInfo r;
5715 union samr_UserInfo *info;
5716 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5717 11, 12, 13, 14, 16, 17, 20, 21};
5718 int i;
5719 bool ret = true;
5721 for (i=0;i<ARRAY_SIZE(levels);i++) {
5722 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5724 r.in.user_handle = handle;
5725 r.in.level = levels[i];
5726 r.out.info = &info;
5728 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5729 "QueryUserInfo failed");
5730 if (!NT_STATUS_IS_OK(r.out.result)) {
5731 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5732 levels[i], nt_errstr(r.out.result));
5733 ret = false;
5737 return ret;
5740 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5741 struct torture_context *tctx,
5742 struct policy_handle *handle)
5744 struct samr_QueryUserInfo2 r;
5745 union samr_UserInfo *info;
5746 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5747 11, 12, 13, 14, 16, 17, 20, 21};
5748 int i;
5749 bool ret = true;
5751 for (i=0;i<ARRAY_SIZE(levels);i++) {
5752 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5754 r.in.user_handle = handle;
5755 r.in.level = levels[i];
5756 r.out.info = &info;
5758 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5759 "QueryUserInfo2 failed");
5760 if (!NT_STATUS_IS_OK(r.out.result)) {
5761 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5762 levels[i], nt_errstr(r.out.result));
5763 ret = false;
5767 return ret;
5770 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5771 struct torture_context *tctx,
5772 struct policy_handle *handle, uint32_t rid)
5774 struct samr_OpenUser r;
5775 struct policy_handle user_handle;
5776 bool ret = true;
5778 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5780 r.in.domain_handle = handle;
5781 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5782 r.in.rid = rid;
5783 r.out.user_handle = &user_handle;
5785 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5786 "OpenUser failed");
5787 if (!NT_STATUS_IS_OK(r.out.result)) {
5788 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5789 return false;
5792 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5793 ret = false;
5796 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5797 ret = false;
5800 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5801 ret = false;
5804 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5805 ret = false;
5808 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5809 ret = false;
5812 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5813 ret = false;
5816 return ret;
5819 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5820 struct torture_context *tctx,
5821 struct policy_handle *handle, uint32_t rid)
5823 struct samr_OpenGroup r;
5824 struct policy_handle group_handle;
5825 bool ret = true;
5827 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5829 r.in.domain_handle = handle;
5830 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5831 r.in.rid = rid;
5832 r.out.group_handle = &group_handle;
5834 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5835 "OpenGroup failed");
5836 if (!NT_STATUS_IS_OK(r.out.result)) {
5837 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5838 return false;
5841 if (!torture_setting_bool(tctx, "samba3", false)) {
5842 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5843 ret = false;
5847 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5848 ret = false;
5851 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5852 ret = false;
5855 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5856 ret = false;
5859 return ret;
5862 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5863 struct torture_context *tctx,
5864 struct policy_handle *handle, uint32_t rid)
5866 struct samr_OpenAlias r;
5867 struct policy_handle alias_handle;
5868 bool ret = true;
5870 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5872 r.in.domain_handle = handle;
5873 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5874 r.in.rid = rid;
5875 r.out.alias_handle = &alias_handle;
5877 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5878 "OpenAlias failed");
5879 if (!NT_STATUS_IS_OK(r.out.result)) {
5880 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5881 return false;
5884 if (!torture_setting_bool(tctx, "samba3", false)) {
5885 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
5886 ret = false;
5890 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
5891 ret = false;
5894 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
5895 ret = false;
5898 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
5899 ret = false;
5902 return ret;
5905 static bool check_mask(struct dcerpc_binding_handle *b,
5906 struct torture_context *tctx,
5907 struct policy_handle *handle, uint32_t rid,
5908 uint32_t acct_flag_mask)
5910 struct samr_OpenUser r;
5911 struct samr_QueryUserInfo q;
5912 union samr_UserInfo *info;
5913 struct policy_handle user_handle;
5914 bool ret = true;
5916 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5918 r.in.domain_handle = handle;
5919 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5920 r.in.rid = rid;
5921 r.out.user_handle = &user_handle;
5923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5924 "OpenUser failed");
5925 if (!NT_STATUS_IS_OK(r.out.result)) {
5926 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5927 return false;
5930 q.in.user_handle = &user_handle;
5931 q.in.level = 16;
5932 q.out.info = &info;
5934 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5935 "QueryUserInfo failed");
5936 if (!NT_STATUS_IS_OK(q.out.result)) {
5937 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5938 nt_errstr(q.out.result));
5939 ret = false;
5940 } else {
5941 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5942 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5943 acct_flag_mask, info->info16.acct_flags, rid);
5944 ret = false;
5948 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5949 ret = false;
5952 return ret;
5955 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
5956 struct torture_context *tctx,
5957 struct policy_handle *handle)
5959 struct samr_EnumDomainUsers r;
5960 uint32_t mask, resume_handle=0;
5961 int i, mask_idx;
5962 bool ret = true;
5963 struct samr_LookupNames n;
5964 struct samr_LookupRids lr ;
5965 struct lsa_Strings names;
5966 struct samr_Ids rids, types;
5967 struct samr_SamArray *sam = NULL;
5968 uint32_t num_entries = 0;
5970 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5971 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5972 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5973 ACB_PWNOEXP, 0};
5975 torture_comment(tctx, "Testing EnumDomainUsers\n");
5977 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5978 r.in.domain_handle = handle;
5979 r.in.resume_handle = &resume_handle;
5980 r.in.acct_flags = mask = masks[mask_idx];
5981 r.in.max_size = (uint32_t)-1;
5982 r.out.resume_handle = &resume_handle;
5983 r.out.num_entries = &num_entries;
5984 r.out.sam = &sam;
5986 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
5987 "EnumDomainUsers failed");
5988 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
5989 !NT_STATUS_IS_OK(r.out.result)) {
5990 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
5991 return false;
5994 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5996 if (sam->count == 0) {
5997 continue;
6000 for (i=0;i<sam->count;i++) {
6001 if (mask) {
6002 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6003 ret = false;
6005 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6006 ret = false;
6011 torture_comment(tctx, "Testing LookupNames\n");
6012 n.in.domain_handle = handle;
6013 n.in.num_names = sam->count;
6014 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6015 n.out.rids = &rids;
6016 n.out.types = &types;
6017 for (i=0;i<sam->count;i++) {
6018 n.in.names[i].string = sam->entries[i].name.string;
6020 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6021 "LookupNames failed");
6022 if (!NT_STATUS_IS_OK(n.out.result)) {
6023 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6024 ret = false;
6028 torture_comment(tctx, "Testing LookupRids\n");
6029 lr.in.domain_handle = handle;
6030 lr.in.num_rids = sam->count;
6031 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6032 lr.out.names = &names;
6033 lr.out.types = &types;
6034 for (i=0;i<sam->count;i++) {
6035 lr.in.rids[i] = sam->entries[i].idx;
6037 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6038 "LookupRids failed");
6039 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6041 return ret;
6045 try blasting the server with a bunch of sync requests
6047 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6048 struct policy_handle *handle)
6050 struct samr_EnumDomainUsers r;
6051 uint32_t resume_handle=0;
6052 int i;
6053 #define ASYNC_COUNT 100
6054 struct tevent_req *req[ASYNC_COUNT];
6056 if (!torture_setting_bool(tctx, "dangerous", false)) {
6057 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6060 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6062 r.in.domain_handle = handle;
6063 r.in.resume_handle = &resume_handle;
6064 r.in.acct_flags = 0;
6065 r.in.max_size = (uint32_t)-1;
6066 r.out.resume_handle = &resume_handle;
6068 for (i=0;i<ASYNC_COUNT;i++) {
6069 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6072 for (i=0;i<ASYNC_COUNT;i++) {
6073 tevent_req_poll(req[i], tctx->ev);
6074 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6075 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6076 i, nt_errstr(r.out.result)));
6079 torture_comment(tctx, "%d async requests OK\n", i);
6081 return true;
6084 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6085 struct torture_context *tctx,
6086 struct policy_handle *handle)
6088 struct samr_EnumDomainGroups r;
6089 uint32_t resume_handle=0;
6090 struct samr_SamArray *sam = NULL;
6091 uint32_t num_entries = 0;
6092 int i;
6093 bool ret = true;
6094 bool universal_group_found = false;
6096 torture_comment(tctx, "Testing EnumDomainGroups\n");
6098 r.in.domain_handle = handle;
6099 r.in.resume_handle = &resume_handle;
6100 r.in.max_size = (uint32_t)-1;
6101 r.out.resume_handle = &resume_handle;
6102 r.out.num_entries = &num_entries;
6103 r.out.sam = &sam;
6105 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6106 "EnumDomainGroups failed");
6107 if (!NT_STATUS_IS_OK(r.out.result)) {
6108 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6109 return false;
6112 if (!sam) {
6113 return false;
6116 for (i=0;i<sam->count;i++) {
6117 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6118 ret = false;
6120 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6121 "Enterprise Admins") == 0)) {
6122 universal_group_found = true;
6126 /* when we are running this on s4 we should get back at least the
6127 * "Enterprise Admins" universal group. If we don't get a group entry
6128 * at all we probably are performing the test on the builtin domain.
6129 * So ignore this case. */
6130 if (torture_setting_bool(tctx, "samba4", false)) {
6131 if ((sam->count > 0) && (!universal_group_found)) {
6132 ret = false;
6136 return ret;
6139 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6140 struct torture_context *tctx,
6141 struct policy_handle *handle)
6143 struct samr_EnumDomainAliases r;
6144 uint32_t resume_handle=0;
6145 struct samr_SamArray *sam = NULL;
6146 uint32_t num_entries = 0;
6147 int i;
6148 bool ret = true;
6150 torture_comment(tctx, "Testing EnumDomainAliases\n");
6152 r.in.domain_handle = handle;
6153 r.in.resume_handle = &resume_handle;
6154 r.in.max_size = (uint32_t)-1;
6155 r.out.sam = &sam;
6156 r.out.num_entries = &num_entries;
6157 r.out.resume_handle = &resume_handle;
6159 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6160 "EnumDomainAliases failed");
6161 if (!NT_STATUS_IS_OK(r.out.result)) {
6162 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6163 return false;
6166 if (!sam) {
6167 return false;
6170 for (i=0;i<sam->count;i++) {
6171 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6172 ret = false;
6176 return ret;
6179 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6180 struct torture_context *tctx,
6181 struct policy_handle *handle)
6183 struct samr_GetDisplayEnumerationIndex r;
6184 bool ret = true;
6185 uint16_t levels[] = {1, 2, 3, 4, 5};
6186 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6187 struct lsa_String name;
6188 uint32_t idx = 0;
6189 int i;
6191 for (i=0;i<ARRAY_SIZE(levels);i++) {
6192 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6194 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6196 r.in.domain_handle = handle;
6197 r.in.level = levels[i];
6198 r.in.name = &name;
6199 r.out.idx = &idx;
6201 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6202 "GetDisplayEnumerationIndex failed");
6204 if (ok_lvl[i] &&
6205 !NT_STATUS_IS_OK(r.out.result) &&
6206 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6207 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6208 levels[i], nt_errstr(r.out.result));
6209 ret = false;
6212 init_lsa_String(&name, "zzzzzzzz");
6214 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6215 "GetDisplayEnumerationIndex failed");
6217 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6218 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6219 levels[i], nt_errstr(r.out.result));
6220 ret = false;
6224 return ret;
6227 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6228 struct torture_context *tctx,
6229 struct policy_handle *handle)
6231 struct samr_GetDisplayEnumerationIndex2 r;
6232 bool ret = true;
6233 uint16_t levels[] = {1, 2, 3, 4, 5};
6234 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6235 struct lsa_String name;
6236 uint32_t idx = 0;
6237 int i;
6239 for (i=0;i<ARRAY_SIZE(levels);i++) {
6240 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6242 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6244 r.in.domain_handle = handle;
6245 r.in.level = levels[i];
6246 r.in.name = &name;
6247 r.out.idx = &idx;
6249 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6250 "GetDisplayEnumerationIndex2 failed");
6251 if (ok_lvl[i] &&
6252 !NT_STATUS_IS_OK(r.out.result) &&
6253 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6254 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6255 levels[i], nt_errstr(r.out.result));
6256 ret = false;
6259 init_lsa_String(&name, "zzzzzzzz");
6261 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6262 "GetDisplayEnumerationIndex2 failed");
6263 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6264 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6265 levels[i], nt_errstr(r.out.result));
6266 ret = false;
6270 return ret;
6273 #define STRING_EQUAL_QUERY(s1, s2, user) \
6274 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6275 /* odd, but valid */ \
6276 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6277 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6278 #s1, user.string, s1.string, s2.string, __location__); \
6279 ret = false; \
6281 #define INT_EQUAL_QUERY(s1, s2, user) \
6282 if (s1 != s2) { \
6283 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6284 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6285 ret = false; \
6288 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6289 struct torture_context *tctx,
6290 struct samr_QueryDisplayInfo *querydisplayinfo,
6291 bool *seen_testuser)
6293 struct samr_OpenUser r;
6294 struct samr_QueryUserInfo q;
6295 union samr_UserInfo *info;
6296 struct policy_handle user_handle;
6297 int i, ret = true;
6298 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6299 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6300 for (i = 0; ; i++) {
6301 switch (querydisplayinfo->in.level) {
6302 case 1:
6303 if (i >= querydisplayinfo->out.info->info1.count) {
6304 return ret;
6306 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6307 break;
6308 case 2:
6309 if (i >= querydisplayinfo->out.info->info2.count) {
6310 return ret;
6312 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6313 break;
6314 case 3:
6315 /* Groups */
6316 case 4:
6317 case 5:
6318 /* Not interested in validating just the account name */
6319 return true;
6322 r.out.user_handle = &user_handle;
6324 switch (querydisplayinfo->in.level) {
6325 case 1:
6326 case 2:
6327 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6328 "OpenUser failed");
6329 if (!NT_STATUS_IS_OK(r.out.result)) {
6330 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6331 return false;
6335 q.in.user_handle = &user_handle;
6336 q.in.level = 21;
6337 q.out.info = &info;
6338 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6339 "QueryUserInfo failed");
6340 if (!NT_STATUS_IS_OK(r.out.result)) {
6341 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6342 return false;
6345 switch (querydisplayinfo->in.level) {
6346 case 1:
6347 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6348 *seen_testuser = true;
6350 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6351 info->info21.full_name, info->info21.account_name);
6352 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6353 info->info21.account_name, info->info21.account_name);
6354 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6355 info->info21.description, info->info21.account_name);
6356 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6357 info->info21.rid, info->info21.account_name);
6358 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6359 info->info21.acct_flags, info->info21.account_name);
6361 break;
6362 case 2:
6363 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6364 info->info21.account_name, info->info21.account_name);
6365 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6366 info->info21.description, info->info21.account_name);
6367 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6368 info->info21.rid, info->info21.account_name);
6369 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6370 info->info21.acct_flags, info->info21.account_name);
6372 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6373 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6374 info->info21.account_name.string);
6377 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6378 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6379 info->info21.account_name.string,
6380 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6381 info->info21.acct_flags);
6382 return false;
6385 break;
6388 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6389 return false;
6392 return ret;
6395 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6396 struct torture_context *tctx,
6397 struct policy_handle *handle)
6399 struct samr_QueryDisplayInfo r;
6400 struct samr_QueryDomainInfo dom_info;
6401 union samr_DomainInfo *info = NULL;
6402 bool ret = true;
6403 uint16_t levels[] = {1, 2, 3, 4, 5};
6404 int i;
6405 bool seen_testuser = false;
6406 uint32_t total_size;
6407 uint32_t returned_size;
6408 union samr_DispInfo disp_info;
6411 for (i=0;i<ARRAY_SIZE(levels);i++) {
6412 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6414 r.in.start_idx = 0;
6415 r.out.result = STATUS_MORE_ENTRIES;
6416 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6417 r.in.domain_handle = handle;
6418 r.in.level = levels[i];
6419 r.in.max_entries = 2;
6420 r.in.buf_size = (uint32_t)-1;
6421 r.out.total_size = &total_size;
6422 r.out.returned_size = &returned_size;
6423 r.out.info = &disp_info;
6425 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6426 "QueryDisplayInfo failed");
6427 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6428 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6429 levels[i], nt_errstr(r.out.result));
6430 ret = false;
6432 switch (r.in.level) {
6433 case 1:
6434 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6435 ret = false;
6437 r.in.start_idx += r.out.info->info1.count;
6438 break;
6439 case 2:
6440 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6441 ret = false;
6443 r.in.start_idx += r.out.info->info2.count;
6444 break;
6445 case 3:
6446 r.in.start_idx += r.out.info->info3.count;
6447 break;
6448 case 4:
6449 r.in.start_idx += r.out.info->info4.count;
6450 break;
6451 case 5:
6452 r.in.start_idx += r.out.info->info5.count;
6453 break;
6456 dom_info.in.domain_handle = handle;
6457 dom_info.in.level = 2;
6458 dom_info.out.info = &info;
6460 /* Check number of users returned is correct */
6461 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6462 "QueryDomainInfo failed");
6463 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6464 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6465 r.in.level, nt_errstr(dom_info.out.result));
6466 ret = false;
6467 break;
6469 switch (r.in.level) {
6470 case 1:
6471 case 4:
6472 if (info->general.num_users < r.in.start_idx) {
6473 /* On AD deployments this numbers don't match
6474 * since QueryDisplayInfo returns universal and
6475 * global groups, QueryDomainInfo only global
6476 * ones. */
6477 if (torture_setting_bool(tctx, "samba3", false)) {
6478 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6479 r.in.start_idx, info->general.num_groups,
6480 info->general.domain_name.string);
6481 ret = false;
6484 if (!seen_testuser) {
6485 struct policy_handle user_handle;
6486 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6487 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6488 info->general.domain_name.string);
6489 ret = false;
6490 test_samr_handle_Close(b, tctx, &user_handle);
6493 break;
6494 case 3:
6495 case 5:
6496 if (info->general.num_groups != r.in.start_idx) {
6497 /* On AD deployments this numbers don't match
6498 * since QueryDisplayInfo returns universal and
6499 * global groups, QueryDomainInfo only global
6500 * ones. */
6501 if (torture_setting_bool(tctx, "samba3", false)) {
6502 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6503 r.in.start_idx, info->general.num_groups,
6504 info->general.domain_name.string);
6505 ret = false;
6509 break;
6514 return ret;
6517 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6518 struct torture_context *tctx,
6519 struct policy_handle *handle)
6521 struct samr_QueryDisplayInfo2 r;
6522 bool ret = true;
6523 uint16_t levels[] = {1, 2, 3, 4, 5};
6524 int i;
6525 uint32_t total_size;
6526 uint32_t returned_size;
6527 union samr_DispInfo info;
6529 for (i=0;i<ARRAY_SIZE(levels);i++) {
6530 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6532 r.in.domain_handle = handle;
6533 r.in.level = levels[i];
6534 r.in.start_idx = 0;
6535 r.in.max_entries = 1000;
6536 r.in.buf_size = (uint32_t)-1;
6537 r.out.total_size = &total_size;
6538 r.out.returned_size = &returned_size;
6539 r.out.info = &info;
6541 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6542 "QueryDisplayInfo2 failed");
6543 if (!NT_STATUS_IS_OK(r.out.result)) {
6544 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6545 levels[i], nt_errstr(r.out.result));
6546 ret = false;
6550 return ret;
6553 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6554 struct torture_context *tctx,
6555 struct policy_handle *handle)
6557 struct samr_QueryDisplayInfo3 r;
6558 bool ret = true;
6559 uint16_t levels[] = {1, 2, 3, 4, 5};
6560 int i;
6561 uint32_t total_size;
6562 uint32_t returned_size;
6563 union samr_DispInfo info;
6565 for (i=0;i<ARRAY_SIZE(levels);i++) {
6566 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6568 r.in.domain_handle = handle;
6569 r.in.level = levels[i];
6570 r.in.start_idx = 0;
6571 r.in.max_entries = 1000;
6572 r.in.buf_size = (uint32_t)-1;
6573 r.out.total_size = &total_size;
6574 r.out.returned_size = &returned_size;
6575 r.out.info = &info;
6577 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6578 "QueryDisplayInfo3 failed");
6579 if (!NT_STATUS_IS_OK(r.out.result)) {
6580 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6581 levels[i], nt_errstr(r.out.result));
6582 ret = false;
6586 return ret;
6590 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6591 struct torture_context *tctx,
6592 struct policy_handle *handle)
6594 struct samr_QueryDisplayInfo r;
6595 bool ret = true;
6596 uint32_t total_size;
6597 uint32_t returned_size;
6598 union samr_DispInfo info;
6600 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6602 r.in.domain_handle = handle;
6603 r.in.level = 1;
6604 r.in.start_idx = 0;
6605 r.in.max_entries = 1;
6606 r.in.buf_size = (uint32_t)-1;
6607 r.out.total_size = &total_size;
6608 r.out.returned_size = &returned_size;
6609 r.out.info = &info;
6611 do {
6612 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6613 "QueryDisplayInfo failed");
6614 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6615 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6616 torture_warning(tctx, "expected idx %d but got %d\n",
6617 r.in.start_idx + 1,
6618 r.out.info->info1.entries[0].idx);
6619 break;
6622 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6623 !NT_STATUS_IS_OK(r.out.result)) {
6624 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6625 r.in.level, nt_errstr(r.out.result));
6626 ret = false;
6627 break;
6629 r.in.start_idx++;
6630 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6631 NT_STATUS_IS_OK(r.out.result)) &&
6632 *r.out.returned_size != 0);
6634 return ret;
6637 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6638 struct torture_context *tctx,
6639 struct policy_handle *handle)
6641 struct samr_QueryDomainInfo r;
6642 union samr_DomainInfo *info = NULL;
6643 struct samr_SetDomainInfo s;
6644 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6645 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6646 int i;
6647 bool ret = true;
6648 struct dcerpc_binding_handle *b = p->binding_handle;
6649 const char *domain_comment = talloc_asprintf(tctx,
6650 "Tortured by Samba4 RPC-SAMR: %s",
6651 timestring(tctx, time(NULL)));
6653 s.in.domain_handle = handle;
6654 s.in.level = 4;
6655 s.in.info = talloc(tctx, union samr_DomainInfo);
6657 s.in.info->oem.oem_information.string = domain_comment;
6658 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6659 "SetDomainInfo failed");
6660 if (!NT_STATUS_IS_OK(s.out.result)) {
6661 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6662 s.in.level, nt_errstr(s.out.result));
6663 return false;
6666 for (i=0;i<ARRAY_SIZE(levels);i++) {
6667 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6669 r.in.domain_handle = handle;
6670 r.in.level = levels[i];
6671 r.out.info = &info;
6673 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6674 "QueryDomainInfo failed");
6675 if (!NT_STATUS_IS_OK(r.out.result)) {
6676 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6677 r.in.level, nt_errstr(r.out.result));
6678 ret = false;
6679 continue;
6682 switch (levels[i]) {
6683 case 2:
6684 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6685 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6686 levels[i], info->general.oem_information.string, domain_comment);
6687 if (!torture_setting_bool(tctx, "samba3", false)) {
6688 ret = false;
6691 if (!info->general.primary.string) {
6692 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6693 levels[i]);
6694 ret = false;
6695 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6696 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6697 if (torture_setting_bool(tctx, "samba3", false)) {
6698 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6699 levels[i], info->general.primary.string, dcerpc_server_name(p));
6703 break;
6704 case 4:
6705 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6706 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6707 levels[i], info->oem.oem_information.string, domain_comment);
6708 if (!torture_setting_bool(tctx, "samba3", false)) {
6709 ret = false;
6712 break;
6713 case 6:
6714 if (!info->info6.primary.string) {
6715 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6716 levels[i]);
6717 ret = false;
6719 break;
6720 case 11:
6721 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6722 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6723 levels[i], info->general2.general.oem_information.string, domain_comment);
6724 if (!torture_setting_bool(tctx, "samba3", false)) {
6725 ret = false;
6728 break;
6731 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6733 s.in.domain_handle = handle;
6734 s.in.level = levels[i];
6735 s.in.info = info;
6737 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6738 "SetDomainInfo failed");
6739 if (set_ok[i]) {
6740 if (!NT_STATUS_IS_OK(s.out.result)) {
6741 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6742 r.in.level, nt_errstr(s.out.result));
6743 ret = false;
6744 continue;
6746 } else {
6747 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6748 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6749 r.in.level, nt_errstr(s.out.result));
6750 ret = false;
6751 continue;
6755 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6756 "QueryDomainInfo failed");
6757 if (!NT_STATUS_IS_OK(r.out.result)) {
6758 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6759 r.in.level, nt_errstr(r.out.result));
6760 ret = false;
6761 continue;
6765 return ret;
6769 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6770 struct torture_context *tctx,
6771 struct policy_handle *handle)
6773 struct samr_QueryDomainInfo2 r;
6774 union samr_DomainInfo *info = NULL;
6775 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6776 int i;
6777 bool ret = true;
6779 for (i=0;i<ARRAY_SIZE(levels);i++) {
6780 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6782 r.in.domain_handle = handle;
6783 r.in.level = levels[i];
6784 r.out.info = &info;
6786 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6787 "QueryDomainInfo2 failed");
6788 if (!NT_STATUS_IS_OK(r.out.result)) {
6789 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6790 r.in.level, nt_errstr(r.out.result));
6791 ret = false;
6792 continue;
6796 return true;
6799 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6800 set of group names. */
6801 static bool test_GroupList(struct dcerpc_binding_handle *b,
6802 struct torture_context *tctx,
6803 struct dom_sid *domain_sid,
6804 struct policy_handle *handle)
6806 struct samr_EnumDomainGroups q1;
6807 struct samr_QueryDisplayInfo q2;
6808 NTSTATUS status;
6809 uint32_t resume_handle=0;
6810 struct samr_SamArray *sam = NULL;
6811 uint32_t num_entries = 0;
6812 int i;
6813 bool ret = true;
6814 uint32_t total_size;
6815 uint32_t returned_size;
6816 union samr_DispInfo info;
6818 int num_names = 0;
6819 const char **names = NULL;
6821 bool builtin_domain = dom_sid_compare(domain_sid,
6822 &global_sid_Builtin) == 0;
6824 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6826 q1.in.domain_handle = handle;
6827 q1.in.resume_handle = &resume_handle;
6828 q1.in.max_size = 5;
6829 q1.out.resume_handle = &resume_handle;
6830 q1.out.num_entries = &num_entries;
6831 q1.out.sam = &sam;
6833 status = STATUS_MORE_ENTRIES;
6834 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6835 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6836 "EnumDomainGroups failed");
6837 status = q1.out.result;
6839 if (!NT_STATUS_IS_OK(status) &&
6840 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6841 break;
6843 for (i=0; i<*q1.out.num_entries; i++) {
6844 add_string_to_array(tctx,
6845 sam->entries[i].name.string,
6846 &names, &num_names);
6850 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6852 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6854 if (builtin_domain) {
6855 torture_assert(tctx, num_names == 0,
6856 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6859 q2.in.domain_handle = handle;
6860 q2.in.level = 5;
6861 q2.in.start_idx = 0;
6862 q2.in.max_entries = 5;
6863 q2.in.buf_size = (uint32_t)-1;
6864 q2.out.total_size = &total_size;
6865 q2.out.returned_size = &returned_size;
6866 q2.out.info = &info;
6868 status = STATUS_MORE_ENTRIES;
6869 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6870 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6871 "QueryDisplayInfo failed");
6872 status = q2.out.result;
6873 if (!NT_STATUS_IS_OK(status) &&
6874 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6875 break;
6877 for (i=0; i<q2.out.info->info5.count; i++) {
6878 int j;
6879 const char *name = q2.out.info->info5.entries[i].account_name.string;
6880 bool found = false;
6881 for (j=0; j<num_names; j++) {
6882 if (names[j] == NULL)
6883 continue;
6884 if (strequal(names[j], name)) {
6885 names[j] = NULL;
6886 found = true;
6887 break;
6891 if ((!found) && (!builtin_domain)) {
6892 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6893 name);
6894 ret = false;
6897 q2.in.start_idx += q2.out.info->info5.count;
6900 if (!NT_STATUS_IS_OK(status)) {
6901 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6902 nt_errstr(status));
6903 ret = false;
6906 if (builtin_domain) {
6907 torture_assert(tctx, q2.in.start_idx != 0,
6908 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
6911 for (i=0; i<num_names; i++) {
6912 if (names[i] != NULL) {
6913 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6914 names[i]);
6915 ret = false;
6919 return ret;
6922 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
6923 struct torture_context *tctx,
6924 struct policy_handle *group_handle)
6926 struct samr_DeleteDomainGroup d;
6928 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6930 d.in.group_handle = group_handle;
6931 d.out.group_handle = group_handle;
6933 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
6934 "DeleteDomainGroup failed");
6935 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
6937 return true;
6940 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
6941 struct torture_context *tctx,
6942 struct policy_handle *domain_handle)
6944 struct samr_TestPrivateFunctionsDomain r;
6945 bool ret = true;
6947 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6949 r.in.domain_handle = domain_handle;
6951 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
6952 "TestPrivateFunctionsDomain failed");
6953 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6955 return ret;
6958 static bool test_RidToSid(struct dcerpc_binding_handle *b,
6959 struct torture_context *tctx,
6960 struct dom_sid *domain_sid,
6961 struct policy_handle *domain_handle)
6963 struct samr_RidToSid r;
6964 bool ret = true;
6965 struct dom_sid *calc_sid, *out_sid;
6966 int rids[] = { 0, 42, 512, 10200 };
6967 int i;
6969 for (i=0;i<ARRAY_SIZE(rids);i++) {
6970 torture_comment(tctx, "Testing RidToSid\n");
6972 calc_sid = dom_sid_dup(tctx, domain_sid);
6973 r.in.domain_handle = domain_handle;
6974 r.in.rid = rids[i];
6975 r.out.sid = &out_sid;
6977 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
6978 "RidToSid failed");
6979 if (!NT_STATUS_IS_OK(r.out.result)) {
6980 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
6981 ret = false;
6982 } else {
6983 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6985 if (!dom_sid_equal(calc_sid, out_sid)) {
6986 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6987 dom_sid_string(tctx, out_sid),
6988 dom_sid_string(tctx, calc_sid));
6989 ret = false;
6994 return ret;
6997 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
6998 struct torture_context *tctx,
6999 struct policy_handle *domain_handle)
7001 struct samr_GetBootKeyInformation r;
7002 bool ret = true;
7003 uint32_t unknown = 0;
7004 NTSTATUS status;
7006 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7008 r.in.domain_handle = domain_handle;
7009 r.out.unknown = &unknown;
7011 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7012 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7013 status = r.out.result;
7015 if (!NT_STATUS_IS_OK(status)) {
7016 /* w2k3 seems to fail this sometimes and pass it sometimes */
7017 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7020 return ret;
7023 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7024 struct torture_context *tctx,
7025 struct policy_handle *domain_handle,
7026 struct policy_handle *group_handle)
7028 NTSTATUS status;
7029 struct samr_AddGroupMember r;
7030 struct samr_DeleteGroupMember d;
7031 struct samr_QueryGroupMember q;
7032 struct samr_RidAttrArray *rids = NULL;
7033 struct samr_SetMemberAttributesOfGroup s;
7034 uint32_t rid;
7035 bool found_member = false;
7036 int i;
7038 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7039 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7041 r.in.group_handle = group_handle;
7042 r.in.rid = rid;
7043 r.in.flags = 0; /* ??? */
7045 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7047 d.in.group_handle = group_handle;
7048 d.in.rid = rid;
7050 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7051 "DeleteGroupMember failed");
7052 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7054 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7055 "AddGroupMember failed");
7056 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7058 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7059 "AddGroupMember failed");
7060 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7062 if (torture_setting_bool(tctx, "samba4", false) ||
7063 torture_setting_bool(tctx, "samba3", false)) {
7064 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7065 } else {
7066 /* this one is quite strange. I am using random inputs in the
7067 hope of triggering an error that might give us a clue */
7069 s.in.group_handle = group_handle;
7070 s.in.unknown1 = random();
7071 s.in.unknown2 = random();
7073 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7074 "SetMemberAttributesOfGroup failed");
7075 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7078 q.in.group_handle = group_handle;
7079 q.out.rids = &rids;
7081 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7082 "QueryGroupMember failed");
7083 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7084 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7086 for (i=0; i < rids->count; i++) {
7087 if (rids->rids[i] == rid) {
7088 found_member = true;
7092 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7094 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7095 "DeleteGroupMember failed");
7096 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7098 rids = NULL;
7099 found_member = false;
7101 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7102 "QueryGroupMember failed");
7103 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7104 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7106 for (i=0; i < rids->count; i++) {
7107 if (rids->rids[i] == rid) {
7108 found_member = true;
7112 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7115 "AddGroupMember failed");
7116 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7118 return true;
7122 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7123 struct torture_context *tctx,
7124 struct policy_handle *domain_handle,
7125 const char *group_name,
7126 struct policy_handle *group_handle,
7127 struct dom_sid *domain_sid,
7128 bool test_group)
7130 struct samr_CreateDomainGroup r;
7131 uint32_t rid;
7132 struct lsa_String name;
7133 bool ret = true;
7135 init_lsa_String(&name, group_name);
7137 r.in.domain_handle = domain_handle;
7138 r.in.name = &name;
7139 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7140 r.out.group_handle = group_handle;
7141 r.out.rid = &rid;
7143 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7145 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7146 "CreateDomainGroup failed");
7148 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7149 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7150 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7151 return true;
7152 } else {
7153 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7154 nt_errstr(r.out.result));
7155 return false;
7159 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7160 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7161 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7162 nt_errstr(r.out.result));
7163 return false;
7165 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7166 "CreateDomainGroup failed");
7168 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7169 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7171 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7172 nt_errstr(r.out.result));
7173 return false;
7175 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7176 "CreateDomainGroup failed");
7178 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7180 if (!test_group) {
7181 return ret;
7184 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7185 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7186 ret = false;
7189 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7190 ret = false;
7193 return ret;
7198 its not totally clear what this does. It seems to accept any sid you like.
7200 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7201 struct torture_context *tctx,
7202 struct policy_handle *domain_handle)
7204 struct samr_RemoveMemberFromForeignDomain r;
7206 r.in.domain_handle = domain_handle;
7207 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7209 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7210 "RemoveMemberFromForeignDomain failed");
7211 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7213 return true;
7216 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7217 struct torture_context *tctx,
7218 struct policy_handle *domain_handle,
7219 uint32_t *total_num_entries_p)
7221 NTSTATUS status;
7222 struct samr_EnumDomainUsers r;
7223 uint32_t resume_handle = 0;
7224 uint32_t num_entries = 0;
7225 uint32_t total_num_entries = 0;
7226 struct samr_SamArray *sam;
7228 r.in.domain_handle = domain_handle;
7229 r.in.acct_flags = 0;
7230 r.in.max_size = (uint32_t)-1;
7231 r.in.resume_handle = &resume_handle;
7233 r.out.sam = &sam;
7234 r.out.num_entries = &num_entries;
7235 r.out.resume_handle = &resume_handle;
7237 torture_comment(tctx, "Testing EnumDomainUsers\n");
7239 do {
7240 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7241 "EnumDomainUsers failed");
7242 if (NT_STATUS_IS_ERR(r.out.result)) {
7243 torture_assert_ntstatus_ok(tctx, r.out.result,
7244 "failed to enumerate users");
7246 status = r.out.result;
7248 total_num_entries += num_entries;
7249 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7251 if (total_num_entries_p) {
7252 *total_num_entries_p = total_num_entries;
7255 return true;
7258 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7259 struct torture_context *tctx,
7260 struct policy_handle *domain_handle,
7261 uint32_t *total_num_entries_p)
7263 NTSTATUS status;
7264 struct samr_EnumDomainGroups r;
7265 uint32_t resume_handle = 0;
7266 uint32_t num_entries = 0;
7267 uint32_t total_num_entries = 0;
7268 struct samr_SamArray *sam;
7270 r.in.domain_handle = domain_handle;
7271 r.in.max_size = (uint32_t)-1;
7272 r.in.resume_handle = &resume_handle;
7274 r.out.sam = &sam;
7275 r.out.num_entries = &num_entries;
7276 r.out.resume_handle = &resume_handle;
7278 torture_comment(tctx, "Testing EnumDomainGroups\n");
7280 do {
7281 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7282 "EnumDomainGroups failed");
7283 if (NT_STATUS_IS_ERR(r.out.result)) {
7284 torture_assert_ntstatus_ok(tctx, r.out.result,
7285 "failed to enumerate groups");
7287 status = r.out.result;
7289 total_num_entries += num_entries;
7290 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7292 if (total_num_entries_p) {
7293 *total_num_entries_p = total_num_entries;
7296 return true;
7299 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7300 struct torture_context *tctx,
7301 struct policy_handle *domain_handle,
7302 uint32_t *total_num_entries_p)
7304 NTSTATUS status;
7305 struct samr_EnumDomainAliases r;
7306 uint32_t resume_handle = 0;
7307 uint32_t num_entries = 0;
7308 uint32_t total_num_entries = 0;
7309 struct samr_SamArray *sam;
7311 r.in.domain_handle = domain_handle;
7312 r.in.max_size = (uint32_t)-1;
7313 r.in.resume_handle = &resume_handle;
7315 r.out.sam = &sam;
7316 r.out.num_entries = &num_entries;
7317 r.out.resume_handle = &resume_handle;
7319 torture_comment(tctx, "Testing EnumDomainAliases\n");
7321 do {
7322 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7323 "EnumDomainAliases failed");
7324 if (NT_STATUS_IS_ERR(r.out.result)) {
7325 torture_assert_ntstatus_ok(tctx, r.out.result,
7326 "failed to enumerate aliases");
7328 status = r.out.result;
7330 total_num_entries += num_entries;
7331 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7333 if (total_num_entries_p) {
7334 *total_num_entries_p = total_num_entries;
7337 return true;
7340 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7341 struct torture_context *tctx,
7342 struct policy_handle *handle,
7343 uint16_t level,
7344 uint32_t *total_num_entries_p)
7346 NTSTATUS status;
7347 struct samr_QueryDisplayInfo r;
7348 uint32_t total_num_entries = 0;
7350 r.in.domain_handle = handle;
7351 r.in.level = level;
7352 r.in.start_idx = 0;
7353 r.in.max_entries = (uint32_t)-1;
7354 r.in.buf_size = (uint32_t)-1;
7356 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7358 do {
7359 uint32_t total_size;
7360 uint32_t returned_size;
7361 union samr_DispInfo info;
7363 r.out.total_size = &total_size;
7364 r.out.returned_size = &returned_size;
7365 r.out.info = &info;
7367 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7368 "failed to query displayinfo");
7369 if (NT_STATUS_IS_ERR(r.out.result)) {
7370 torture_assert_ntstatus_ok(tctx, r.out.result,
7371 "failed to query displayinfo");
7373 status = r.out.result;
7375 if (*r.out.returned_size == 0) {
7376 break;
7379 switch (r.in.level) {
7380 case 1:
7381 total_num_entries += info.info1.count;
7382 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7383 break;
7384 case 2:
7385 total_num_entries += info.info2.count;
7386 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7387 break;
7388 case 3:
7389 total_num_entries += info.info3.count;
7390 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7391 break;
7392 case 4:
7393 total_num_entries += info.info4.count;
7394 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7395 break;
7396 case 5:
7397 total_num_entries += info.info5.count;
7398 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7399 break;
7400 default:
7401 return false;
7404 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7406 if (total_num_entries_p) {
7407 *total_num_entries_p = total_num_entries;
7410 return true;
7413 static bool test_ManyObjects(struct dcerpc_pipe *p,
7414 struct torture_context *tctx,
7415 struct policy_handle *domain_handle,
7416 struct dom_sid *domain_sid,
7417 struct torture_samr_context *ctx)
7419 uint32_t num_total = ctx->num_objects_large_dc;
7420 uint32_t num_enum = 0;
7421 uint32_t num_disp = 0;
7422 uint32_t num_created = 0;
7423 uint32_t num_anounced = 0;
7424 uint32_t i;
7425 struct dcerpc_binding_handle *b = p->binding_handle;
7427 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7429 /* query */
7432 struct samr_QueryDomainInfo2 r;
7433 union samr_DomainInfo *info;
7434 r.in.domain_handle = domain_handle;
7435 r.in.level = 2;
7436 r.out.info = &info;
7438 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7439 "QueryDomainInfo2 failed");
7440 torture_assert_ntstatus_ok(tctx, r.out.result,
7441 "failed to query domain info");
7443 switch (ctx->choice) {
7444 case TORTURE_SAMR_MANY_ACCOUNTS:
7445 num_anounced = info->general.num_users;
7446 break;
7447 case TORTURE_SAMR_MANY_GROUPS:
7448 num_anounced = info->general.num_groups;
7449 break;
7450 case TORTURE_SAMR_MANY_ALIASES:
7451 num_anounced = info->general.num_aliases;
7452 break;
7453 default:
7454 return false;
7458 /* create */
7460 for (i=0; i < num_total; i++) {
7462 const char *name = NULL;
7464 switch (ctx->choice) {
7465 case TORTURE_SAMR_MANY_ACCOUNTS:
7466 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7467 torture_assert(tctx,
7468 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7469 "failed to create user");
7470 break;
7471 case TORTURE_SAMR_MANY_GROUPS:
7472 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7473 torture_assert(tctx,
7474 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7475 "failed to create group");
7476 break;
7477 case TORTURE_SAMR_MANY_ALIASES:
7478 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7479 torture_assert(tctx,
7480 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7481 "failed to create alias");
7482 break;
7483 default:
7484 return false;
7486 if (!policy_handle_empty(&handles[i])) {
7487 num_created++;
7491 /* enum */
7493 switch (ctx->choice) {
7494 case TORTURE_SAMR_MANY_ACCOUNTS:
7495 torture_assert(tctx,
7496 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7497 "failed to enum users");
7498 break;
7499 case TORTURE_SAMR_MANY_GROUPS:
7500 torture_assert(tctx,
7501 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7502 "failed to enum groups");
7503 break;
7504 case TORTURE_SAMR_MANY_ALIASES:
7505 torture_assert(tctx,
7506 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7507 "failed to enum aliases");
7508 break;
7509 default:
7510 return false;
7513 /* dispinfo */
7515 switch (ctx->choice) {
7516 case TORTURE_SAMR_MANY_ACCOUNTS:
7517 torture_assert(tctx,
7518 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7519 "failed to query display info");
7520 break;
7521 case TORTURE_SAMR_MANY_GROUPS:
7522 torture_assert(tctx,
7523 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7524 "failed to query display info");
7525 break;
7526 case TORTURE_SAMR_MANY_ALIASES:
7527 /* no aliases in dispinfo */
7528 break;
7529 default:
7530 return false;
7533 /* close or delete */
7535 for (i=0; i < num_total; i++) {
7537 if (policy_handle_empty(&handles[i])) {
7538 continue;
7541 if (torture_setting_bool(tctx, "samba3", false)) {
7542 torture_assert(tctx,
7543 test_samr_handle_Close(b, tctx, &handles[i]),
7544 "failed to close handle");
7545 } else {
7546 switch (ctx->choice) {
7547 case TORTURE_SAMR_MANY_ACCOUNTS:
7548 torture_assert(tctx,
7549 test_DeleteUser(b, tctx, &handles[i]),
7550 "failed to delete user");
7551 break;
7552 case TORTURE_SAMR_MANY_GROUPS:
7553 torture_assert(tctx,
7554 test_DeleteDomainGroup(b, tctx, &handles[i]),
7555 "failed to delete group");
7556 break;
7557 case TORTURE_SAMR_MANY_ALIASES:
7558 torture_assert(tctx,
7559 test_DeleteAlias(b, tctx, &handles[i]),
7560 "failed to delete alias");
7561 break;
7562 default:
7563 return false;
7568 talloc_free(handles);
7570 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7571 torture_comment(tctx,
7572 "unexpected number of results (%u) returned in enum call, expected %u\n",
7573 num_enum, num_anounced + num_created);
7575 torture_comment(tctx,
7576 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7577 num_disp, num_anounced + num_created);
7580 return true;
7583 static bool test_Connect(struct dcerpc_binding_handle *b,
7584 struct torture_context *tctx,
7585 struct policy_handle *handle);
7587 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7588 struct torture_samr_context *ctx, struct dom_sid *sid)
7590 struct samr_OpenDomain r;
7591 struct policy_handle domain_handle;
7592 struct policy_handle alias_handle;
7593 struct policy_handle user_handle;
7594 struct policy_handle group_handle;
7595 bool ret = true;
7596 struct dcerpc_binding_handle *b = p->binding_handle;
7598 ZERO_STRUCT(alias_handle);
7599 ZERO_STRUCT(user_handle);
7600 ZERO_STRUCT(group_handle);
7601 ZERO_STRUCT(domain_handle);
7603 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7605 r.in.connect_handle = &ctx->handle;
7606 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7607 r.in.sid = sid;
7608 r.out.domain_handle = &domain_handle;
7610 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7611 "OpenDomain failed");
7612 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7614 /* run the domain tests with the main handle closed - this tests
7615 the servers reference counting */
7616 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7618 switch (ctx->choice) {
7619 case TORTURE_SAMR_PASSWORDS:
7620 case TORTURE_SAMR_USER_PRIVILEGES:
7621 if (!torture_setting_bool(tctx, "samba3", false)) {
7622 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7624 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7625 if (!ret) {
7626 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7628 break;
7629 case TORTURE_SAMR_USER_ATTRIBUTES:
7630 if (!torture_setting_bool(tctx, "samba3", false)) {
7631 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7633 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7634 /* This test needs 'complex' users to validate */
7635 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7636 if (!ret) {
7637 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7639 break;
7640 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7641 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7642 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7643 if (!torture_setting_bool(tctx, "samba3", false)) {
7644 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7646 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7647 if (!ret) {
7648 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7650 break;
7651 case TORTURE_SAMR_MANY_ACCOUNTS:
7652 case TORTURE_SAMR_MANY_GROUPS:
7653 case TORTURE_SAMR_MANY_ALIASES:
7654 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7655 if (!ret) {
7656 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7658 break;
7659 case TORTURE_SAMR_OTHER:
7660 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7661 if (!ret) {
7662 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7664 if (!torture_setting_bool(tctx, "samba3", false)) {
7665 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7667 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7668 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7669 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7670 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7671 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7672 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7673 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7674 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7675 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7676 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7677 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7678 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7679 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7681 if (torture_setting_bool(tctx, "samba4", false)) {
7682 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7683 } else {
7684 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7685 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7687 ret &= test_GroupList(b, tctx, sid, &domain_handle);
7688 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7689 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7690 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7691 if (!ret) {
7692 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7694 break;
7697 if (!policy_handle_empty(&user_handle) &&
7698 !test_DeleteUser(b, tctx, &user_handle)) {
7699 ret = false;
7702 if (!policy_handle_empty(&alias_handle) &&
7703 !test_DeleteAlias(b, tctx, &alias_handle)) {
7704 ret = false;
7707 if (!policy_handle_empty(&group_handle) &&
7708 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7709 ret = false;
7712 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7714 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7715 /* reconnect the main handle */
7717 if (!ret) {
7718 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7721 return ret;
7724 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7725 struct torture_samr_context *ctx, const char *domain)
7727 struct samr_LookupDomain r;
7728 struct dom_sid2 *sid = NULL;
7729 struct lsa_String n1;
7730 struct lsa_String n2;
7731 bool ret = true;
7732 struct dcerpc_binding_handle *b = p->binding_handle;
7734 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7736 /* check for correct error codes */
7737 r.in.connect_handle = &ctx->handle;
7738 r.in.domain_name = &n2;
7739 r.out.sid = &sid;
7740 n2.string = NULL;
7742 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7743 "LookupDomain failed");
7744 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7746 init_lsa_String(&n2, "xxNODOMAINxx");
7748 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7749 "LookupDomain failed");
7750 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7752 r.in.connect_handle = &ctx->handle;
7754 init_lsa_String(&n1, domain);
7755 r.in.domain_name = &n1;
7757 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7758 "LookupDomain failed");
7759 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7761 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7762 ret = false;
7765 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7766 ret = false;
7769 return ret;
7773 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7774 struct torture_samr_context *ctx)
7776 struct samr_EnumDomains r;
7777 uint32_t resume_handle = 0;
7778 uint32_t num_entries = 0;
7779 struct samr_SamArray *sam = NULL;
7780 int i;
7781 bool ret = true;
7782 struct dcerpc_binding_handle *b = p->binding_handle;
7784 r.in.connect_handle = &ctx->handle;
7785 r.in.resume_handle = &resume_handle;
7786 r.in.buf_size = (uint32_t)-1;
7787 r.out.resume_handle = &resume_handle;
7788 r.out.num_entries = &num_entries;
7789 r.out.sam = &sam;
7791 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7792 "EnumDomains failed");
7793 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7795 if (!*r.out.sam) {
7796 return false;
7799 for (i=0;i<sam->count;i++) {
7800 if (!test_LookupDomain(p, tctx, ctx,
7801 sam->entries[i].name.string)) {
7802 ret = false;
7806 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7807 "EnumDomains failed");
7808 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7810 return ret;
7814 static bool test_Connect(struct dcerpc_binding_handle *b,
7815 struct torture_context *tctx,
7816 struct policy_handle *handle)
7818 struct samr_Connect r;
7819 struct samr_Connect2 r2;
7820 struct samr_Connect3 r3;
7821 struct samr_Connect4 r4;
7822 struct samr_Connect5 r5;
7823 union samr_ConnectInfo info;
7824 struct policy_handle h;
7825 uint32_t level_out = 0;
7826 bool ret = true, got_handle = false;
7828 torture_comment(tctx, "Testing samr_Connect\n");
7830 r.in.system_name = 0;
7831 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7832 r.out.connect_handle = &h;
7834 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7835 "Connect failed");
7836 if (!NT_STATUS_IS_OK(r.out.result)) {
7837 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7838 ret = false;
7839 } else {
7840 got_handle = true;
7841 *handle = h;
7844 torture_comment(tctx, "Testing samr_Connect2\n");
7846 r2.in.system_name = NULL;
7847 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7848 r2.out.connect_handle = &h;
7850 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7851 "Connect2 failed");
7852 if (!NT_STATUS_IS_OK(r2.out.result)) {
7853 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7854 ret = false;
7855 } else {
7856 if (got_handle) {
7857 test_samr_handle_Close(b, tctx, handle);
7859 got_handle = true;
7860 *handle = h;
7863 torture_comment(tctx, "Testing samr_Connect3\n");
7865 r3.in.system_name = NULL;
7866 r3.in.unknown = 0;
7867 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7868 r3.out.connect_handle = &h;
7870 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7871 "Connect3 failed");
7872 if (!NT_STATUS_IS_OK(r3.out.result)) {
7873 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
7874 ret = false;
7875 } else {
7876 if (got_handle) {
7877 test_samr_handle_Close(b, tctx, handle);
7879 got_handle = true;
7880 *handle = h;
7883 torture_comment(tctx, "Testing samr_Connect4\n");
7885 r4.in.system_name = "";
7886 r4.in.client_version = 0;
7887 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7888 r4.out.connect_handle = &h;
7890 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
7891 "Connect4 failed");
7892 if (!NT_STATUS_IS_OK(r4.out.result)) {
7893 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
7894 ret = false;
7895 } else {
7896 if (got_handle) {
7897 test_samr_handle_Close(b, tctx, handle);
7899 got_handle = true;
7900 *handle = h;
7903 torture_comment(tctx, "Testing samr_Connect5\n");
7905 info.info1.client_version = 0;
7906 info.info1.unknown2 = 0;
7908 r5.in.system_name = "";
7909 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7910 r5.in.level_in = 1;
7911 r5.out.level_out = &level_out;
7912 r5.in.info_in = &info;
7913 r5.out.info_out = &info;
7914 r5.out.connect_handle = &h;
7916 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
7917 "Connect5 failed");
7918 if (!NT_STATUS_IS_OK(r5.out.result)) {
7919 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
7920 ret = false;
7921 } else {
7922 if (got_handle) {
7923 test_samr_handle_Close(b, tctx, handle);
7925 got_handle = true;
7926 *handle = h;
7929 return ret;
7933 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p,
7934 struct torture_context *tctx)
7936 struct samr_ValidatePassword r;
7937 union samr_ValidatePasswordReq req;
7938 union samr_ValidatePasswordRep *repp = NULL;
7939 NTSTATUS status;
7940 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7941 int i;
7942 struct dcerpc_binding_handle *b = p->binding_handle;
7944 torture_comment(tctx, "Testing samr_ValidatePassword\n");
7946 ZERO_STRUCT(r);
7947 r.in.level = NetValidatePasswordReset;
7948 r.in.req = &req;
7949 r.out.rep = &repp;
7951 ZERO_STRUCT(req);
7952 req.req3.account.string = "non-existant-account-aklsdji";
7954 for (i=0; passwords[i]; i++) {
7955 req.req3.password.string = passwords[i];
7957 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
7958 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
7959 torture_skip(tctx, "ValidatePassword not supported by server\n");
7961 torture_assert_ntstatus_ok(tctx, status,
7962 "samr_ValidatePassword failed");
7963 torture_assert_ntstatus_ok(tctx, r.out.result,
7964 "samr_ValidatePassword failed");
7965 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7966 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7967 req.req3.password.string, repp->ctr3.status);
7970 return true;
7973 bool torture_rpc_samr(struct torture_context *torture)
7975 NTSTATUS status;
7976 struct dcerpc_pipe *p;
7977 bool ret = true;
7978 struct torture_samr_context *ctx;
7979 struct dcerpc_binding_handle *b;
7981 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7982 if (!NT_STATUS_IS_OK(status)) {
7983 return false;
7985 b = p->binding_handle;
7987 ctx = talloc_zero(torture, struct torture_samr_context);
7989 ctx->choice = TORTURE_SAMR_OTHER;
7991 ret &= test_Connect(b, torture, &ctx->handle);
7993 if (!torture_setting_bool(torture, "samba3", false)) {
7994 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7997 ret &= test_EnumDomains(p, torture, ctx);
7999 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8001 ret &= test_Shutdown(b, torture, &ctx->handle);
8003 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8005 return ret;
8009 bool torture_rpc_samr_users(struct torture_context *torture)
8011 NTSTATUS status;
8012 struct dcerpc_pipe *p;
8013 bool ret = true;
8014 struct torture_samr_context *ctx;
8015 struct dcerpc_binding_handle *b;
8017 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8018 if (!NT_STATUS_IS_OK(status)) {
8019 return false;
8021 b = p->binding_handle;
8023 ctx = talloc_zero(torture, struct torture_samr_context);
8025 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8027 ret &= test_Connect(b, torture, &ctx->handle);
8029 if (!torture_setting_bool(torture, "samba3", false)) {
8030 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8033 ret &= test_EnumDomains(p, torture, ctx);
8035 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8037 ret &= test_Shutdown(b, torture, &ctx->handle);
8039 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8041 return ret;
8045 bool torture_rpc_samr_passwords(struct torture_context *torture)
8047 NTSTATUS status;
8048 struct dcerpc_pipe *p;
8049 bool ret = true;
8050 struct torture_samr_context *ctx;
8051 struct dcerpc_binding_handle *b;
8053 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8054 if (!NT_STATUS_IS_OK(status)) {
8055 return false;
8057 b = p->binding_handle;
8059 ctx = talloc_zero(torture, struct torture_samr_context);
8061 ctx->choice = TORTURE_SAMR_PASSWORDS;
8063 ret &= test_Connect(b, torture, &ctx->handle);
8065 ret &= test_EnumDomains(p, torture, ctx);
8067 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8069 ret &= test_samr_ValidatePassword(p, torture);
8071 return ret;
8074 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8075 struct dcerpc_pipe *p2,
8076 struct cli_credentials *machine_credentials)
8078 NTSTATUS status;
8079 struct dcerpc_pipe *p;
8080 bool ret = true;
8081 struct torture_samr_context *ctx;
8082 struct dcerpc_binding_handle *b;
8084 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8085 if (!NT_STATUS_IS_OK(status)) {
8086 return false;
8088 b = p->binding_handle;
8090 ctx = talloc_zero(torture, struct torture_samr_context);
8092 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8093 ctx->machine_credentials = machine_credentials;
8095 ret &= test_Connect(b, torture, &ctx->handle);
8097 ret &= test_EnumDomains(p, torture, ctx);
8099 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8101 return ret;
8104 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8106 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8107 struct torture_rpc_tcase *tcase;
8109 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8110 &ndr_table_samr,
8111 TEST_ACCOUNT_NAME_PWD);
8113 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8114 torture_rpc_samr_pwdlastset);
8116 return suite;
8119 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8120 struct dcerpc_pipe *p2,
8121 struct cli_credentials *machine_credentials)
8123 NTSTATUS status;
8124 struct dcerpc_pipe *p;
8125 bool ret = true;
8126 struct torture_samr_context *ctx;
8127 struct dcerpc_binding_handle *b;
8129 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8130 if (!NT_STATUS_IS_OK(status)) {
8131 return false;
8133 b = p->binding_handle;
8135 ctx = talloc_zero(torture, struct torture_samr_context);
8137 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8138 ctx->machine_credentials = machine_credentials;
8140 ret &= test_Connect(b, torture, &ctx->handle);
8142 ret &= test_EnumDomains(p, torture, ctx);
8144 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8146 return ret;
8149 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8151 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8152 struct torture_rpc_tcase *tcase;
8154 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8155 &ndr_table_samr,
8156 TEST_ACCOUNT_NAME_PWD);
8158 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8159 torture_rpc_samr_users_privileges_delete_user);
8161 return suite;
8164 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8165 struct dcerpc_pipe *p2,
8166 void *data)
8168 NTSTATUS status;
8169 struct dcerpc_pipe *p;
8170 bool ret = true;
8171 struct torture_samr_context *ctx =
8172 talloc_get_type_abort(data, struct torture_samr_context);
8173 struct dcerpc_binding_handle *b;
8175 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8176 if (!NT_STATUS_IS_OK(status)) {
8177 return false;
8179 b = p->binding_handle;
8181 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8182 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8183 ctx->num_objects_large_dc);
8185 ret &= test_Connect(b, torture, &ctx->handle);
8187 ret &= test_EnumDomains(p, torture, ctx);
8189 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8191 return ret;
8194 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8195 struct dcerpc_pipe *p2,
8196 void *data)
8198 NTSTATUS status;
8199 struct dcerpc_pipe *p;
8200 bool ret = true;
8201 struct torture_samr_context *ctx =
8202 talloc_get_type_abort(data, struct torture_samr_context);
8203 struct dcerpc_binding_handle *b;
8205 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8206 if (!NT_STATUS_IS_OK(status)) {
8207 return false;
8209 b = p->binding_handle;
8211 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8212 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8213 ctx->num_objects_large_dc);
8215 ret &= test_Connect(b, torture, &ctx->handle);
8217 ret &= test_EnumDomains(p, torture, ctx);
8219 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8221 return ret;
8224 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8225 struct dcerpc_pipe *p2,
8226 void *data)
8228 NTSTATUS status;
8229 struct dcerpc_pipe *p;
8230 bool ret = true;
8231 struct torture_samr_context *ctx =
8232 talloc_get_type_abort(data, struct torture_samr_context);
8233 struct dcerpc_binding_handle *b;
8235 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8236 if (!NT_STATUS_IS_OK(status)) {
8237 return false;
8239 b = p->binding_handle;
8241 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8242 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8243 ctx->num_objects_large_dc);
8245 ret &= test_Connect(b, torture, &ctx->handle);
8247 ret &= test_EnumDomains(p, torture, ctx);
8249 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8251 return ret;
8254 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8256 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8257 struct torture_rpc_tcase *tcase;
8258 struct torture_samr_context *ctx;
8260 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8262 ctx = talloc_zero(suite, struct torture_samr_context);
8263 ctx->num_objects_large_dc = 150;
8265 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8266 torture_rpc_samr_many_aliases, ctx);
8267 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8268 torture_rpc_samr_many_groups, ctx);
8269 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8270 torture_rpc_samr_many_accounts, ctx);
8272 return suite;
8275 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8276 struct dcerpc_pipe *p2,
8277 struct cli_credentials *machine_credentials)
8279 NTSTATUS status;
8280 struct dcerpc_pipe *p;
8281 bool ret = true;
8282 struct torture_samr_context *ctx;
8283 struct dcerpc_binding_handle *b;
8285 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8286 if (!NT_STATUS_IS_OK(status)) {
8287 return false;
8289 b = p->binding_handle;
8291 ctx = talloc_zero(torture, struct torture_samr_context);
8293 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8294 ctx->machine_credentials = machine_credentials;
8296 ret &= test_Connect(b, torture, &ctx->handle);
8298 ret &= test_EnumDomains(p, torture, ctx);
8300 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8302 return ret;
8305 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8307 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8308 struct torture_rpc_tcase *tcase;
8310 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8311 &ndr_table_samr,
8312 TEST_ACCOUNT_NAME_PWD);
8314 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8315 torture_rpc_samr_badpwdcount);
8317 return suite;
8320 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8321 struct dcerpc_pipe *p2,
8322 struct cli_credentials *machine_credentials)
8324 NTSTATUS status;
8325 struct dcerpc_pipe *p;
8326 bool ret = true;
8327 struct torture_samr_context *ctx;
8328 struct dcerpc_binding_handle *b;
8330 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8331 if (!NT_STATUS_IS_OK(status)) {
8332 return false;
8334 b = p->binding_handle;
8336 ctx = talloc_zero(torture, struct torture_samr_context);
8338 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8339 ctx->machine_credentials = machine_credentials;
8341 ret &= test_Connect(b, torture, &ctx->handle);
8343 ret &= test_EnumDomains(p, torture, ctx);
8345 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8347 return ret;
8350 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8352 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8353 struct torture_rpc_tcase *tcase;
8355 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8356 &ndr_table_samr,
8357 TEST_ACCOUNT_NAME_PWD);
8359 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8360 torture_rpc_samr_lockout);
8362 return suite;