s3-selftest: Remove some unnecessary comma
[Samba/gebeck_regimport.git] / source4 / torture / rpc / samr.c
blobbf1d713eed3b08e70eb50ce7940d31433e79b011
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) Jelmer Vernooij 2005-2007
8 Copyright (C) Guenther Deschner 2008-2010
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "torture/torture.h"
26 #include <tevent.h>
27 #include "system/time.h"
28 #include "system/network.h"
29 #include "librpc/gen_ndr/lsa.h"
30 #include "librpc/gen_ndr/ndr_netlogon.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_samr_c.h"
33 #include "librpc/gen_ndr/ndr_lsa_c.h"
34 #include "../lib/crypto/crypto.h"
35 #include "libcli/auth/libcli_auth.h"
36 #include "libcli/security/security.h"
37 #include "torture/rpc/torture_rpc.h"
38 #include "param/param.h"
39 #include "auth/gensec/gensec.h"
40 #include "auth/gensec/schannel.h"
41 #include "auth/gensec/gensec_proto.h"
42 #include "../libcli/auth/schannel.h"
44 #define TEST_ACCOUNT_NAME "samrtorturetest"
45 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
46 #define TEST_ALIASNAME "samrtorturetestalias"
47 #define TEST_GROUPNAME "samrtorturetestgroup"
48 #define TEST_MACHINENAME "samrtestmach$"
49 #define TEST_DOMAINNAME "samrtestdom$"
51 enum torture_samr_choice {
52 TORTURE_SAMR_PASSWORDS,
53 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
54 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT,
55 TORTURE_SAMR_PASSWORDS_LOCKOUT,
56 TORTURE_SAMR_USER_ATTRIBUTES,
57 TORTURE_SAMR_USER_PRIVILEGES,
58 TORTURE_SAMR_OTHER,
59 TORTURE_SAMR_MANY_ACCOUNTS,
60 TORTURE_SAMR_MANY_GROUPS,
61 TORTURE_SAMR_MANY_ALIASES
64 struct torture_samr_context {
65 struct policy_handle handle;
66 struct cli_credentials *machine_credentials;
67 enum torture_samr_choice choice;
68 uint32_t num_objects_large_dc;
71 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
72 struct torture_context *tctx,
73 struct policy_handle *handle);
75 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
76 struct torture_context *tctx,
77 struct policy_handle *handle);
79 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
80 struct torture_context *tctx,
81 struct policy_handle *handle);
83 static bool test_ChangePassword(struct dcerpc_pipe *p,
84 struct torture_context *tctx,
85 const char *acct_name,
86 struct policy_handle *domain_handle, char **password);
88 static void init_lsa_String(struct lsa_String *string, const char *s)
90 string->string = s;
93 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
95 string->string = s;
98 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
100 string->length = length;
101 string->size = length;
102 string->array = (uint16_t *)discard_const(s);
105 bool test_samr_handle_Close(struct dcerpc_binding_handle *b,
106 struct torture_context *tctx,
107 struct policy_handle *handle)
109 struct samr_Close r;
111 r.in.handle = handle;
112 r.out.handle = handle;
114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Close_r(b, tctx, &r),
115 "Close failed");
116 torture_assert_ntstatus_ok(tctx, r.out.result, "Close failed");
118 return true;
121 static bool test_Shutdown(struct dcerpc_binding_handle *b,
122 struct torture_context *tctx,
123 struct policy_handle *handle)
125 struct samr_Shutdown r;
127 if (!torture_setting_bool(tctx, "dangerous", false)) {
128 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
129 return true;
132 r.in.connect_handle = handle;
134 torture_comment(tctx, "Testing samr_Shutdown\n");
136 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Shutdown_r(b, tctx, &r),
137 "Shutdown failed");
138 torture_assert_ntstatus_ok(tctx, r.out.result, "Shutdown failed");
140 return true;
143 static bool test_SetDsrmPassword(struct dcerpc_binding_handle *b,
144 struct torture_context *tctx,
145 struct policy_handle *handle)
147 struct samr_SetDsrmPassword r;
148 struct lsa_String string;
149 struct samr_Password hash;
151 if (!torture_setting_bool(tctx, "dangerous", false)) {
152 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
155 E_md4hash("TeSTDSRM123", hash.hash);
157 init_lsa_String(&string, "Administrator");
159 r.in.name = &string;
160 r.in.unknown = 0;
161 r.in.hash = &hash;
163 torture_comment(tctx, "Testing samr_SetDsrmPassword\n");
165 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDsrmPassword_r(b, tctx, &r),
166 "SetDsrmPassword failed");
167 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED, "SetDsrmPassword failed");
169 return true;
173 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
174 struct torture_context *tctx,
175 struct policy_handle *handle)
177 struct samr_QuerySecurity r;
178 struct samr_SetSecurity s;
179 struct sec_desc_buf *sdbuf = NULL;
181 r.in.handle = handle;
182 r.in.sec_info = 7;
183 r.out.sdbuf = &sdbuf;
185 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
186 "QuerySecurity failed");
187 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
189 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
191 s.in.handle = handle;
192 s.in.sec_info = 7;
193 s.in.sdbuf = sdbuf;
195 if (torture_setting_bool(tctx, "samba4", false)) {
196 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
199 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetSecurity_r(b, tctx, &s),
200 "SetSecurity failed");
201 torture_assert_ntstatus_ok(tctx, r.out.result, "SetSecurity failed");
203 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
204 "QuerySecurity failed");
205 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
207 return true;
211 static bool test_SetUserInfo(struct dcerpc_binding_handle *b, struct torture_context *tctx,
212 struct policy_handle *handle, uint32_t base_acct_flags,
213 const char *base_account_name)
215 struct samr_SetUserInfo s;
216 struct samr_SetUserInfo2 s2;
217 struct samr_QueryUserInfo q;
218 struct samr_QueryUserInfo q0;
219 union samr_UserInfo u;
220 union samr_UserInfo *info;
221 bool ret = true;
222 const char *test_account_name;
224 uint32_t user_extra_flags = 0;
226 if (!torture_setting_bool(tctx, "samba3", false)) {
227 if (base_acct_flags == ACB_NORMAL) {
228 /* When created, accounts are expired by default */
229 user_extra_flags = ACB_PW_EXPIRED;
233 s.in.user_handle = handle;
234 s.in.info = &u;
236 s2.in.user_handle = handle;
237 s2.in.info = &u;
239 q.in.user_handle = handle;
240 q.out.info = &info;
241 q0 = q;
243 #define TESTCALL(call, r) \
244 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
245 #call " failed"); \
246 if (!NT_STATUS_IS_OK(r.out.result)) { \
247 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
248 r.in.level, nt_errstr(r.out.result), __location__); \
249 ret = false; \
250 break; \
253 #define STRING_EQUAL(s1, s2, field) \
254 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
255 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
256 #field, s2, __location__); \
257 ret = false; \
258 break; \
261 #define MEM_EQUAL(s1, s2, length, field) \
262 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
263 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
264 #field, (const char *)s2, __location__); \
265 ret = false; \
266 break; \
269 #define INT_EQUAL(i1, i2, field) \
270 if (i1 != i2) { \
271 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
272 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
273 ret = false; \
274 break; \
277 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
278 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
279 q.in.level = lvl1; \
280 TESTCALL(QueryUserInfo, q) \
281 s.in.level = lvl1; \
282 s2.in.level = lvl1; \
283 u = *info; \
284 if (lvl1 == 21) { \
285 ZERO_STRUCT(u.info21); \
286 u.info21.fields_present = fpval; \
288 init_lsa_String(&u.info ## lvl1.field1, value); \
289 TESTCALL(SetUserInfo, s) \
290 TESTCALL(SetUserInfo2, s2) \
291 init_lsa_String(&u.info ## lvl1.field1, ""); \
292 TESTCALL(QueryUserInfo, q); \
293 u = *info; \
294 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
295 q.in.level = lvl2; \
296 TESTCALL(QueryUserInfo, q) \
297 u = *info; \
298 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
299 } while (0)
301 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
302 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
303 q.in.level = lvl1; \
304 TESTCALL(QueryUserInfo, q) \
305 s.in.level = lvl1; \
306 s2.in.level = lvl1; \
307 u = *info; \
308 if (lvl1 == 21) { \
309 ZERO_STRUCT(u.info21); \
310 u.info21.fields_present = fpval; \
312 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
313 TESTCALL(SetUserInfo, s) \
314 TESTCALL(SetUserInfo2, s2) \
315 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
316 TESTCALL(QueryUserInfo, q); \
317 u = *info; \
318 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
319 q.in.level = lvl2; \
320 TESTCALL(QueryUserInfo, q) \
321 u = *info; \
322 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
323 } while (0)
325 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
326 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
327 q.in.level = lvl1; \
328 TESTCALL(QueryUserInfo, q) \
329 s.in.level = lvl1; \
330 s2.in.level = lvl1; \
331 u = *info; \
332 if (lvl1 == 21) { \
333 uint8_t *bits = u.info21.logon_hours.bits; \
334 ZERO_STRUCT(u.info21); \
335 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
336 u.info21.logon_hours.units_per_week = 168; \
337 u.info21.logon_hours.bits = bits; \
339 u.info21.fields_present = fpval; \
341 u.info ## lvl1.field1 = value; \
342 TESTCALL(SetUserInfo, s) \
343 TESTCALL(SetUserInfo2, s2) \
344 u.info ## lvl1.field1 = 0; \
345 TESTCALL(QueryUserInfo, q); \
346 u = *info; \
347 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
348 q.in.level = lvl2; \
349 TESTCALL(QueryUserInfo, q) \
350 u = *info; \
351 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
352 } while (0)
354 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
355 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
356 } while (0)
358 q0.in.level = 12;
359 do { TESTCALL(QueryUserInfo, q0) } while (0);
361 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
362 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
363 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
364 SAMR_FIELD_COMMENT);
366 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
367 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
368 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
369 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
370 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
371 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
372 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
373 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
374 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
375 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
376 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
377 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
378 test_account_name = base_account_name;
379 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
380 SAMR_FIELD_ACCOUNT_NAME);
382 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
387 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
388 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
389 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
390 SAMR_FIELD_FULL_NAME);
392 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
393 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
394 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
395 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
396 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
397 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
398 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
399 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
400 SAMR_FIELD_FULL_NAME);
402 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
404 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
405 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
406 SAMR_FIELD_LOGON_SCRIPT);
408 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
410 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
411 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
412 SAMR_FIELD_PROFILE_PATH);
414 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
416 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
417 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
418 SAMR_FIELD_HOME_DIRECTORY);
419 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
420 SAMR_FIELD_HOME_DIRECTORY);
422 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
424 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
425 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
426 SAMR_FIELD_HOME_DRIVE);
427 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
428 SAMR_FIELD_HOME_DRIVE);
430 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
431 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
432 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
433 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
434 SAMR_FIELD_DESCRIPTION);
436 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
437 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
438 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
439 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
440 SAMR_FIELD_WORKSTATIONS);
441 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
442 SAMR_FIELD_WORKSTATIONS);
443 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
444 SAMR_FIELD_WORKSTATIONS);
445 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
446 SAMR_FIELD_WORKSTATIONS);
448 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
449 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
450 SAMR_FIELD_PARAMETERS);
451 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
452 SAMR_FIELD_PARAMETERS);
453 /* also empty user parameters are allowed */
454 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
455 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
456 SAMR_FIELD_PARAMETERS);
457 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
458 SAMR_FIELD_PARAMETERS);
460 /* Samba 3 cannot store country_code and code_page atm. - gd */
461 if (!torture_setting_bool(tctx, "samba3", false)) {
462 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
463 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
464 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
465 SAMR_FIELD_COUNTRY_CODE);
466 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
467 SAMR_FIELD_COUNTRY_CODE);
469 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
470 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
471 SAMR_FIELD_CODE_PAGE);
472 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
473 SAMR_FIELD_CODE_PAGE);
476 if (!torture_setting_bool(tctx, "samba3", false)) {
477 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
478 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
479 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
480 SAMR_FIELD_ACCT_EXPIRY);
481 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
482 SAMR_FIELD_ACCT_EXPIRY);
483 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
484 SAMR_FIELD_ACCT_EXPIRY);
485 } else {
486 /* Samba 3 can only store seconds / time_t in passdb - gd */
487 NTTIME nt;
488 unix_to_nt_time(&nt, time(NULL) + __LINE__);
489 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
490 unix_to_nt_time(&nt, time(NULL) + __LINE__);
491 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
492 unix_to_nt_time(&nt, time(NULL) + __LINE__);
493 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
494 unix_to_nt_time(&nt, time(NULL) + __LINE__);
495 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
496 unix_to_nt_time(&nt, time(NULL) + __LINE__);
497 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
500 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
501 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
502 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
503 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
504 SAMR_FIELD_LOGON_HOURS);
506 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
507 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
508 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
510 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
511 (base_acct_flags | ACB_DISABLED),
512 (base_acct_flags | ACB_DISABLED | user_extra_flags),
515 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
516 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
517 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
518 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
520 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
521 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
522 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
526 /* The 'autolock' flag doesn't stick - check this */
527 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
528 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
529 (base_acct_flags | ACB_DISABLED | user_extra_flags),
531 #if 0
532 /* Removing the 'disabled' flag doesn't stick - check this */
533 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
534 (base_acct_flags),
535 (base_acct_flags | ACB_DISABLED | user_extra_flags),
537 #endif
539 /* Samba3 cannot store these atm */
540 if (!torture_setting_bool(tctx, "samba3", false)) {
541 /* The 'store plaintext' flag does stick */
542 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
543 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
544 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
546 /* The 'use DES' flag does stick */
547 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
548 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
549 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
551 /* The 'don't require kerberos pre-authentication flag does stick */
552 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
553 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
554 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
556 /* The 'no kerberos PAC required' flag sticks */
557 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
558 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
559 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
562 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
563 (base_acct_flags | ACB_DISABLED),
564 (base_acct_flags | ACB_DISABLED | user_extra_flags),
565 SAMR_FIELD_ACCT_FLAGS);
567 #if 0
568 /* these fail with win2003 - it appears you can't set the primary gid?
569 the set succeeds, but the gid isn't changed. Very weird! */
570 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
571 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
572 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
573 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
574 #endif
576 return ret;
580 generate a random password for password change tests
582 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
584 size_t len = MAX(8, min_len);
585 char *s = generate_random_password(mem_ctx, len, len+6);
586 return s;
589 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
591 char *s = samr_rand_pass_silent(mem_ctx, min_len);
592 printf("Generated password '%s'\n", s);
593 return s;
598 generate a random password for password change tests
600 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
602 int i;
603 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
604 generate_random_buffer(password.data, password.length);
606 for (i=0; i < len; i++) {
607 if (((uint16_t *)password.data)[i] == 0) {
608 ((uint16_t *)password.data)[i] = 1;
612 return password;
616 generate a random password for password change tests (fixed length)
618 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
620 char *s = generate_random_password(mem_ctx, len, len);
621 printf("Generated password '%s'\n", s);
622 return s;
625 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
626 struct policy_handle *handle, char **password)
628 NTSTATUS status;
629 struct samr_SetUserInfo s;
630 union samr_UserInfo u;
631 bool ret = true;
632 DATA_BLOB session_key;
633 char *newpass;
634 struct dcerpc_binding_handle *b = p->binding_handle;
635 struct samr_GetUserPwInfo pwp;
636 struct samr_PwInfo info;
637 int policy_min_pw_len = 0;
638 pwp.in.user_handle = handle;
639 pwp.out.info = &info;
641 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
642 "GetUserPwInfo failed");
643 if (NT_STATUS_IS_OK(pwp.out.result)) {
644 policy_min_pw_len = pwp.out.info->min_password_length;
646 newpass = samr_rand_pass(tctx, policy_min_pw_len);
648 s.in.user_handle = handle;
649 s.in.info = &u;
650 s.in.level = 24;
652 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
653 u.info24.password_expired = 0;
655 status = dcerpc_fetch_session_key(p, &session_key);
656 if (!NT_STATUS_IS_OK(status)) {
657 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
658 s.in.level, nt_errstr(status));
659 return false;
662 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
664 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
666 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
667 "SetUserInfo failed");
668 if (!NT_STATUS_IS_OK(s.out.result)) {
669 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
670 s.in.level, nt_errstr(s.out.result));
671 ret = false;
672 } else {
673 *password = newpass;
676 return ret;
680 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
681 struct policy_handle *handle, uint32_t fields_present,
682 char **password)
684 NTSTATUS status;
685 struct samr_SetUserInfo s;
686 union samr_UserInfo u;
687 bool ret = true;
688 DATA_BLOB session_key;
689 struct dcerpc_binding_handle *b = p->binding_handle;
690 char *newpass;
691 struct samr_GetUserPwInfo pwp;
692 struct samr_PwInfo info;
693 int policy_min_pw_len = 0;
694 pwp.in.user_handle = handle;
695 pwp.out.info = &info;
697 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
698 "GetUserPwInfo failed");
699 if (NT_STATUS_IS_OK(pwp.out.result)) {
700 policy_min_pw_len = pwp.out.info->min_password_length;
702 newpass = samr_rand_pass(tctx, policy_min_pw_len);
704 s.in.user_handle = handle;
705 s.in.info = &u;
706 s.in.level = 23;
708 ZERO_STRUCT(u);
710 u.info23.info.fields_present = fields_present;
712 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
714 status = dcerpc_fetch_session_key(p, &session_key);
715 if (!NT_STATUS_IS_OK(status)) {
716 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
717 s.in.level, nt_errstr(status));
718 return false;
721 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
723 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
725 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
726 "SetUserInfo failed");
727 if (!NT_STATUS_IS_OK(s.out.result)) {
728 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
729 s.in.level, nt_errstr(s.out.result));
730 ret = false;
731 } else {
732 *password = newpass;
735 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
737 status = dcerpc_fetch_session_key(p, &session_key);
738 if (!NT_STATUS_IS_OK(status)) {
739 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
740 s.in.level, nt_errstr(status));
741 return false;
744 /* This should break the key nicely */
745 session_key.length--;
746 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
748 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
750 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
751 "SetUserInfo failed");
752 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
753 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
754 s.in.level, nt_errstr(s.out.result));
755 ret = false;
758 return ret;
762 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
763 struct policy_handle *handle, bool makeshort,
764 char **password)
766 NTSTATUS status;
767 struct samr_SetUserInfo s;
768 union samr_UserInfo u;
769 bool ret = true;
770 DATA_BLOB session_key;
771 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
772 uint8_t confounder[16];
773 char *newpass;
774 struct dcerpc_binding_handle *b = p->binding_handle;
775 struct MD5Context ctx;
776 struct samr_GetUserPwInfo pwp;
777 struct samr_PwInfo info;
778 int policy_min_pw_len = 0;
779 pwp.in.user_handle = handle;
780 pwp.out.info = &info;
782 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
783 "GetUserPwInfo failed");
784 if (NT_STATUS_IS_OK(pwp.out.result)) {
785 policy_min_pw_len = pwp.out.info->min_password_length;
787 if (makeshort && policy_min_pw_len) {
788 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
789 } else {
790 newpass = samr_rand_pass(tctx, policy_min_pw_len);
793 s.in.user_handle = handle;
794 s.in.info = &u;
795 s.in.level = 26;
797 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
798 u.info26.password_expired = 0;
800 status = dcerpc_fetch_session_key(p, &session_key);
801 if (!NT_STATUS_IS_OK(status)) {
802 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
803 s.in.level, nt_errstr(status));
804 return false;
807 generate_random_buffer((uint8_t *)confounder, 16);
809 MD5Init(&ctx);
810 MD5Update(&ctx, confounder, 16);
811 MD5Update(&ctx, session_key.data, session_key.length);
812 MD5Final(confounded_session_key.data, &ctx);
814 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
815 memcpy(&u.info26.password.data[516], confounder, 16);
817 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
819 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
820 "SetUserInfo failed");
821 if (!NT_STATUS_IS_OK(s.out.result)) {
822 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
823 s.in.level, nt_errstr(s.out.result));
824 ret = false;
825 } else {
826 *password = newpass;
829 /* This should break the key nicely */
830 confounded_session_key.data[0]++;
832 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
833 memcpy(&u.info26.password.data[516], confounder, 16);
835 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
837 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
838 "SetUserInfo failed");
839 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
840 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
841 s.in.level, nt_errstr(s.out.result));
842 ret = false;
843 } else {
844 *password = newpass;
847 return ret;
850 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
851 struct policy_handle *handle, uint32_t fields_present,
852 char **password)
854 NTSTATUS status;
855 struct samr_SetUserInfo s;
856 union samr_UserInfo u;
857 bool ret = true;
858 DATA_BLOB session_key;
859 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
860 struct MD5Context ctx;
861 uint8_t confounder[16];
862 char *newpass;
863 struct dcerpc_binding_handle *b = p->binding_handle;
864 struct samr_GetUserPwInfo pwp;
865 struct samr_PwInfo info;
866 int policy_min_pw_len = 0;
867 pwp.in.user_handle = handle;
868 pwp.out.info = &info;
870 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
871 "GetUserPwInfo failed");
872 if (NT_STATUS_IS_OK(pwp.out.result)) {
873 policy_min_pw_len = pwp.out.info->min_password_length;
875 newpass = samr_rand_pass(tctx, policy_min_pw_len);
877 s.in.user_handle = handle;
878 s.in.info = &u;
879 s.in.level = 25;
881 ZERO_STRUCT(u);
883 u.info25.info.fields_present = fields_present;
885 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
887 status = dcerpc_fetch_session_key(p, &session_key);
888 if (!NT_STATUS_IS_OK(status)) {
889 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
890 s.in.level, nt_errstr(status));
891 return false;
894 generate_random_buffer((uint8_t *)confounder, 16);
896 MD5Init(&ctx);
897 MD5Update(&ctx, confounder, 16);
898 MD5Update(&ctx, session_key.data, session_key.length);
899 MD5Final(confounded_session_key.data, &ctx);
901 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
902 memcpy(&u.info25.password.data[516], confounder, 16);
904 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
906 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
907 "SetUserInfo failed");
908 if (!NT_STATUS_IS_OK(s.out.result)) {
909 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
910 s.in.level, nt_errstr(s.out.result));
911 ret = false;
912 } else {
913 *password = newpass;
916 /* This should break the key nicely */
917 confounded_session_key.data[0]++;
919 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
920 memcpy(&u.info25.password.data[516], confounder, 16);
922 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
924 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
925 "SetUserInfo failed");
926 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
927 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
928 s.in.level, nt_errstr(s.out.result));
929 ret = false;
932 return ret;
935 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
936 struct policy_handle *handle, char **password)
938 NTSTATUS status;
939 struct samr_SetUserInfo s;
940 union samr_UserInfo u;
941 bool ret = true;
942 DATA_BLOB session_key;
943 char *newpass;
944 struct dcerpc_binding_handle *b = p->binding_handle;
945 struct samr_GetUserPwInfo pwp;
946 struct samr_PwInfo info;
947 int policy_min_pw_len = 0;
948 uint8_t lm_hash[16], nt_hash[16];
950 pwp.in.user_handle = handle;
951 pwp.out.info = &info;
953 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
954 "GetUserPwInfo failed");
955 if (NT_STATUS_IS_OK(pwp.out.result)) {
956 policy_min_pw_len = pwp.out.info->min_password_length;
958 newpass = samr_rand_pass(tctx, policy_min_pw_len);
960 s.in.user_handle = handle;
961 s.in.info = &u;
962 s.in.level = 18;
964 ZERO_STRUCT(u);
966 u.info18.nt_pwd_active = true;
967 u.info18.lm_pwd_active = true;
969 E_md4hash(newpass, nt_hash);
970 E_deshash(newpass, lm_hash);
972 status = dcerpc_fetch_session_key(p, &session_key);
973 if (!NT_STATUS_IS_OK(status)) {
974 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
975 s.in.level, nt_errstr(status));
976 return false;
980 DATA_BLOB in,out;
981 in = data_blob_const(nt_hash, 16);
982 out = data_blob_talloc_zero(tctx, 16);
983 sess_crypt_blob(&out, &in, &session_key, true);
984 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
987 DATA_BLOB in,out;
988 in = data_blob_const(lm_hash, 16);
989 out = data_blob_talloc_zero(tctx, 16);
990 sess_crypt_blob(&out, &in, &session_key, true);
991 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
994 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
996 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
997 "SetUserInfo failed");
998 if (!NT_STATUS_IS_OK(s.out.result)) {
999 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1000 s.in.level, nt_errstr(s.out.result));
1001 ret = false;
1002 } else {
1003 *password = newpass;
1006 return ret;
1009 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
1010 struct policy_handle *handle, uint32_t fields_present,
1011 char **password)
1013 NTSTATUS status;
1014 struct samr_SetUserInfo s;
1015 union samr_UserInfo u;
1016 bool ret = true;
1017 DATA_BLOB session_key;
1018 char *newpass;
1019 struct dcerpc_binding_handle *b = p->binding_handle;
1020 struct samr_GetUserPwInfo pwp;
1021 struct samr_PwInfo info;
1022 int policy_min_pw_len = 0;
1023 uint8_t lm_hash[16], nt_hash[16];
1025 pwp.in.user_handle = handle;
1026 pwp.out.info = &info;
1028 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1029 "GetUserPwInfo failed");
1030 if (NT_STATUS_IS_OK(pwp.out.result)) {
1031 policy_min_pw_len = pwp.out.info->min_password_length;
1033 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1035 s.in.user_handle = handle;
1036 s.in.info = &u;
1037 s.in.level = 21;
1039 E_md4hash(newpass, nt_hash);
1040 E_deshash(newpass, lm_hash);
1042 ZERO_STRUCT(u);
1044 u.info21.fields_present = fields_present;
1046 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1047 u.info21.lm_owf_password.length = 16;
1048 u.info21.lm_owf_password.size = 16;
1049 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1050 u.info21.lm_password_set = true;
1053 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1054 u.info21.nt_owf_password.length = 16;
1055 u.info21.nt_owf_password.size = 16;
1056 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1057 u.info21.nt_password_set = true;
1060 status = dcerpc_fetch_session_key(p, &session_key);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1063 s.in.level, nt_errstr(status));
1064 return false;
1067 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1068 DATA_BLOB in,out;
1069 in = data_blob_const(u.info21.lm_owf_password.array,
1070 u.info21.lm_owf_password.length);
1071 out = data_blob_talloc_zero(tctx, 16);
1072 sess_crypt_blob(&out, &in, &session_key, true);
1073 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1076 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1077 DATA_BLOB in,out;
1078 in = data_blob_const(u.info21.nt_owf_password.array,
1079 u.info21.nt_owf_password.length);
1080 out = data_blob_talloc_zero(tctx, 16);
1081 sess_crypt_blob(&out, &in, &session_key, true);
1082 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1085 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1087 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1088 "SetUserInfo failed");
1089 if (!NT_STATUS_IS_OK(s.out.result)) {
1090 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1091 s.in.level, nt_errstr(s.out.result));
1092 ret = false;
1093 } else {
1094 *password = newpass;
1097 /* try invalid length */
1098 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1100 u.info21.nt_owf_password.length++;
1102 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1103 "SetUserInfo failed");
1104 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1105 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1106 s.in.level, nt_errstr(s.out.result));
1107 ret = false;
1111 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1113 u.info21.lm_owf_password.length++;
1115 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1116 "SetUserInfo failed");
1117 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1118 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1119 s.in.level, nt_errstr(s.out.result));
1120 ret = false;
1124 return ret;
1127 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1128 struct torture_context *tctx,
1129 struct policy_handle *handle,
1130 uint16_t level,
1131 uint32_t fields_present,
1132 char **password, uint8_t password_expired,
1133 bool use_setinfo2,
1134 bool *matched_expected_error)
1136 NTSTATUS status;
1137 NTSTATUS expected_error = NT_STATUS_OK;
1138 struct samr_SetUserInfo s;
1139 struct samr_SetUserInfo2 s2;
1140 union samr_UserInfo u;
1141 bool ret = true;
1142 DATA_BLOB session_key;
1143 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1144 struct MD5Context ctx;
1145 uint8_t confounder[16];
1146 char *newpass;
1147 struct dcerpc_binding_handle *b = p->binding_handle;
1148 struct samr_GetUserPwInfo pwp;
1149 struct samr_PwInfo info;
1150 int policy_min_pw_len = 0;
1151 const char *comment = NULL;
1152 uint8_t lm_hash[16], nt_hash[16];
1154 pwp.in.user_handle = handle;
1155 pwp.out.info = &info;
1157 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1158 "GetUserPwInfo failed");
1159 if (NT_STATUS_IS_OK(pwp.out.result)) {
1160 policy_min_pw_len = pwp.out.info->min_password_length;
1162 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1164 if (use_setinfo2) {
1165 s2.in.user_handle = handle;
1166 s2.in.info = &u;
1167 s2.in.level = level;
1168 } else {
1169 s.in.user_handle = handle;
1170 s.in.info = &u;
1171 s.in.level = level;
1174 if (fields_present & SAMR_FIELD_COMMENT) {
1175 comment = talloc_asprintf(tctx, "comment: %ld\n", (long int) time(NULL));
1178 ZERO_STRUCT(u);
1180 switch (level) {
1181 case 18:
1182 E_md4hash(newpass, nt_hash);
1183 E_deshash(newpass, lm_hash);
1185 u.info18.nt_pwd_active = true;
1186 u.info18.lm_pwd_active = true;
1187 u.info18.password_expired = password_expired;
1189 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1190 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1192 break;
1193 case 21:
1194 E_md4hash(newpass, nt_hash);
1195 E_deshash(newpass, lm_hash);
1197 u.info21.fields_present = fields_present;
1198 u.info21.password_expired = password_expired;
1199 u.info21.comment.string = comment;
1201 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1202 u.info21.lm_owf_password.length = 16;
1203 u.info21.lm_owf_password.size = 16;
1204 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1205 u.info21.lm_password_set = true;
1208 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1209 u.info21.nt_owf_password.length = 16;
1210 u.info21.nt_owf_password.size = 16;
1211 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1212 u.info21.nt_password_set = true;
1215 break;
1216 case 23:
1217 u.info23.info.fields_present = fields_present;
1218 u.info23.info.password_expired = password_expired;
1219 u.info23.info.comment.string = comment;
1221 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1223 break;
1224 case 24:
1225 u.info24.password_expired = password_expired;
1227 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1229 break;
1230 case 25:
1231 u.info25.info.fields_present = fields_present;
1232 u.info25.info.password_expired = password_expired;
1233 u.info25.info.comment.string = comment;
1235 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1237 break;
1238 case 26:
1239 u.info26.password_expired = password_expired;
1241 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1243 break;
1246 status = dcerpc_fetch_session_key(p, &session_key);
1247 if (!NT_STATUS_IS_OK(status)) {
1248 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1249 s.in.level, nt_errstr(status));
1250 return false;
1253 generate_random_buffer((uint8_t *)confounder, 16);
1255 MD5Init(&ctx);
1256 MD5Update(&ctx, confounder, 16);
1257 MD5Update(&ctx, session_key.data, session_key.length);
1258 MD5Final(confounded_session_key.data, &ctx);
1260 switch (level) {
1261 case 18:
1263 DATA_BLOB in,out;
1264 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1265 out = data_blob_talloc_zero(tctx, 16);
1266 sess_crypt_blob(&out, &in, &session_key, true);
1267 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1270 DATA_BLOB in,out;
1271 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1272 out = data_blob_talloc_zero(tctx, 16);
1273 sess_crypt_blob(&out, &in, &session_key, true);
1274 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1277 break;
1278 case 21:
1279 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1280 DATA_BLOB in,out;
1281 in = data_blob_const(u.info21.lm_owf_password.array,
1282 u.info21.lm_owf_password.length);
1283 out = data_blob_talloc_zero(tctx, 16);
1284 sess_crypt_blob(&out, &in, &session_key, true);
1285 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1287 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1288 DATA_BLOB in,out;
1289 in = data_blob_const(u.info21.nt_owf_password.array,
1290 u.info21.nt_owf_password.length);
1291 out = data_blob_talloc_zero(tctx, 16);
1292 sess_crypt_blob(&out, &in, &session_key, true);
1293 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1295 break;
1296 case 23:
1297 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1298 break;
1299 case 24:
1300 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1301 break;
1302 case 25:
1303 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1304 memcpy(&u.info25.password.data[516], confounder, 16);
1305 break;
1306 case 26:
1307 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1308 memcpy(&u.info26.password.data[516], confounder, 16);
1309 break;
1312 if (use_setinfo2) {
1313 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
1314 "SetUserInfo2 failed");
1315 status = s2.out.result;
1316 } else {
1317 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1318 "SetUserInfo failed");
1319 status = s.out.result;
1322 if (!NT_STATUS_IS_OK(status)) {
1323 if (fields_present == 0) {
1324 expected_error = NT_STATUS_INVALID_PARAMETER;
1326 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1327 expected_error = NT_STATUS_ACCESS_DENIED;
1331 if (!NT_STATUS_IS_OK(expected_error)) {
1332 if (use_setinfo2) {
1333 torture_assert_ntstatus_equal(tctx,
1334 s2.out.result,
1335 expected_error, "SetUserInfo2 failed");
1336 } else {
1337 torture_assert_ntstatus_equal(tctx,
1338 s.out.result,
1339 expected_error, "SetUserInfo failed");
1341 *matched_expected_error = true;
1342 return true;
1345 if (!NT_STATUS_IS_OK(status)) {
1346 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1347 use_setinfo2 ? "2":"", level, nt_errstr(status));
1348 ret = false;
1349 } else {
1350 *password = newpass;
1353 return ret;
1356 static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
1357 struct torture_context *tctx,
1358 struct policy_handle *handle)
1360 struct samr_SetAliasInfo r;
1361 struct samr_QueryAliasInfo q;
1362 union samr_AliasInfo *info;
1363 uint16_t levels[] = {2, 3};
1364 int i;
1365 bool ret = true;
1367 /* Ignoring switch level 1, as that includes the number of members for the alias
1368 * and setting this to a wrong value might have negative consequences
1371 for (i=0;i<ARRAY_SIZE(levels);i++) {
1372 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1374 r.in.alias_handle = handle;
1375 r.in.level = levels[i];
1376 r.in.info = talloc(tctx, union samr_AliasInfo);
1377 switch (r.in.level) {
1378 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1379 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1380 "Test Description, should test I18N as well"); break;
1381 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1384 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
1385 "SetAliasInfo failed");
1386 if (!NT_STATUS_IS_OK(r.out.result)) {
1387 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1388 levels[i], nt_errstr(r.out.result));
1389 ret = false;
1392 q.in.alias_handle = handle;
1393 q.in.level = levels[i];
1394 q.out.info = &info;
1396 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
1397 "QueryAliasInfo failed");
1398 if (!NT_STATUS_IS_OK(q.out.result)) {
1399 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1400 levels[i], nt_errstr(q.out.result));
1401 ret = false;
1405 return ret;
1408 static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
1409 struct torture_context *tctx,
1410 struct policy_handle *user_handle)
1412 struct samr_GetGroupsForUser r;
1413 struct samr_RidWithAttributeArray *rids = NULL;
1415 torture_comment(tctx, "Testing GetGroupsForUser\n");
1417 r.in.user_handle = user_handle;
1418 r.out.rids = &rids;
1420 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
1421 "GetGroupsForUser failed");
1422 torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
1424 return true;
1428 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1429 struct lsa_String *domain_name)
1431 struct samr_GetDomPwInfo r;
1432 struct samr_PwInfo info;
1433 struct dcerpc_binding_handle *b = p->binding_handle;
1435 r.in.domain_name = domain_name;
1436 r.out.info = &info;
1438 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1440 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1441 "GetDomPwInfo failed");
1442 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1444 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1445 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1447 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1448 "GetDomPwInfo failed");
1449 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1451 r.in.domain_name->string = "\\\\__NONAME__";
1452 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1454 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1455 "GetDomPwInfo failed");
1456 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1458 r.in.domain_name->string = "\\\\Builtin";
1459 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1461 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1462 "GetDomPwInfo failed");
1463 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1465 return true;
1468 static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
1469 struct torture_context *tctx,
1470 struct policy_handle *handle)
1472 struct samr_GetUserPwInfo r;
1473 struct samr_PwInfo info;
1475 torture_comment(tctx, "Testing GetUserPwInfo\n");
1477 r.in.user_handle = handle;
1478 r.out.info = &info;
1480 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
1481 "GetUserPwInfo failed");
1482 torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
1484 return true;
1487 static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
1488 struct torture_context *tctx,
1489 struct policy_handle *domain_handle, const char *name,
1490 uint32_t *rid)
1492 NTSTATUS status;
1493 struct samr_LookupNames n;
1494 struct lsa_String sname[2];
1495 struct samr_Ids rids, types;
1497 init_lsa_String(&sname[0], name);
1499 n.in.domain_handle = domain_handle;
1500 n.in.num_names = 1;
1501 n.in.names = sname;
1502 n.out.rids = &rids;
1503 n.out.types = &types;
1504 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1505 if (!NT_STATUS_IS_OK(status)) {
1506 return status;
1508 if (NT_STATUS_IS_OK(n.out.result)) {
1509 *rid = n.out.rids->ids[0];
1510 } else {
1511 return n.out.result;
1514 init_lsa_String(&sname[1], "xxNONAMExx");
1515 n.in.num_names = 2;
1516 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1517 if (!NT_STATUS_IS_OK(status)) {
1518 return status;
1520 if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
1521 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
1522 if (NT_STATUS_IS_OK(n.out.result)) {
1523 return NT_STATUS_UNSUCCESSFUL;
1525 return n.out.result;
1528 n.in.num_names = 0;
1529 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1530 if (!NT_STATUS_IS_OK(status)) {
1531 return status;
1533 if (!NT_STATUS_IS_OK(n.out.result)) {
1534 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1535 return n.out.result;
1538 init_lsa_String(&sname[0], "xxNONAMExx");
1539 n.in.num_names = 1;
1540 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 return status;
1544 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1545 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
1546 if (NT_STATUS_IS_OK(n.out.result)) {
1547 return NT_STATUS_UNSUCCESSFUL;
1549 return n.out.result;
1552 init_lsa_String(&sname[0], "xxNONAMExx");
1553 init_lsa_String(&sname[1], "xxNONAME2xx");
1554 n.in.num_names = 2;
1555 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 return status;
1559 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1560 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
1561 if (NT_STATUS_IS_OK(n.out.result)) {
1562 return NT_STATUS_UNSUCCESSFUL;
1564 return n.out.result;
1567 return NT_STATUS_OK;
1570 static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
1571 struct torture_context *tctx,
1572 struct policy_handle *domain_handle,
1573 const char *name, struct policy_handle *user_handle)
1575 NTSTATUS status;
1576 struct samr_OpenUser r;
1577 uint32_t rid;
1579 status = test_LookupName(b, tctx, domain_handle, name, &rid);
1580 if (!NT_STATUS_IS_OK(status)) {
1581 return status;
1584 r.in.domain_handle = domain_handle;
1585 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1586 r.in.rid = rid;
1587 r.out.user_handle = user_handle;
1588 status = dcerpc_samr_OpenUser_r(b, tctx, &r);
1589 if (!NT_STATUS_IS_OK(status)) {
1590 return status;
1592 if (!NT_STATUS_IS_OK(r.out.result)) {
1593 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
1596 return r.out.result;
1599 #if 0
1600 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1601 struct torture_context *tctx,
1602 struct policy_handle *handle)
1604 NTSTATUS status;
1605 struct samr_ChangePasswordUser r;
1606 bool ret = true;
1607 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1608 struct policy_handle user_handle;
1609 char *oldpass = "test";
1610 char *newpass = "test2";
1611 uint8_t old_nt_hash[16], new_nt_hash[16];
1612 uint8_t old_lm_hash[16], new_lm_hash[16];
1614 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1615 if (!NT_STATUS_IS_OK(status)) {
1616 return false;
1619 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1621 torture_comment(tctx, "old password: %s\n", oldpass);
1622 torture_comment(tctx, "new password: %s\n", newpass);
1624 E_md4hash(oldpass, old_nt_hash);
1625 E_md4hash(newpass, new_nt_hash);
1626 E_deshash(oldpass, old_lm_hash);
1627 E_deshash(newpass, new_lm_hash);
1629 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1630 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1631 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1632 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1633 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1634 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1636 r.in.handle = &user_handle;
1637 r.in.lm_present = 1;
1638 r.in.old_lm_crypted = &hash1;
1639 r.in.new_lm_crypted = &hash2;
1640 r.in.nt_present = 1;
1641 r.in.old_nt_crypted = &hash3;
1642 r.in.new_nt_crypted = &hash4;
1643 r.in.cross1_present = 1;
1644 r.in.nt_cross = &hash5;
1645 r.in.cross2_present = 1;
1646 r.in.lm_cross = &hash6;
1648 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1649 "ChangePasswordUser failed");
1650 if (!NT_STATUS_IS_OK(r.out.result)) {
1651 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1652 ret = false;
1655 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1656 ret = false;
1659 return ret;
1661 #endif
1663 static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
1664 struct torture_context *tctx,
1665 const char *acct_name,
1666 struct policy_handle *handle, char **password)
1668 NTSTATUS status;
1669 struct samr_ChangePasswordUser r;
1670 bool ret = true;
1671 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1672 struct policy_handle user_handle;
1673 char *oldpass;
1674 uint8_t old_nt_hash[16], new_nt_hash[16];
1675 uint8_t old_lm_hash[16], new_lm_hash[16];
1676 bool changed = true;
1678 char *newpass;
1679 struct samr_GetUserPwInfo pwp;
1680 struct samr_PwInfo info;
1681 int policy_min_pw_len = 0;
1683 status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
1684 if (!NT_STATUS_IS_OK(status)) {
1685 return false;
1687 pwp.in.user_handle = &user_handle;
1688 pwp.out.info = &info;
1690 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1691 "GetUserPwInfo failed");
1692 if (NT_STATUS_IS_OK(pwp.out.result)) {
1693 policy_min_pw_len = pwp.out.info->min_password_length;
1695 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1697 torture_comment(tctx, "Testing ChangePasswordUser\n");
1699 torture_assert(tctx, *password != NULL,
1700 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1702 oldpass = *password;
1704 E_md4hash(oldpass, old_nt_hash);
1705 E_md4hash(newpass, new_nt_hash);
1706 E_deshash(oldpass, old_lm_hash);
1707 E_deshash(newpass, new_lm_hash);
1709 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1710 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1711 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1712 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1713 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1714 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1716 r.in.user_handle = &user_handle;
1717 r.in.lm_present = 1;
1718 /* Break the LM hash */
1719 hash1.hash[0]++;
1720 r.in.old_lm_crypted = &hash1;
1721 r.in.new_lm_crypted = &hash2;
1722 r.in.nt_present = 1;
1723 r.in.old_nt_crypted = &hash3;
1724 r.in.new_nt_crypted = &hash4;
1725 r.in.cross1_present = 1;
1726 r.in.nt_cross = &hash5;
1727 r.in.cross2_present = 1;
1728 r.in.lm_cross = &hash6;
1730 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1731 "ChangePasswordUser failed");
1732 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1733 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1735 /* Unbreak the LM hash */
1736 hash1.hash[0]--;
1738 r.in.user_handle = &user_handle;
1739 r.in.lm_present = 1;
1740 r.in.old_lm_crypted = &hash1;
1741 r.in.new_lm_crypted = &hash2;
1742 /* Break the NT hash */
1743 hash3.hash[0]--;
1744 r.in.nt_present = 1;
1745 r.in.old_nt_crypted = &hash3;
1746 r.in.new_nt_crypted = &hash4;
1747 r.in.cross1_present = 1;
1748 r.in.nt_cross = &hash5;
1749 r.in.cross2_present = 1;
1750 r.in.lm_cross = &hash6;
1752 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1753 "ChangePasswordUser failed");
1754 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1755 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1757 /* Unbreak the NT hash */
1758 hash3.hash[0]--;
1760 r.in.user_handle = &user_handle;
1761 r.in.lm_present = 1;
1762 r.in.old_lm_crypted = &hash1;
1763 r.in.new_lm_crypted = &hash2;
1764 r.in.nt_present = 1;
1765 r.in.old_nt_crypted = &hash3;
1766 r.in.new_nt_crypted = &hash4;
1767 r.in.cross1_present = 1;
1768 r.in.nt_cross = &hash5;
1769 r.in.cross2_present = 1;
1770 /* Break the LM cross */
1771 hash6.hash[0]++;
1772 r.in.lm_cross = &hash6;
1774 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1775 "ChangePasswordUser failed");
1776 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1777 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));
1778 ret = false;
1781 /* Unbreak the LM cross */
1782 hash6.hash[0]--;
1784 r.in.user_handle = &user_handle;
1785 r.in.lm_present = 1;
1786 r.in.old_lm_crypted = &hash1;
1787 r.in.new_lm_crypted = &hash2;
1788 r.in.nt_present = 1;
1789 r.in.old_nt_crypted = &hash3;
1790 r.in.new_nt_crypted = &hash4;
1791 r.in.cross1_present = 1;
1792 /* Break the NT cross */
1793 hash5.hash[0]++;
1794 r.in.nt_cross = &hash5;
1795 r.in.cross2_present = 1;
1796 r.in.lm_cross = &hash6;
1798 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1799 "ChangePasswordUser failed");
1800 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1801 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));
1802 ret = false;
1805 /* Unbreak the NT cross */
1806 hash5.hash[0]--;
1809 /* Reset the hashes to not broken values */
1810 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1811 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1812 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1813 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1814 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1815 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1817 r.in.user_handle = &user_handle;
1818 r.in.lm_present = 1;
1819 r.in.old_lm_crypted = &hash1;
1820 r.in.new_lm_crypted = &hash2;
1821 r.in.nt_present = 1;
1822 r.in.old_nt_crypted = &hash3;
1823 r.in.new_nt_crypted = &hash4;
1824 r.in.cross1_present = 1;
1825 r.in.nt_cross = &hash5;
1826 r.in.cross2_present = 0;
1827 r.in.lm_cross = NULL;
1829 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1830 "ChangePasswordUser failed");
1831 if (NT_STATUS_IS_OK(r.out.result)) {
1832 changed = true;
1833 *password = newpass;
1834 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1835 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1836 ret = false;
1839 oldpass = newpass;
1840 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1842 E_md4hash(oldpass, old_nt_hash);
1843 E_md4hash(newpass, new_nt_hash);
1844 E_deshash(oldpass, old_lm_hash);
1845 E_deshash(newpass, new_lm_hash);
1848 /* Reset the hashes to not broken values */
1849 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1850 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1851 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1852 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1853 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1854 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1856 r.in.user_handle = &user_handle;
1857 r.in.lm_present = 1;
1858 r.in.old_lm_crypted = &hash1;
1859 r.in.new_lm_crypted = &hash2;
1860 r.in.nt_present = 1;
1861 r.in.old_nt_crypted = &hash3;
1862 r.in.new_nt_crypted = &hash4;
1863 r.in.cross1_present = 0;
1864 r.in.nt_cross = NULL;
1865 r.in.cross2_present = 1;
1866 r.in.lm_cross = &hash6;
1868 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1869 "ChangePasswordUser failed");
1870 if (NT_STATUS_IS_OK(r.out.result)) {
1871 changed = true;
1872 *password = newpass;
1873 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1874 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1875 ret = false;
1878 oldpass = newpass;
1879 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1881 E_md4hash(oldpass, old_nt_hash);
1882 E_md4hash(newpass, new_nt_hash);
1883 E_deshash(oldpass, old_lm_hash);
1884 E_deshash(newpass, new_lm_hash);
1887 /* Reset the hashes to not broken values */
1888 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1889 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1890 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1891 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1892 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1893 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1895 r.in.user_handle = &user_handle;
1896 r.in.lm_present = 1;
1897 r.in.old_lm_crypted = &hash1;
1898 r.in.new_lm_crypted = &hash2;
1899 r.in.nt_present = 1;
1900 r.in.old_nt_crypted = &hash3;
1901 r.in.new_nt_crypted = &hash4;
1902 r.in.cross1_present = 1;
1903 r.in.nt_cross = &hash5;
1904 r.in.cross2_present = 1;
1905 r.in.lm_cross = &hash6;
1907 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1908 "ChangePasswordUser failed");
1909 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1910 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1911 } else if (!NT_STATUS_IS_OK(r.out.result)) {
1912 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1913 ret = false;
1914 } else {
1915 changed = true;
1916 *password = newpass;
1919 r.in.user_handle = &user_handle;
1920 r.in.lm_present = 1;
1921 r.in.old_lm_crypted = &hash1;
1922 r.in.new_lm_crypted = &hash2;
1923 r.in.nt_present = 1;
1924 r.in.old_nt_crypted = &hash3;
1925 r.in.new_nt_crypted = &hash4;
1926 r.in.cross1_present = 1;
1927 r.in.nt_cross = &hash5;
1928 r.in.cross2_present = 1;
1929 r.in.lm_cross = &hash6;
1931 if (changed) {
1932 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1933 "ChangePasswordUser failed");
1934 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1935 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1936 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1937 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
1938 ret = false;
1943 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
1944 ret = false;
1947 return ret;
1951 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
1952 struct torture_context *tctx,
1953 const char *acct_name,
1954 struct policy_handle *handle, char **password)
1956 struct samr_OemChangePasswordUser2 r;
1957 bool ret = true;
1958 struct samr_Password lm_verifier;
1959 struct samr_CryptPassword lm_pass;
1960 struct lsa_AsciiString server, account, account_bad;
1961 char *oldpass;
1962 char *newpass;
1963 struct dcerpc_binding_handle *b = p->binding_handle;
1964 uint8_t old_lm_hash[16], new_lm_hash[16];
1966 struct samr_GetDomPwInfo dom_pw_info;
1967 struct samr_PwInfo info;
1968 int policy_min_pw_len = 0;
1970 struct lsa_String domain_name;
1972 domain_name.string = "";
1973 dom_pw_info.in.domain_name = &domain_name;
1974 dom_pw_info.out.info = &info;
1976 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1978 torture_assert(tctx, *password != NULL,
1979 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1981 oldpass = *password;
1983 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
1984 "GetDomPwInfo failed");
1985 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
1986 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1989 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1991 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1992 account.string = acct_name;
1994 E_deshash(oldpass, old_lm_hash);
1995 E_deshash(newpass, new_lm_hash);
1997 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1998 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1999 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2001 r.in.server = &server;
2002 r.in.account = &account;
2003 r.in.password = &lm_pass;
2004 r.in.hash = &lm_verifier;
2006 /* Break the verification */
2007 lm_verifier.hash[0]++;
2009 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2010 "OemChangePasswordUser2 failed");
2012 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2013 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2014 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2015 nt_errstr(r.out.result));
2016 ret = false;
2019 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2020 /* Break the old password */
2021 old_lm_hash[0]++;
2022 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2023 /* unbreak it for the next operation */
2024 old_lm_hash[0]--;
2025 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2027 r.in.server = &server;
2028 r.in.account = &account;
2029 r.in.password = &lm_pass;
2030 r.in.hash = &lm_verifier;
2032 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2033 "OemChangePasswordUser2 failed");
2035 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2036 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2037 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2038 nt_errstr(r.out.result));
2039 ret = false;
2042 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2043 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2045 r.in.server = &server;
2046 r.in.account = &account;
2047 r.in.password = &lm_pass;
2048 r.in.hash = NULL;
2050 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2051 "OemChangePasswordUser2 failed");
2053 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2054 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2055 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2056 nt_errstr(r.out.result));
2057 ret = false;
2060 /* This shouldn't be a valid name */
2061 account_bad.string = TEST_ACCOUNT_NAME "XX";
2062 r.in.account = &account_bad;
2064 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2065 "OemChangePasswordUser2 failed");
2067 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2068 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2069 nt_errstr(r.out.result));
2070 ret = false;
2073 /* This shouldn't be a valid name */
2074 account_bad.string = TEST_ACCOUNT_NAME "XX";
2075 r.in.account = &account_bad;
2076 r.in.password = &lm_pass;
2077 r.in.hash = &lm_verifier;
2079 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2080 "OemChangePasswordUser2 failed");
2082 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2083 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2084 nt_errstr(r.out.result));
2085 ret = false;
2088 /* This shouldn't be a valid name */
2089 account_bad.string = TEST_ACCOUNT_NAME "XX";
2090 r.in.account = &account_bad;
2091 r.in.password = NULL;
2092 r.in.hash = &lm_verifier;
2094 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2095 "OemChangePasswordUser2 failed");
2097 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2098 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2099 nt_errstr(r.out.result));
2100 ret = false;
2103 E_deshash(oldpass, old_lm_hash);
2104 E_deshash(newpass, new_lm_hash);
2106 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2107 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2108 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2110 r.in.server = &server;
2111 r.in.account = &account;
2112 r.in.password = &lm_pass;
2113 r.in.hash = &lm_verifier;
2115 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2116 "OemChangePasswordUser2 failed");
2118 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2119 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2120 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2121 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2122 ret = false;
2123 } else {
2124 *password = newpass;
2127 return ret;
2131 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2132 const char *acct_name,
2133 char **password,
2134 char *newpass, bool allow_password_restriction)
2136 struct samr_ChangePasswordUser2 r;
2137 bool ret = true;
2138 struct lsa_String server, account;
2139 struct samr_CryptPassword nt_pass, lm_pass;
2140 struct samr_Password nt_verifier, lm_verifier;
2141 char *oldpass;
2142 struct dcerpc_binding_handle *b = p->binding_handle;
2143 uint8_t old_nt_hash[16], new_nt_hash[16];
2144 uint8_t old_lm_hash[16], new_lm_hash[16];
2146 struct samr_GetDomPwInfo dom_pw_info;
2147 struct samr_PwInfo info;
2149 struct lsa_String domain_name;
2151 domain_name.string = "";
2152 dom_pw_info.in.domain_name = &domain_name;
2153 dom_pw_info.out.info = &info;
2155 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2157 torture_assert(tctx, *password != NULL,
2158 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2159 oldpass = *password;
2161 if (!newpass) {
2162 int policy_min_pw_len = 0;
2163 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2164 "GetDomPwInfo failed");
2165 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2166 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2169 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2172 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2173 init_lsa_String(&account, acct_name);
2175 E_md4hash(oldpass, old_nt_hash);
2176 E_md4hash(newpass, new_nt_hash);
2178 E_deshash(oldpass, old_lm_hash);
2179 E_deshash(newpass, new_lm_hash);
2181 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2182 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2183 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2185 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2186 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2187 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2189 r.in.server = &server;
2190 r.in.account = &account;
2191 r.in.nt_password = &nt_pass;
2192 r.in.nt_verifier = &nt_verifier;
2193 r.in.lm_change = 1;
2194 r.in.lm_password = &lm_pass;
2195 r.in.lm_verifier = &lm_verifier;
2197 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2198 "ChangePasswordUser2 failed");
2200 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2201 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2202 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2203 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2204 ret = false;
2205 } else {
2206 *password = newpass;
2209 return ret;
2213 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2214 const char *account_string,
2215 int policy_min_pw_len,
2216 char **password,
2217 const char *newpass,
2218 NTTIME last_password_change,
2219 bool handle_reject_reason)
2221 struct samr_ChangePasswordUser3 r;
2222 bool ret = true;
2223 struct lsa_String server, account, account_bad;
2224 struct samr_CryptPassword nt_pass, lm_pass;
2225 struct samr_Password nt_verifier, lm_verifier;
2226 char *oldpass;
2227 struct dcerpc_binding_handle *b = p->binding_handle;
2228 uint8_t old_nt_hash[16], new_nt_hash[16];
2229 uint8_t old_lm_hash[16], new_lm_hash[16];
2230 NTTIME t;
2231 struct samr_DomInfo1 *dominfo = NULL;
2232 struct userPwdChangeFailureInformation *reject = NULL;
2234 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2236 if (newpass == NULL) {
2237 do {
2238 if (policy_min_pw_len == 0) {
2239 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2240 } else {
2241 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2243 } while (check_password_quality(newpass) == false);
2244 } else {
2245 torture_comment(tctx, "Using password '%s'\n", newpass);
2248 torture_assert(tctx, *password != NULL,
2249 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2251 oldpass = *password;
2252 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2253 init_lsa_String(&account, account_string);
2255 E_md4hash(oldpass, old_nt_hash);
2256 E_md4hash(newpass, new_nt_hash);
2258 E_deshash(oldpass, old_lm_hash);
2259 E_deshash(newpass, new_lm_hash);
2261 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2262 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2263 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2265 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2266 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2267 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2269 /* Break the verification */
2270 nt_verifier.hash[0]++;
2272 r.in.server = &server;
2273 r.in.account = &account;
2274 r.in.nt_password = &nt_pass;
2275 r.in.nt_verifier = &nt_verifier;
2276 r.in.lm_change = 1;
2277 r.in.lm_password = &lm_pass;
2278 r.in.lm_verifier = &lm_verifier;
2279 r.in.password3 = NULL;
2280 r.out.dominfo = &dominfo;
2281 r.out.reject = &reject;
2283 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2284 "ChangePasswordUser3 failed");
2285 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2286 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2287 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2288 nt_errstr(r.out.result));
2289 ret = false;
2292 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2293 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2294 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2296 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2297 /* Break the NT hash */
2298 old_nt_hash[0]++;
2299 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2300 /* Unbreak it again */
2301 old_nt_hash[0]--;
2302 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2304 r.in.server = &server;
2305 r.in.account = &account;
2306 r.in.nt_password = &nt_pass;
2307 r.in.nt_verifier = &nt_verifier;
2308 r.in.lm_change = 1;
2309 r.in.lm_password = &lm_pass;
2310 r.in.lm_verifier = &lm_verifier;
2311 r.in.password3 = NULL;
2312 r.out.dominfo = &dominfo;
2313 r.out.reject = &reject;
2315 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2316 "ChangePasswordUser3 failed");
2317 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2318 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2319 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2320 nt_errstr(r.out.result));
2321 ret = false;
2324 /* This shouldn't be a valid name */
2325 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2327 r.in.account = &account_bad;
2328 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2329 "ChangePasswordUser3 failed");
2330 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2331 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2332 nt_errstr(r.out.result));
2333 ret = false;
2336 E_md4hash(oldpass, old_nt_hash);
2337 E_md4hash(newpass, new_nt_hash);
2339 E_deshash(oldpass, old_lm_hash);
2340 E_deshash(newpass, new_lm_hash);
2342 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2343 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2344 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2346 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2347 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2348 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2350 r.in.server = &server;
2351 r.in.account = &account;
2352 r.in.nt_password = &nt_pass;
2353 r.in.nt_verifier = &nt_verifier;
2354 r.in.lm_change = 1;
2355 r.in.lm_password = &lm_pass;
2356 r.in.lm_verifier = &lm_verifier;
2357 r.in.password3 = NULL;
2358 r.out.dominfo = &dominfo;
2359 r.out.reject = &reject;
2361 unix_to_nt_time(&t, time(NULL));
2363 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2364 "ChangePasswordUser3 failed");
2366 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2367 && dominfo
2368 && reject
2369 && handle_reject_reason
2370 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2371 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2373 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2374 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2375 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2376 return false;
2380 /* We tested the order of precendence which is as follows:
2382 * pwd min_age
2383 * pwd length
2384 * pwd complexity
2385 * pwd history
2387 Guenther */
2389 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2390 (last_password_change + dominfo->min_password_age > t)) {
2392 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2393 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2394 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2395 return false;
2398 } else if ((dominfo->min_password_length > 0) &&
2399 (strlen(newpass) < dominfo->min_password_length)) {
2401 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2402 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2403 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2404 return false;
2407 } else if ((dominfo->password_history_length > 0) &&
2408 strequal(oldpass, newpass)) {
2410 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2411 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2412 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2413 return false;
2415 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2417 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2418 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2419 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2420 return false;
2425 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2426 /* retry with adjusted size */
2427 return test_ChangePasswordUser3(p, tctx, account_string,
2428 dominfo->min_password_length,
2429 password, NULL, 0, false);
2433 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2434 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2435 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2436 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2437 return false;
2439 /* Perhaps the server has a 'min password age' set? */
2441 } else {
2442 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2444 *password = talloc_strdup(tctx, newpass);
2447 return ret;
2450 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2451 const char *account_string,
2452 struct policy_handle *handle,
2453 char **password)
2455 NTSTATUS status;
2456 struct samr_ChangePasswordUser3 r;
2457 struct samr_SetUserInfo s;
2458 union samr_UserInfo u;
2459 DATA_BLOB session_key;
2460 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2461 uint8_t confounder[16];
2462 struct MD5Context ctx;
2464 bool ret = true;
2465 struct lsa_String server, account;
2466 struct samr_CryptPassword nt_pass;
2467 struct samr_Password nt_verifier;
2468 DATA_BLOB new_random_pass;
2469 char *newpass;
2470 char *oldpass;
2471 struct dcerpc_binding_handle *b = p->binding_handle;
2472 uint8_t old_nt_hash[16], new_nt_hash[16];
2473 NTTIME t;
2474 struct samr_DomInfo1 *dominfo = NULL;
2475 struct userPwdChangeFailureInformation *reject = NULL;
2477 new_random_pass = samr_very_rand_pass(tctx, 128);
2479 torture_assert(tctx, *password != NULL,
2480 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2482 oldpass = *password;
2483 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2484 init_lsa_String(&account, account_string);
2486 s.in.user_handle = handle;
2487 s.in.info = &u;
2488 s.in.level = 25;
2490 ZERO_STRUCT(u);
2492 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2494 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2496 status = dcerpc_fetch_session_key(p, &session_key);
2497 if (!NT_STATUS_IS_OK(status)) {
2498 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2499 s.in.level, nt_errstr(status));
2500 return false;
2503 generate_random_buffer((uint8_t *)confounder, 16);
2505 MD5Init(&ctx);
2506 MD5Update(&ctx, confounder, 16);
2507 MD5Update(&ctx, session_key.data, session_key.length);
2508 MD5Final(confounded_session_key.data, &ctx);
2510 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2511 memcpy(&u.info25.password.data[516], confounder, 16);
2513 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2515 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2516 "SetUserInfo failed");
2517 if (!NT_STATUS_IS_OK(s.out.result)) {
2518 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2519 s.in.level, nt_errstr(s.out.result));
2520 ret = false;
2523 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2525 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2527 new_random_pass = samr_very_rand_pass(tctx, 128);
2529 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2531 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2532 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2533 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2535 r.in.server = &server;
2536 r.in.account = &account;
2537 r.in.nt_password = &nt_pass;
2538 r.in.nt_verifier = &nt_verifier;
2539 r.in.lm_change = 0;
2540 r.in.lm_password = NULL;
2541 r.in.lm_verifier = NULL;
2542 r.in.password3 = NULL;
2543 r.out.dominfo = &dominfo;
2544 r.out.reject = &reject;
2546 unix_to_nt_time(&t, time(NULL));
2548 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2549 "ChangePasswordUser3 failed");
2551 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2552 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2553 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2554 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2555 return false;
2557 /* Perhaps the server has a 'min password age' set? */
2559 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2560 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2561 ret = false;
2564 newpass = samr_rand_pass(tctx, 128);
2566 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2568 E_md4hash(newpass, new_nt_hash);
2570 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2571 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2572 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2574 r.in.server = &server;
2575 r.in.account = &account;
2576 r.in.nt_password = &nt_pass;
2577 r.in.nt_verifier = &nt_verifier;
2578 r.in.lm_change = 0;
2579 r.in.lm_password = NULL;
2580 r.in.lm_verifier = NULL;
2581 r.in.password3 = NULL;
2582 r.out.dominfo = &dominfo;
2583 r.out.reject = &reject;
2585 unix_to_nt_time(&t, time(NULL));
2587 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2588 "ChangePasswordUser3 failed");
2590 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2591 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2592 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2593 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2594 return false;
2596 /* Perhaps the server has a 'min password age' set? */
2598 } else {
2599 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2600 *password = talloc_strdup(tctx, newpass);
2603 return ret;
2607 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2608 struct torture_context *tctx,
2609 struct policy_handle *alias_handle)
2611 struct samr_GetMembersInAlias r;
2612 struct lsa_SidArray sids;
2614 torture_comment(tctx, "Testing GetMembersInAlias\n");
2616 r.in.alias_handle = alias_handle;
2617 r.out.sids = &sids;
2619 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2620 "GetMembersInAlias failed");
2621 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2623 return true;
2626 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2627 struct torture_context *tctx,
2628 struct policy_handle *alias_handle,
2629 const struct dom_sid *domain_sid)
2631 struct samr_AddAliasMember r;
2632 struct samr_DeleteAliasMember d;
2633 struct dom_sid *sid;
2635 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2637 torture_comment(tctx, "Testing AddAliasMember\n");
2638 r.in.alias_handle = alias_handle;
2639 r.in.sid = sid;
2641 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2642 "AddAliasMember failed");
2643 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2645 d.in.alias_handle = alias_handle;
2646 d.in.sid = sid;
2648 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2649 "DeleteAliasMember failed");
2650 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2652 return true;
2655 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2656 struct torture_context *tctx,
2657 struct policy_handle *alias_handle)
2659 struct samr_AddMultipleMembersToAlias a;
2660 struct samr_RemoveMultipleMembersFromAlias r;
2661 struct lsa_SidArray sids;
2663 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2664 a.in.alias_handle = alias_handle;
2665 a.in.sids = &sids;
2667 sids.num_sids = 3;
2668 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2670 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2671 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2672 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2674 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2675 "AddMultipleMembersToAlias failed");
2676 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2679 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2680 r.in.alias_handle = alias_handle;
2681 r.in.sids = &sids;
2683 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2684 "RemoveMultipleMembersFromAlias failed");
2685 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2687 /* strange! removing twice doesn't give any error */
2688 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2689 "RemoveMultipleMembersFromAlias failed");
2690 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2692 /* but removing an alias that isn't there does */
2693 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2695 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2696 "RemoveMultipleMembersFromAlias failed");
2697 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2699 return true;
2702 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2703 struct torture_context *tctx,
2704 struct policy_handle *domain_handle)
2706 struct samr_GetAliasMembership r;
2707 struct lsa_SidArray sids;
2708 struct samr_Ids rids;
2710 torture_comment(tctx, "Testing GetAliasMembership\n");
2712 r.in.domain_handle = domain_handle;
2713 r.in.sids = &sids;
2714 r.out.rids = &rids;
2716 sids.num_sids = 0;
2717 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2719 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2720 "GetAliasMembership failed");
2721 torture_assert_ntstatus_ok(tctx, r.out.result,
2722 "samr_GetAliasMembership failed");
2724 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2725 "protocol misbehaviour");
2727 sids.num_sids = 1;
2728 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2729 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2731 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2732 "samr_GetAliasMembership failed");
2733 torture_assert_ntstatus_ok(tctx, r.out.result,
2734 "samr_GetAliasMembership failed");
2736 #if 0
2737 /* only true for w2k8 it seems
2738 * win7, xp, w2k3 will return a 0 length array pointer */
2740 if (rids.ids && (rids.count == 0)) {
2741 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2743 #endif
2744 if (!rids.ids && rids.count) {
2745 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2748 return true;
2751 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2752 struct torture_context *tctx,
2753 struct policy_handle *user_handle)
2755 struct samr_TestPrivateFunctionsUser r;
2757 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2759 r.in.user_handle = user_handle;
2761 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2762 "TestPrivateFunctionsUser failed");
2763 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2765 return true;
2768 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2769 struct torture_context *tctx,
2770 struct policy_handle *handle,
2771 bool use_info2,
2772 NTTIME *pwdlastset)
2774 NTSTATUS status;
2775 uint16_t levels[] = { /* 3, */ 5, 21 };
2776 int i;
2777 NTTIME pwdlastset3 = 0;
2778 NTTIME pwdlastset5 = 0;
2779 NTTIME pwdlastset21 = 0;
2781 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2782 use_info2 ? "2":"");
2784 for (i=0; i<ARRAY_SIZE(levels); i++) {
2786 struct samr_QueryUserInfo r;
2787 struct samr_QueryUserInfo2 r2;
2788 union samr_UserInfo *info;
2790 if (use_info2) {
2791 r2.in.user_handle = handle;
2792 r2.in.level = levels[i];
2793 r2.out.info = &info;
2794 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2795 "QueryUserInfo2 failed");
2796 status = r2.out.result;
2798 } else {
2799 r.in.user_handle = handle;
2800 r.in.level = levels[i];
2801 r.out.info = &info;
2802 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2803 "QueryUserInfo failed");
2804 status = r.out.result;
2807 if (!NT_STATUS_IS_OK(status) &&
2808 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2809 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2810 use_info2 ? "2":"", levels[i], nt_errstr(status));
2811 return false;
2814 switch (levels[i]) {
2815 case 3:
2816 pwdlastset3 = info->info3.last_password_change;
2817 break;
2818 case 5:
2819 pwdlastset5 = info->info5.last_password_change;
2820 break;
2821 case 21:
2822 pwdlastset21 = info->info21.last_password_change;
2823 break;
2824 default:
2825 return false;
2828 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2829 "pwdlastset mixup"); */
2830 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2831 "pwdlastset mixup");
2833 *pwdlastset = pwdlastset21;
2835 torture_comment(tctx, "(pwdlastset: %llu)\n",
2836 (unsigned long long) *pwdlastset);
2838 return true;
2841 static bool test_SamLogon(struct torture_context *tctx,
2842 struct dcerpc_pipe *p,
2843 struct cli_credentials *test_credentials,
2844 NTSTATUS expected_result,
2845 bool interactive)
2847 NTSTATUS status;
2848 struct netr_LogonSamLogonEx r;
2849 union netr_LogonLevel logon;
2850 union netr_Validation validation;
2851 uint8_t authoritative;
2852 struct netr_IdentityInfo identity;
2853 struct netr_NetworkInfo ninfo;
2854 struct netr_PasswordInfo pinfo;
2855 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2856 int flags = CLI_CRED_NTLM_AUTH;
2857 uint32_t samlogon_flags = 0;
2858 struct netlogon_creds_CredentialState *creds;
2859 struct netr_Authenticator a;
2860 struct dcerpc_binding_handle *b = p->binding_handle;
2862 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2864 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
2865 flags |= CLI_CRED_LANMAN_AUTH;
2868 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
2869 flags |= CLI_CRED_NTLMv2_AUTH;
2872 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2873 &identity.account_name.string,
2874 &identity.domain_name.string);
2876 identity.parameter_control =
2877 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2878 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2879 identity.logon_id_low = 0;
2880 identity.logon_id_high = 0;
2881 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2883 if (interactive) {
2884 netlogon_creds_client_authenticator(creds, &a);
2886 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2887 ZERO_STRUCT(pinfo.lmpassword.hash);
2889 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2891 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2892 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2893 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2894 } else {
2895 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2896 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2899 pinfo.identity_info = identity;
2900 logon.password = &pinfo;
2902 r.in.logon_level = NetlogonInteractiveInformation;
2903 } else {
2904 generate_random_buffer(ninfo.challenge,
2905 sizeof(ninfo.challenge));
2906 chal = data_blob_const(ninfo.challenge,
2907 sizeof(ninfo.challenge));
2909 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2910 cli_credentials_get_domain(test_credentials));
2912 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2913 &flags,
2914 chal,
2915 names_blob,
2916 &lm_resp, &nt_resp,
2917 NULL, NULL);
2918 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2920 ninfo.lm.data = lm_resp.data;
2921 ninfo.lm.length = lm_resp.length;
2923 ninfo.nt.data = nt_resp.data;
2924 ninfo.nt.length = nt_resp.length;
2926 ninfo.identity_info = identity;
2927 logon.network = &ninfo;
2929 r.in.logon_level = NetlogonNetworkInformation;
2932 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2933 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2934 r.in.logon = &logon;
2935 r.in.flags = &samlogon_flags;
2936 r.out.flags = &samlogon_flags;
2937 r.out.validation = &validation;
2938 r.out.authoritative = &authoritative;
2940 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2942 r.in.validation_level = 6;
2944 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2945 "netr_LogonSamLogonEx failed");
2946 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
2947 r.in.validation_level = 3;
2948 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2949 "netr_LogonSamLogonEx failed");
2951 if (!NT_STATUS_IS_OK(r.out.result)) {
2952 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
2953 return true;
2954 } else {
2955 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
2958 return true;
2961 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2962 struct dcerpc_pipe *p,
2963 struct cli_credentials *machine_creds,
2964 const char *acct_name,
2965 const char *password,
2966 NTSTATUS expected_samlogon_result,
2967 bool interactive)
2969 bool ret = true;
2970 struct cli_credentials *test_credentials;
2972 test_credentials = cli_credentials_init(tctx);
2974 cli_credentials_set_workstation(test_credentials,
2975 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2976 cli_credentials_set_domain(test_credentials,
2977 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2978 cli_credentials_set_username(test_credentials,
2979 acct_name, CRED_SPECIFIED);
2980 cli_credentials_set_password(test_credentials,
2981 password, CRED_SPECIFIED);
2983 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
2984 interactive ? "interactive" : "network", acct_name, password);
2986 if (!test_SamLogon(tctx, p, test_credentials,
2987 expected_samlogon_result, interactive)) {
2988 torture_warning(tctx, "new password did not work\n");
2989 ret = false;
2992 return ret;
2995 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2996 struct dcerpc_pipe *np,
2997 struct torture_context *tctx,
2998 struct policy_handle *handle,
2999 uint16_t level,
3000 uint32_t fields_present,
3001 uint8_t password_expired,
3002 bool *matched_expected_error,
3003 bool use_setinfo2,
3004 const char *acct_name,
3005 char **password,
3006 struct cli_credentials *machine_creds,
3007 bool use_queryinfo2,
3008 NTTIME *pwdlastset,
3009 NTSTATUS expected_samlogon_result)
3011 const char *fields = NULL;
3012 bool ret = true;
3013 struct dcerpc_binding_handle *b = p->binding_handle;
3015 switch (level) {
3016 case 21:
3017 case 23:
3018 case 25:
3019 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3020 fields_present);
3021 break;
3022 default:
3023 break;
3026 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3027 "(password_expired: %d) %s\n",
3028 use_setinfo2 ? "2":"", level, password_expired,
3029 fields ? fields : "");
3031 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3032 fields_present,
3033 password,
3034 password_expired,
3035 use_setinfo2,
3036 matched_expected_error)) {
3037 ret = false;
3040 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3041 use_queryinfo2,
3042 pwdlastset)) {
3043 ret = false;
3046 if (*matched_expected_error == true) {
3047 return ret;
3050 if (!test_SamLogon_with_creds(tctx, np,
3051 machine_creds,
3052 acct_name,
3053 *password,
3054 expected_samlogon_result,
3055 false)) {
3056 ret = false;
3059 return ret;
3062 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3063 struct cli_credentials *credentials,
3064 struct dcerpc_pipe **p)
3066 struct dcerpc_binding *b;
3068 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3069 "failed to get rpc binding");
3071 /* We have to use schannel, otherwise the SamLogonEx fails
3072 * with INTERNAL_ERROR */
3074 b->flags &= ~DCERPC_AUTH_OPTIONS;
3075 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
3077 torture_assert_ntstatus_ok(tctx,
3078 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3079 credentials, tctx->ev, tctx->lp_ctx),
3080 "failed to bind to netlogon");
3082 return true;
3085 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3086 struct torture_context *tctx,
3087 uint32_t acct_flags,
3088 const char *acct_name,
3089 struct policy_handle *handle,
3090 char **password,
3091 struct cli_credentials *machine_credentials)
3093 int s = 0, q = 0, f = 0, l = 0, z = 0;
3094 bool ret = true;
3095 int delay = 50000;
3096 bool set_levels[] = { false, true };
3097 bool query_levels[] = { false, true };
3098 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3099 uint32_t nonzeros[] = { 1, 24 };
3100 uint32_t fields_present[] = {
3102 SAMR_FIELD_EXPIRED_FLAG,
3103 SAMR_FIELD_LAST_PWD_CHANGE,
3104 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3105 SAMR_FIELD_COMMENT,
3106 SAMR_FIELD_NT_PASSWORD_PRESENT,
3107 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3108 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3109 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3110 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3111 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3112 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3114 struct dcerpc_pipe *np = NULL;
3116 if (torture_setting_bool(tctx, "samba3", false) ||
3117 torture_setting_bool(tctx, "samba4", false)) {
3118 delay = 999999;
3119 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3120 delay);
3123 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3125 /* set to 1 to enable testing for all possible opcode
3126 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3127 combinations */
3128 #if 0
3129 #define TEST_ALL_LEVELS 1
3130 #define TEST_SET_LEVELS 1
3131 #define TEST_QUERY_LEVELS 1
3132 #endif
3133 #ifdef TEST_ALL_LEVELS
3134 for (l=0; l<ARRAY_SIZE(levels); l++) {
3135 #else
3136 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3137 #endif
3138 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3139 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3140 #ifdef TEST_SET_LEVELS
3141 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3142 #endif
3143 #ifdef TEST_QUERY_LEVELS
3144 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3145 #endif
3146 NTTIME pwdlastset_old = 0;
3147 NTTIME pwdlastset_new = 0;
3148 bool matched_expected_error = false;
3149 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3151 torture_comment(tctx, "------------------------------\n"
3152 "Testing pwdLastSet attribute for flags: 0x%08x "
3153 "(s: %d (l: %d), q: %d)\n",
3154 acct_flags, s, levels[l], q);
3156 switch (levels[l]) {
3157 case 21:
3158 case 23:
3159 case 25:
3160 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3161 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3162 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3164 break;
3168 /* set #1 */
3170 /* set a password and force password change (pwdlastset 0) by
3171 * setting the password expired flag to a non-0 value */
3173 if (!test_SetPassword_level(p, np, tctx, handle,
3174 levels[l],
3175 fields_present[f],
3176 nonzeros[z],
3177 &matched_expected_error,
3178 set_levels[s],
3179 acct_name,
3180 password,
3181 machine_credentials,
3182 query_levels[q],
3183 &pwdlastset_new,
3184 expected_samlogon_result)) {
3185 ret = false;
3188 if (matched_expected_error == true) {
3189 /* skipping on expected failure */
3190 continue;
3193 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3194 * set without the SAMR_FIELD_EXPIRED_FLAG */
3196 switch (levels[l]) {
3197 case 21:
3198 case 23:
3199 case 25:
3200 if ((pwdlastset_new != 0) &&
3201 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3202 torture_comment(tctx, "not considering a non-0 "
3203 "pwdLastSet as a an error as the "
3204 "SAMR_FIELD_EXPIRED_FLAG has not "
3205 "been set\n");
3206 break;
3208 break;
3209 default:
3210 if (pwdlastset_new != 0) {
3211 torture_warning(tctx, "pwdLastSet test failed: "
3212 "expected pwdLastSet 0 but got %llu\n",
3213 (unsigned long long) pwdlastset_old);
3214 ret = false;
3216 break;
3219 switch (levels[l]) {
3220 case 21:
3221 case 23:
3222 case 25:
3223 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3224 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3225 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3226 (pwdlastset_old >= pwdlastset_new)) {
3227 torture_warning(tctx, "pwdlastset not increasing\n");
3228 ret = false;
3230 break;
3233 pwdlastset_old = pwdlastset_new;
3235 usleep(delay);
3237 /* set #2 */
3239 /* set a password, pwdlastset needs to get updated (increased
3240 * value), password_expired value used here is 0 */
3242 if (!test_SetPassword_level(p, np, tctx, handle,
3243 levels[l],
3244 fields_present[f],
3246 &matched_expected_error,
3247 set_levels[s],
3248 acct_name,
3249 password,
3250 machine_credentials,
3251 query_levels[q],
3252 &pwdlastset_new,
3253 expected_samlogon_result)) {
3254 ret = false;
3257 /* when a password has been changed, pwdlastset must not be 0 afterwards
3258 * and must be larger then the old value */
3260 switch (levels[l]) {
3261 case 21:
3262 case 23:
3263 case 25:
3264 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3265 * password has been changed, old and new pwdlastset
3266 * need to be the same value */
3268 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3269 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3270 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3272 torture_assert_int_equal(tctx, pwdlastset_old,
3273 pwdlastset_new, "pwdlastset must be equal");
3274 break;
3276 break;
3277 default:
3278 if (pwdlastset_old >= pwdlastset_new) {
3279 torture_warning(tctx, "pwdLastSet test failed: "
3280 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3281 (unsigned long long) pwdlastset_old,
3282 (unsigned long long) pwdlastset_new);
3283 ret = false;
3285 if (pwdlastset_new == 0) {
3286 torture_warning(tctx, "pwdLastSet test failed: "
3287 "expected non-0 pwdlastset, got: %llu\n",
3288 (unsigned long long) pwdlastset_new);
3289 ret = false;
3291 break;
3294 switch (levels[l]) {
3295 case 21:
3296 case 23:
3297 case 25:
3298 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3299 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3300 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3301 (pwdlastset_old >= pwdlastset_new)) {
3302 torture_warning(tctx, "pwdlastset not increasing\n");
3303 ret = false;
3305 break;
3308 pwdlastset_old = pwdlastset_new;
3310 usleep(delay);
3312 /* set #2b */
3314 /* set a password, pwdlastset needs to get updated (increased
3315 * value), password_expired value used here is 0 */
3317 if (!test_SetPassword_level(p, np, tctx, handle,
3318 levels[l],
3319 fields_present[f],
3321 &matched_expected_error,
3322 set_levels[s],
3323 acct_name,
3324 password,
3325 machine_credentials,
3326 query_levels[q],
3327 &pwdlastset_new,
3328 expected_samlogon_result)) {
3329 ret = false;
3332 /* when a password has been changed, pwdlastset must not be 0 afterwards
3333 * and must be larger then the old value */
3335 switch (levels[l]) {
3336 case 21:
3337 case 23:
3338 case 25:
3340 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3341 * password has been changed, old and new pwdlastset
3342 * need to be the same value */
3344 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3345 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3346 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3348 torture_assert_int_equal(tctx, pwdlastset_old,
3349 pwdlastset_new, "pwdlastset must be equal");
3350 break;
3352 break;
3353 default:
3354 if (pwdlastset_old >= pwdlastset_new) {
3355 torture_warning(tctx, "pwdLastSet test failed: "
3356 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3357 (unsigned long long) pwdlastset_old,
3358 (unsigned long long) pwdlastset_new);
3359 ret = false;
3361 if (pwdlastset_new == 0) {
3362 torture_warning(tctx, "pwdLastSet test failed: "
3363 "expected non-0 pwdlastset, got: %llu\n",
3364 (unsigned long long) pwdlastset_new);
3365 ret = false;
3367 break;
3370 switch (levels[l]) {
3371 case 21:
3372 case 23:
3373 case 25:
3374 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3375 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3376 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3377 (pwdlastset_old >= pwdlastset_new)) {
3378 torture_warning(tctx, "pwdlastset not increasing\n");
3379 ret = false;
3381 break;
3384 pwdlastset_old = pwdlastset_new;
3386 usleep(delay);
3388 /* set #3 */
3390 /* set a password and force password change (pwdlastset 0) by
3391 * setting the password expired flag to a non-0 value */
3393 if (!test_SetPassword_level(p, np, tctx, handle,
3394 levels[l],
3395 fields_present[f],
3396 nonzeros[z],
3397 &matched_expected_error,
3398 set_levels[s],
3399 acct_name,
3400 password,
3401 machine_credentials,
3402 query_levels[q],
3403 &pwdlastset_new,
3404 expected_samlogon_result)) {
3405 ret = false;
3408 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3409 * set without the SAMR_FIELD_EXPIRED_FLAG */
3411 switch (levels[l]) {
3412 case 21:
3413 case 23:
3414 case 25:
3415 if ((pwdlastset_new != 0) &&
3416 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3417 torture_comment(tctx, "not considering a non-0 "
3418 "pwdLastSet as a an error as the "
3419 "SAMR_FIELD_EXPIRED_FLAG has not "
3420 "been set\n");
3421 break;
3424 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3425 * password has been changed, old and new pwdlastset
3426 * need to be the same value */
3428 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3429 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3430 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3432 torture_assert_int_equal(tctx, pwdlastset_old,
3433 pwdlastset_new, "pwdlastset must be equal");
3434 break;
3436 break;
3437 default:
3438 if (pwdlastset_new != 0) {
3439 torture_warning(tctx, "pwdLastSet test failed: "
3440 "expected pwdLastSet 0, got %llu\n",
3441 (unsigned long long) pwdlastset_old);
3442 ret = false;
3444 break;
3447 switch (levels[l]) {
3448 case 21:
3449 case 23:
3450 case 25:
3451 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3452 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3453 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3454 (pwdlastset_old >= pwdlastset_new)) {
3455 torture_warning(tctx, "pwdlastset not increasing\n");
3456 ret = false;
3458 break;
3461 /* if the level we are testing does not have a fields_present
3462 * field, skip all fields present tests by setting f to to
3463 * arraysize */
3464 switch (levels[l]) {
3465 case 18:
3466 case 24:
3467 case 26:
3468 f = ARRAY_SIZE(fields_present);
3469 break;
3472 #ifdef TEST_QUERY_LEVELS
3474 #endif
3475 #ifdef TEST_SET_LEVELS
3477 #endif
3478 } /* fields present */
3479 } /* nonzeros */
3480 } /* levels */
3482 #undef TEST_SET_LEVELS
3483 #undef TEST_QUERY_LEVELS
3485 talloc_free(np);
3487 return ret;
3490 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3491 struct torture_context *tctx,
3492 struct policy_handle *handle,
3493 uint32_t *badpwdcount)
3495 union samr_UserInfo *info;
3496 struct samr_QueryUserInfo r;
3498 r.in.user_handle = handle;
3499 r.in.level = 3;
3500 r.out.info = &info;
3502 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3504 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3505 "failed to query userinfo");
3506 torture_assert_ntstatus_ok(tctx, r.out.result,
3507 "failed to query userinfo");
3509 *badpwdcount = info->info3.bad_password_count;
3511 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3513 return true;
3516 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3517 struct torture_context *tctx,
3518 struct policy_handle *user_handle,
3519 uint32_t acct_flags)
3521 struct samr_SetUserInfo r;
3522 union samr_UserInfo user_info;
3524 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3526 user_info.info16.acct_flags = acct_flags;
3528 r.in.user_handle = user_handle;
3529 r.in.level = 16;
3530 r.in.info = &user_info;
3532 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3533 "failed to set account flags");
3534 torture_assert_ntstatus_ok(tctx, r.out.result,
3535 "failed to set account flags");
3537 return true;
3540 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3541 struct torture_context *tctx,
3542 struct policy_handle *user_handle,
3543 uint32_t acct_flags,
3544 char **password)
3546 struct dcerpc_binding_handle *b = p->binding_handle;
3548 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3549 "failed to set password");
3551 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3553 torture_assert(tctx,
3554 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3555 acct_flags & ~ACB_DISABLED),
3556 "failed to enable user");
3558 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3559 "failed to set password");
3561 return true;
3564 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3565 struct torture_context *tctx,
3566 struct policy_handle *domain_handle,
3567 enum samr_DomainInfoClass level,
3568 union samr_DomainInfo *info)
3570 struct samr_SetDomainInfo r;
3572 r.in.domain_handle = domain_handle;
3573 r.in.level = level;
3574 r.in.info = info;
3576 torture_assert_ntstatus_ok(tctx,
3577 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3578 "failed to set domain info");
3579 torture_assert_ntstatus_ok(tctx, r.out.result,
3580 "failed to set domain info");
3582 return true;
3585 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3586 struct torture_context *tctx,
3587 struct policy_handle *domain_handle,
3588 enum samr_DomainInfoClass level,
3589 union samr_DomainInfo *info,
3590 NTSTATUS expected)
3592 struct samr_SetDomainInfo r;
3594 r.in.domain_handle = domain_handle;
3595 r.in.level = level;
3596 r.in.info = info;
3598 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3599 "SetDomainInfo failed");
3600 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3602 return true;
3605 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3606 struct torture_context *tctx,
3607 struct policy_handle *domain_handle,
3608 enum samr_DomainInfoClass level,
3609 union samr_DomainInfo **q_info)
3611 struct samr_QueryDomainInfo2 r;
3613 r.in.domain_handle = domain_handle;
3614 r.in.level = level;
3615 r.out.info = q_info;
3617 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3618 "failed to query domain info");
3619 torture_assert_ntstatus_ok(tctx, r.out.result,
3620 "failed to query domain info");
3622 return true;
3625 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3626 struct dcerpc_pipe *np,
3627 struct torture_context *tctx,
3628 uint32_t acct_flags,
3629 const char *acct_name,
3630 struct policy_handle *domain_handle,
3631 struct policy_handle *user_handle,
3632 char **password,
3633 struct cli_credentials *machine_credentials,
3634 const char *comment,
3635 bool disable,
3636 bool interactive,
3637 NTSTATUS expected_success_status,
3638 struct samr_DomInfo1 *info1,
3639 struct samr_DomInfo12 *info12)
3641 union samr_DomainInfo info;
3642 char **passwords;
3643 int i;
3644 uint32_t badpwdcount, tmp;
3645 uint32_t password_history_length = 12;
3646 uint32_t lockout_threshold = 15;
3647 struct dcerpc_binding_handle *b = p->binding_handle;
3649 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3651 torture_assert(tctx, password_history_length < lockout_threshold,
3652 "password history length needs to be smaller than account lockout threshold for this test");
3655 /* set policies */
3657 info.info1 = *info1;
3658 info.info1.password_history_length = password_history_length;
3660 torture_assert(tctx,
3661 test_SetDomainInfo(b, tctx, domain_handle,
3662 DomainPasswordInformation, &info),
3663 "failed to set password history length");
3665 info.info12 = *info12;
3666 info.info12.lockout_threshold = lockout_threshold;
3668 torture_assert(tctx,
3669 test_SetDomainInfo(b, tctx, domain_handle,
3670 DomainLockoutInformation, &info),
3671 "failed to set lockout threshold");
3673 /* reset bad pwd count */
3675 torture_assert(tctx,
3676 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3679 /* enable or disable account */
3680 if (disable) {
3681 torture_assert(tctx,
3682 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3683 acct_flags | ACB_DISABLED),
3684 "failed to disable user");
3685 } else {
3686 torture_assert(tctx,
3687 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3688 acct_flags & ~ACB_DISABLED),
3689 "failed to enable user");
3693 /* setup password history */
3695 passwords = talloc_array(tctx, char *, password_history_length);
3697 for (i=0; i < password_history_length; i++) {
3699 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3700 "failed to set password");
3701 passwords[i] = talloc_strdup(tctx, *password);
3703 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3704 acct_name, passwords[i],
3705 expected_success_status, interactive)) {
3706 torture_fail(tctx, "failed to auth with latest password");
3709 torture_assert(tctx,
3710 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3712 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3716 /* test with wrong password */
3718 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3719 acct_name, "random_crap",
3720 NT_STATUS_WRONG_PASSWORD, interactive)) {
3721 torture_fail(tctx, "succeeded to authenticate with wrong password");
3724 torture_assert(tctx,
3725 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3727 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3730 /* test with latest good password */
3732 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3733 passwords[password_history_length-1],
3734 expected_success_status, interactive)) {
3735 torture_fail(tctx, "succeeded to authenticate with wrong password");
3738 torture_assert(tctx,
3739 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3741 if (disable) {
3742 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3743 } else {
3744 /* only enabled accounts get the bad pwd count reset upon
3745 * successful logon */
3746 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3749 tmp = badpwdcount;
3752 /* test password history */
3754 for (i=0; i < password_history_length; i++) {
3756 torture_comment(tctx, "Testing bad password count behavior with "
3757 "password #%d of #%d\n", i, password_history_length);
3759 /* - network samlogon will succeed auth and not
3760 * increase badpwdcount for 2 last entries
3761 * - interactive samlogon only for the last one */
3763 if (i == password_history_length - 1 ||
3764 (i == password_history_length - 2 && !interactive)) {
3766 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3767 acct_name, passwords[i],
3768 expected_success_status, interactive)) {
3769 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3772 torture_assert(tctx,
3773 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3775 if (disable) {
3776 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3777 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3778 } else {
3779 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3780 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3783 tmp = badpwdcount;
3785 continue;
3788 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3789 acct_name, passwords[i],
3790 NT_STATUS_WRONG_PASSWORD, interactive)) {
3791 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3794 torture_assert(tctx,
3795 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3797 /* - network samlogon will fail auth but not increase
3798 * badpwdcount for 3rd last entry
3799 * - interactive samlogon for 3rd and 2nd last entry */
3801 if (i == password_history_length - 3 ||
3802 (i == password_history_length - 2 && interactive)) {
3803 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3804 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3805 } else {
3806 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3807 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3810 tmp = badpwdcount;
3813 return true;
3816 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3817 struct torture_context *tctx,
3818 uint32_t acct_flags,
3819 const char *acct_name,
3820 struct policy_handle *domain_handle,
3821 struct policy_handle *user_handle,
3822 char **password,
3823 struct cli_credentials *machine_credentials)
3825 union samr_DomainInfo *q_info, s_info;
3826 struct samr_DomInfo1 info1, _info1;
3827 struct samr_DomInfo12 info12, _info12;
3828 bool ret = true;
3829 struct dcerpc_binding_handle *b = p->binding_handle;
3830 struct dcerpc_pipe *np;
3831 int i;
3833 struct {
3834 const char *comment;
3835 bool disabled;
3836 bool interactive;
3837 NTSTATUS expected_success_status;
3838 } creds[] = {
3840 .comment = "network logon (disabled account)",
3841 .disabled = true,
3842 .interactive = false,
3843 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3846 .comment = "network logon (enabled account)",
3847 .disabled = false,
3848 .interactive = false,
3849 .expected_success_status= NT_STATUS_OK
3852 .comment = "interactive logon (disabled account)",
3853 .disabled = true,
3854 .interactive = true,
3855 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3858 .comment = "interactive logon (enabled account)",
3859 .disabled = false,
3860 .interactive = true,
3861 .expected_success_status= NT_STATUS_OK
3865 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3867 /* backup old policies */
3869 torture_assert(tctx,
3870 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3871 DomainPasswordInformation, &q_info),
3872 "failed to query domain info level 1");
3874 info1 = q_info->info1;
3875 _info1 = info1;
3877 torture_assert(tctx,
3878 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3879 DomainLockoutInformation, &q_info),
3880 "failed to query domain info level 12");
3882 info12 = q_info->info12;
3883 _info12 = info12;
3885 /* run tests */
3887 for (i=0; i < ARRAY_SIZE(creds); i++) {
3889 /* skip trust tests for now */
3890 if (acct_flags & ACB_WSTRUST ||
3891 acct_flags & ACB_SVRTRUST ||
3892 acct_flags & ACB_DOMTRUST) {
3893 continue;
3896 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3897 domain_handle, user_handle, password,
3898 machine_credentials,
3899 creds[i].comment,
3900 creds[i].disabled,
3901 creds[i].interactive,
3902 creds[i].expected_success_status,
3903 &_info1, &_info12);
3904 if (!ret) {
3905 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3906 } else {
3907 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3911 /* restore policies */
3913 s_info.info1 = info1;
3915 torture_assert(tctx,
3916 test_SetDomainInfo(b, tctx, domain_handle,
3917 DomainPasswordInformation, &s_info),
3918 "failed to set password information");
3920 s_info.info12 = info12;
3922 torture_assert(tctx,
3923 test_SetDomainInfo(b, tctx, domain_handle,
3924 DomainLockoutInformation, &s_info),
3925 "failed to set lockout information");
3927 return ret;
3930 static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3931 struct torture_context *tctx,
3932 struct policy_handle *handle,
3933 uint32_t *acct_flags)
3935 union samr_UserInfo *info;
3936 struct samr_QueryUserInfo r;
3938 r.in.user_handle = handle;
3939 r.in.level = 16;
3940 r.out.info = &info;
3942 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3944 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3945 "failed to query userinfo");
3946 torture_assert_ntstatus_ok(tctx, r.out.result,
3947 "failed to query userinfo");
3949 *acct_flags = info->info16.acct_flags;
3951 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3953 return true;
3956 static bool test_Password_lockout(struct dcerpc_pipe *p,
3957 struct dcerpc_pipe *np,
3958 struct torture_context *tctx,
3959 uint32_t acct_flags,
3960 const char *acct_name,
3961 struct policy_handle *domain_handle,
3962 struct policy_handle *user_handle,
3963 char **password,
3964 struct cli_credentials *machine_credentials,
3965 const char *comment,
3966 bool disable,
3967 bool interactive,
3968 NTSTATUS expected_success_status,
3969 struct samr_DomInfo1 *info1,
3970 struct samr_DomInfo12 *info12)
3972 union samr_DomainInfo info;
3973 uint32_t badpwdcount;
3974 uint32_t password_history_length = 1;
3975 uint64_t lockout_threshold = 1;
3976 uint32_t lockout_seconds = 5;
3977 uint64_t delta_time_factor = 10 * 1000 * 1000;
3978 struct dcerpc_binding_handle *b = p->binding_handle;
3980 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3982 /* set policies */
3984 info.info1 = *info1;
3986 torture_comment(tctx, "setting password history length.\n");
3987 info.info1.password_history_length = password_history_length;
3989 torture_assert(tctx,
3990 test_SetDomainInfo(b, tctx, domain_handle,
3991 DomainPasswordInformation, &info),
3992 "failed to set password history length");
3994 info.info12 = *info12;
3995 info.info12.lockout_threshold = lockout_threshold;
3997 /* set lockout duration < lockout window: should fail */
3998 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3999 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4001 torture_assert(tctx,
4002 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4003 DomainLockoutInformation, &info,
4004 NT_STATUS_INVALID_PARAMETER),
4005 "setting lockout duration < lockout window gave unexpected result");
4007 info.info12.lockout_duration = 0;
4008 info.info12.lockout_window = 0;
4010 torture_assert(tctx,
4011 test_SetDomainInfo(b, tctx, domain_handle,
4012 DomainLockoutInformation, &info),
4013 "failed to set lockout window and duration to 0");
4016 /* set lockout duration of 5 seconds */
4017 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4018 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4020 torture_assert(tctx,
4021 test_SetDomainInfo(b, tctx, domain_handle,
4022 DomainLockoutInformation, &info),
4023 "failed to set lockout window and duration to 5 seconds");
4025 /* reset bad pwd count */
4027 torture_assert(tctx,
4028 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4031 /* enable or disable account */
4033 if (disable) {
4034 torture_assert(tctx,
4035 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4036 acct_flags | ACB_DISABLED),
4037 "failed to disable user");
4038 } else {
4039 torture_assert(tctx,
4040 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4041 acct_flags & ~ACB_DISABLED),
4042 "failed to enable user");
4046 /* test logon with right password */
4048 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4049 acct_name, *password,
4050 expected_success_status, interactive)) {
4051 torture_fail(tctx, "failed to auth with latest password");
4054 torture_assert(tctx,
4055 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4056 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4059 /* test with wrong password ==> lockout */
4061 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4062 acct_name, "random_crap",
4063 NT_STATUS_WRONG_PASSWORD, interactive)) {
4064 torture_fail(tctx, "succeeded to authenticate with wrong password");
4067 torture_assert(tctx,
4068 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4069 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4071 torture_assert(tctx,
4072 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4073 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4074 "expected account to be locked");
4077 /* test with good password */
4079 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4080 *password,
4081 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4083 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4086 /* bad pwd count should not get updated */
4087 torture_assert(tctx,
4088 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4089 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4091 /* curiously, windows does _not_ set the autlock flag */
4092 torture_assert(tctx,
4093 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4094 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4095 "expected account to be locked");
4098 /* with bad password */
4100 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4101 acct_name, "random_crap2",
4102 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4104 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4107 /* bad pwd count should not get updated */
4108 torture_assert(tctx,
4109 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4110 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4112 /* curiously, windows does _not_ set the autlock flag */
4113 torture_assert(tctx,
4114 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4115 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4116 "expected account to be locked");
4119 /* let lockout duration expire ==> unlock */
4121 torture_comment(tctx, "let lockout duration expire...\n");
4122 sleep(lockout_seconds + 1);
4124 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4125 *password,
4126 expected_success_status, interactive))
4128 torture_fail(tctx, "failed to authenticate after lockout expired");
4131 torture_assert(tctx,
4132 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4133 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4134 "expected account not to be locked");
4136 return true;
4139 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4140 struct torture_context *tctx,
4141 uint32_t acct_flags,
4142 const char *acct_name,
4143 struct policy_handle *domain_handle,
4144 struct policy_handle *user_handle,
4145 char **password,
4146 struct cli_credentials *machine_credentials)
4148 union samr_DomainInfo *q_info, s_info;
4149 struct samr_DomInfo1 info1, _info1;
4150 struct samr_DomInfo12 info12, _info12;
4151 bool ret = true;
4152 struct dcerpc_binding_handle *b = p->binding_handle;
4153 struct dcerpc_pipe *np;
4154 int i;
4156 struct {
4157 const char *comment;
4158 bool disabled;
4159 bool interactive;
4160 NTSTATUS expected_success_status;
4161 } creds[] = {
4163 .comment = "network logon (disabled account)",
4164 .disabled = true,
4165 .interactive = false,
4166 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4169 .comment = "network logon (enabled account)",
4170 .disabled = false,
4171 .interactive = false,
4172 .expected_success_status= NT_STATUS_OK
4175 .comment = "interactive logon (disabled account)",
4176 .disabled = true,
4177 .interactive = true,
4178 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4181 .comment = "interactive logon (enabled account)",
4182 .disabled = false,
4183 .interactive = true,
4184 .expected_success_status= NT_STATUS_OK
4188 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4190 /* backup old policies */
4192 torture_assert(tctx,
4193 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4194 DomainPasswordInformation, &q_info),
4195 "failed to query domain info level 1");
4197 info1 = q_info->info1;
4198 _info1 = info1;
4200 torture_assert(tctx,
4201 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4202 DomainLockoutInformation, &q_info),
4203 "failed to query domain info level 12");
4205 info12 = q_info->info12;
4206 _info12 = info12;
4208 /* run tests */
4210 for (i=0; i < ARRAY_SIZE(creds); i++) {
4212 /* skip trust tests for now */
4213 if (acct_flags & ACB_WSTRUST ||
4214 acct_flags & ACB_SVRTRUST ||
4215 acct_flags & ACB_DOMTRUST) {
4216 continue;
4219 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4220 domain_handle, user_handle, password,
4221 machine_credentials,
4222 creds[i].comment,
4223 creds[i].disabled,
4224 creds[i].interactive,
4225 creds[i].expected_success_status,
4226 &_info1, &_info12);
4227 if (!ret) {
4228 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4229 } else {
4230 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4234 /* restore policies */
4236 s_info.info1 = info1;
4238 torture_assert(tctx,
4239 test_SetDomainInfo(b, tctx, domain_handle,
4240 DomainPasswordInformation, &s_info),
4241 "failed to set password information");
4243 s_info.info12 = info12;
4245 torture_assert(tctx,
4246 test_SetDomainInfo(b, tctx, domain_handle,
4247 DomainLockoutInformation, &s_info),
4248 "failed to set lockout information");
4250 return ret;
4253 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4254 struct dcerpc_pipe *lp,
4255 struct torture_context *tctx,
4256 struct policy_handle *domain_handle,
4257 struct policy_handle *lsa_handle,
4258 struct policy_handle *user_handle,
4259 const struct dom_sid *domain_sid,
4260 uint32_t rid,
4261 struct cli_credentials *machine_credentials)
4263 bool ret = true;
4264 struct dcerpc_binding_handle *b = p->binding_handle;
4265 struct dcerpc_binding_handle *lb = lp->binding_handle;
4267 struct policy_handle lsa_acct_handle;
4268 struct dom_sid *user_sid;
4270 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4273 struct lsa_EnumAccountRights r;
4274 struct lsa_RightSet rights;
4276 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4278 r.in.handle = lsa_handle;
4279 r.in.sid = user_sid;
4280 r.out.rights = &rights;
4282 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4283 "lsa_EnumAccountRights failed");
4284 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4285 "Expected enum rights for account to fail");
4289 struct lsa_RightSet rights;
4290 struct lsa_StringLarge names[2];
4291 struct lsa_AddAccountRights r;
4293 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4295 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4296 init_lsa_StringLarge(&names[1], NULL);
4298 rights.count = 1;
4299 rights.names = names;
4301 r.in.handle = lsa_handle;
4302 r.in.sid = user_sid;
4303 r.in.rights = &rights;
4305 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4306 "lsa_AddAccountRights failed");
4307 torture_assert_ntstatus_ok(tctx, r.out.result,
4308 "Failed to add privileges");
4312 struct lsa_EnumAccounts r;
4313 uint32_t resume_handle = 0;
4314 struct lsa_SidArray lsa_sid_array;
4315 int i;
4316 bool found_sid = false;
4318 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4320 r.in.handle = lsa_handle;
4321 r.in.num_entries = 0x1000;
4322 r.in.resume_handle = &resume_handle;
4323 r.out.sids = &lsa_sid_array;
4324 r.out.resume_handle = &resume_handle;
4326 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4327 "lsa_EnumAccounts failed");
4328 torture_assert_ntstatus_ok(tctx, r.out.result,
4329 "Failed to enum accounts");
4331 for (i=0; i < lsa_sid_array.num_sids; i++) {
4332 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4333 found_sid = true;
4337 torture_assert(tctx, found_sid,
4338 "failed to list privileged account");
4342 struct lsa_EnumAccountRights r;
4343 struct lsa_RightSet user_rights;
4345 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4347 r.in.handle = lsa_handle;
4348 r.in.sid = user_sid;
4349 r.out.rights = &user_rights;
4351 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4352 "lsa_EnumAccountRights failed");
4353 torture_assert_ntstatus_ok(tctx, r.out.result,
4354 "Failed to enum rights for account");
4356 if (user_rights.count < 1) {
4357 torture_warning(tctx, "failed to find newly added rights");
4358 return false;
4363 struct lsa_OpenAccount r;
4365 torture_comment(tctx, "Testing LSA OpenAccount\n");
4367 r.in.handle = lsa_handle;
4368 r.in.sid = user_sid;
4369 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4370 r.out.acct_handle = &lsa_acct_handle;
4372 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4373 "lsa_OpenAccount failed");
4374 torture_assert_ntstatus_ok(tctx, r.out.result,
4375 "Failed to open lsa account");
4379 struct lsa_GetSystemAccessAccount r;
4380 uint32_t access_mask;
4382 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4384 r.in.handle = &lsa_acct_handle;
4385 r.out.access_mask = &access_mask;
4387 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4388 "lsa_GetSystemAccessAccount failed");
4389 torture_assert_ntstatus_ok(tctx, r.out.result,
4390 "Failed to get lsa system access account");
4394 struct lsa_Close r;
4396 torture_comment(tctx, "Testing LSA Close\n");
4398 r.in.handle = &lsa_acct_handle;
4399 r.out.handle = &lsa_acct_handle;
4401 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4402 "lsa_Close failed");
4403 torture_assert_ntstatus_ok(tctx, r.out.result,
4404 "Failed to close lsa");
4408 struct samr_DeleteUser r;
4410 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4412 r.in.user_handle = user_handle;
4413 r.out.user_handle = user_handle;
4415 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4416 "DeleteUser failed");
4417 torture_assert_ntstatus_ok(tctx, r.out.result,
4418 "DeleteUser failed");
4422 struct lsa_EnumAccounts r;
4423 uint32_t resume_handle = 0;
4424 struct lsa_SidArray lsa_sid_array;
4425 int i;
4426 bool found_sid = false;
4428 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4430 r.in.handle = lsa_handle;
4431 r.in.num_entries = 0x1000;
4432 r.in.resume_handle = &resume_handle;
4433 r.out.sids = &lsa_sid_array;
4434 r.out.resume_handle = &resume_handle;
4436 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4437 "lsa_EnumAccounts failed");
4438 torture_assert_ntstatus_ok(tctx, r.out.result,
4439 "Failed to enum accounts");
4441 for (i=0; i < lsa_sid_array.num_sids; i++) {
4442 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4443 found_sid = true;
4447 torture_assert(tctx, found_sid,
4448 "failed to list privileged account");
4452 struct lsa_EnumAccountRights r;
4453 struct lsa_RightSet user_rights;
4455 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4457 r.in.handle = lsa_handle;
4458 r.in.sid = user_sid;
4459 r.out.rights = &user_rights;
4461 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4462 "lsa_EnumAccountRights failed");
4463 torture_assert_ntstatus_ok(tctx, r.out.result,
4464 "Failed to enum rights for account");
4466 if (user_rights.count < 1) {
4467 torture_warning(tctx, "failed to find newly added rights");
4468 return false;
4473 struct lsa_OpenAccount r;
4475 torture_comment(tctx, "Testing LSA OpenAccount\n");
4477 r.in.handle = lsa_handle;
4478 r.in.sid = user_sid;
4479 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4480 r.out.acct_handle = &lsa_acct_handle;
4482 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4483 "lsa_OpenAccount failed");
4484 torture_assert_ntstatus_ok(tctx, r.out.result,
4485 "Failed to open lsa account");
4489 struct lsa_GetSystemAccessAccount r;
4490 uint32_t access_mask;
4492 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4494 r.in.handle = &lsa_acct_handle;
4495 r.out.access_mask = &access_mask;
4497 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4498 "lsa_GetSystemAccessAccount failed");
4499 torture_assert_ntstatus_ok(tctx, r.out.result,
4500 "Failed to get lsa system access account");
4504 struct lsa_DeleteObject r;
4506 torture_comment(tctx, "Testing LSA DeleteObject\n");
4508 r.in.handle = &lsa_acct_handle;
4509 r.out.handle = &lsa_acct_handle;
4511 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4512 "lsa_DeleteObject failed");
4513 torture_assert_ntstatus_ok(tctx, r.out.result,
4514 "Failed to delete object");
4518 struct lsa_EnumAccounts r;
4519 uint32_t resume_handle = 0;
4520 struct lsa_SidArray lsa_sid_array;
4521 int i;
4522 bool found_sid = false;
4524 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4526 r.in.handle = lsa_handle;
4527 r.in.num_entries = 0x1000;
4528 r.in.resume_handle = &resume_handle;
4529 r.out.sids = &lsa_sid_array;
4530 r.out.resume_handle = &resume_handle;
4532 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4533 "lsa_EnumAccounts failed");
4534 torture_assert_ntstatus_ok(tctx, r.out.result,
4535 "Failed to enum accounts");
4537 for (i=0; i < lsa_sid_array.num_sids; i++) {
4538 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4539 found_sid = true;
4543 torture_assert(tctx, !found_sid,
4544 "should not have listed privileged account");
4548 struct lsa_EnumAccountRights r;
4549 struct lsa_RightSet user_rights;
4551 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4553 r.in.handle = lsa_handle;
4554 r.in.sid = user_sid;
4555 r.out.rights = &user_rights;
4557 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4558 "lsa_EnumAccountRights failed");
4559 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4560 "Failed to enum rights for account");
4563 return ret;
4566 static bool test_user_ops(struct dcerpc_pipe *p,
4567 struct torture_context *tctx,
4568 struct policy_handle *user_handle,
4569 struct policy_handle *domain_handle,
4570 const struct dom_sid *domain_sid,
4571 uint32_t base_acct_flags,
4572 const char *base_acct_name, enum torture_samr_choice which_ops,
4573 struct cli_credentials *machine_credentials)
4575 char *password = NULL;
4576 struct samr_QueryUserInfo q;
4577 union samr_UserInfo *info;
4578 NTSTATUS status;
4579 struct dcerpc_binding_handle *b = p->binding_handle;
4581 bool ret = true;
4582 int i;
4583 uint32_t rid;
4584 const uint32_t password_fields[] = {
4585 SAMR_FIELD_NT_PASSWORD_PRESENT,
4586 SAMR_FIELD_LM_PASSWORD_PRESENT,
4587 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4591 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4592 if (!NT_STATUS_IS_OK(status)) {
4593 ret = false;
4596 switch (which_ops) {
4597 case TORTURE_SAMR_USER_ATTRIBUTES:
4598 if (!test_QuerySecurity(b, tctx, user_handle)) {
4599 ret = false;
4602 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4603 ret = false;
4606 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4607 ret = false;
4610 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4611 base_acct_name)) {
4612 ret = false;
4615 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4616 ret = false;
4619 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4620 ret = false;
4623 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4624 ret = false;
4626 break;
4627 case TORTURE_SAMR_PASSWORDS:
4628 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4629 char simple_pass[9];
4630 char *v = generate_random_str(tctx, 1);
4632 ZERO_STRUCT(simple_pass);
4633 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4635 torture_comment(tctx, "Testing machine account password policy rules\n");
4637 /* Workstation trust accounts don't seem to need to honour password quality policy */
4638 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4639 ret = false;
4642 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4643 ret = false;
4646 /* reset again, to allow another 'user' password change */
4647 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4648 ret = false;
4651 /* Try a 'short' password */
4652 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4653 ret = false;
4656 /* Try a compleatly random password */
4657 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4658 ret = false;
4662 for (i = 0; password_fields[i]; i++) {
4663 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4664 ret = false;
4667 /* check it was set right */
4668 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4669 ret = false;
4673 for (i = 0; password_fields[i]; i++) {
4674 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4675 ret = false;
4678 /* check it was set right */
4679 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4680 ret = false;
4684 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4685 ret = false;
4688 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4689 ret = false;
4692 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4693 ret = false;
4696 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4697 ret = false;
4700 for (i = 0; password_fields[i]; i++) {
4702 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4703 /* we need to skip as that would break
4704 * the ChangePasswordUser3 verify */
4705 continue;
4708 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4709 ret = false;
4712 /* check it was set right */
4713 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4714 ret = false;
4718 q.in.user_handle = user_handle;
4719 q.in.level = 5;
4720 q.out.info = &info;
4722 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4723 "QueryUserInfo failed");
4724 if (!NT_STATUS_IS_OK(q.out.result)) {
4725 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4726 q.in.level, nt_errstr(q.out.result));
4727 ret = false;
4728 } else {
4729 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4730 if ((info->info5.acct_flags) != expected_flags) {
4731 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4732 info->info5.acct_flags,
4733 expected_flags);
4734 /* FIXME: GD */
4735 if (!torture_setting_bool(tctx, "samba3", false)) {
4736 ret = false;
4739 if (info->info5.rid != rid) {
4740 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4741 info->info5.rid, rid);
4746 break;
4748 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4750 /* test last password change timestamp behaviour */
4751 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4752 base_acct_name,
4753 user_handle, &password,
4754 machine_credentials)) {
4755 ret = false;
4758 if (ret == true) {
4759 torture_comment(tctx, "pwdLastSet test succeeded\n");
4760 } else {
4761 torture_warning(tctx, "pwdLastSet test failed\n");
4764 break;
4766 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4768 /* test bad pwd count change behaviour */
4769 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4770 base_acct_name,
4771 domain_handle,
4772 user_handle, &password,
4773 machine_credentials)) {
4774 ret = false;
4777 if (ret == true) {
4778 torture_comment(tctx, "badPwdCount test succeeded\n");
4779 } else {
4780 torture_warning(tctx, "badPwdCount test failed\n");
4783 break;
4785 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4787 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4788 base_acct_name,
4789 domain_handle,
4790 user_handle, &password,
4791 machine_credentials))
4793 ret = false;
4796 if (ret == true) {
4797 torture_comment(tctx, "lockout test succeeded\n");
4798 } else {
4799 torture_warning(tctx, "lockout test failed\n");
4802 break;
4805 case TORTURE_SAMR_USER_PRIVILEGES: {
4807 struct dcerpc_pipe *lp;
4808 struct policy_handle *lsa_handle;
4809 struct dcerpc_binding_handle *lb;
4811 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4812 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4813 lb = lp->binding_handle;
4815 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4816 ret = false;
4819 if (!test_DeleteUser_with_privs(p, lp, tctx,
4820 domain_handle, lsa_handle, user_handle,
4821 domain_sid, rid,
4822 machine_credentials)) {
4823 ret = false;
4826 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4827 ret = false;
4830 if (!ret) {
4831 torture_warning(tctx, "privileged user delete test failed\n");
4834 break;
4836 case TORTURE_SAMR_OTHER:
4837 case TORTURE_SAMR_MANY_ACCOUNTS:
4838 case TORTURE_SAMR_MANY_GROUPS:
4839 case TORTURE_SAMR_MANY_ALIASES:
4840 /* We just need the account to exist */
4841 break;
4843 return ret;
4846 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4847 struct torture_context *tctx,
4848 struct policy_handle *alias_handle,
4849 const struct dom_sid *domain_sid)
4851 bool ret = true;
4853 if (!torture_setting_bool(tctx, "samba3", false)) {
4854 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4855 ret = false;
4859 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4860 ret = false;
4863 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4864 ret = false;
4867 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4868 ret = false;
4871 if (torture_setting_bool(tctx, "samba3", false) ||
4872 torture_setting_bool(tctx, "samba4", false)) {
4873 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4874 return ret;
4877 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
4878 ret = false;
4881 return ret;
4885 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
4886 struct torture_context *tctx,
4887 struct policy_handle *user_handle)
4889 struct samr_DeleteUser d;
4890 torture_comment(tctx, "Testing DeleteUser\n");
4892 d.in.user_handle = user_handle;
4893 d.out.user_handle = user_handle;
4895 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4896 "DeleteUser failed");
4897 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
4899 return true;
4902 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
4903 struct torture_context *tctx,
4904 struct policy_handle *handle, const char *name)
4906 NTSTATUS status;
4907 struct samr_DeleteUser d;
4908 struct policy_handle user_handle;
4909 uint32_t rid;
4911 status = test_LookupName(b, tctx, handle, name, &rid);
4912 if (!NT_STATUS_IS_OK(status)) {
4913 goto failed;
4916 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
4917 if (!NT_STATUS_IS_OK(status)) {
4918 goto failed;
4921 d.in.user_handle = &user_handle;
4922 d.out.user_handle = &user_handle;
4923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4924 "DeleteUser failed");
4925 if (!NT_STATUS_IS_OK(d.out.result)) {
4926 status = d.out.result;
4927 goto failed;
4930 return true;
4932 failed:
4933 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4934 return false;
4938 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
4939 struct torture_context *tctx,
4940 struct policy_handle *handle, const char *name)
4942 NTSTATUS status;
4943 struct samr_OpenGroup r;
4944 struct samr_DeleteDomainGroup d;
4945 struct policy_handle group_handle;
4946 uint32_t rid;
4948 status = test_LookupName(b, tctx, handle, name, &rid);
4949 if (!NT_STATUS_IS_OK(status)) {
4950 goto failed;
4953 r.in.domain_handle = handle;
4954 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4955 r.in.rid = rid;
4956 r.out.group_handle = &group_handle;
4957 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
4958 "OpenGroup failed");
4959 if (!NT_STATUS_IS_OK(r.out.result)) {
4960 status = r.out.result;
4961 goto failed;
4964 d.in.group_handle = &group_handle;
4965 d.out.group_handle = &group_handle;
4966 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
4967 "DeleteDomainGroup failed");
4968 if (!NT_STATUS_IS_OK(d.out.result)) {
4969 status = d.out.result;
4970 goto failed;
4973 return true;
4975 failed:
4976 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4977 return false;
4981 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
4982 struct torture_context *tctx,
4983 struct policy_handle *domain_handle,
4984 const char *name)
4986 NTSTATUS status;
4987 struct samr_OpenAlias r;
4988 struct samr_DeleteDomAlias d;
4989 struct policy_handle alias_handle;
4990 uint32_t rid;
4992 torture_comment(tctx, "Testing DeleteAlias_byname\n");
4994 status = test_LookupName(b, tctx, domain_handle, name, &rid);
4995 if (!NT_STATUS_IS_OK(status)) {
4996 goto failed;
4999 r.in.domain_handle = domain_handle;
5000 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5001 r.in.rid = rid;
5002 r.out.alias_handle = &alias_handle;
5003 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5004 "OpenAlias failed");
5005 if (!NT_STATUS_IS_OK(r.out.result)) {
5006 status = r.out.result;
5007 goto failed;
5010 d.in.alias_handle = &alias_handle;
5011 d.out.alias_handle = &alias_handle;
5012 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5013 "DeleteDomAlias failed");
5014 if (!NT_STATUS_IS_OK(d.out.result)) {
5015 status = d.out.result;
5016 goto failed;
5019 return true;
5021 failed:
5022 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5023 return false;
5026 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5027 struct torture_context *tctx,
5028 struct policy_handle *alias_handle)
5030 struct samr_DeleteDomAlias d;
5031 bool ret = true;
5033 torture_comment(tctx, "Testing DeleteAlias\n");
5035 d.in.alias_handle = alias_handle;
5036 d.out.alias_handle = alias_handle;
5038 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5039 "DeleteDomAlias failed");
5040 if (!NT_STATUS_IS_OK(d.out.result)) {
5041 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5042 ret = false;
5045 return ret;
5048 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5049 struct torture_context *tctx,
5050 struct policy_handle *domain_handle,
5051 const char *alias_name,
5052 struct policy_handle *alias_handle,
5053 const struct dom_sid *domain_sid,
5054 bool test_alias)
5056 struct samr_CreateDomAlias r;
5057 struct lsa_String name;
5058 uint32_t rid;
5059 bool ret = true;
5061 init_lsa_String(&name, alias_name);
5062 r.in.domain_handle = domain_handle;
5063 r.in.alias_name = &name;
5064 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5065 r.out.alias_handle = alias_handle;
5066 r.out.rid = &rid;
5068 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5070 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5071 "CreateDomAlias failed");
5073 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5074 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5075 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5076 return true;
5077 } else {
5078 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5079 nt_errstr(r.out.result));
5080 return false;
5084 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5085 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5086 return false;
5088 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5089 "CreateDomAlias failed");
5092 if (!NT_STATUS_IS_OK(r.out.result)) {
5093 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5094 return false;
5097 if (!test_alias) {
5098 return ret;
5101 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5102 ret = false;
5105 return ret;
5108 static bool test_ChangePassword(struct dcerpc_pipe *p,
5109 struct torture_context *tctx,
5110 const char *acct_name,
5111 struct policy_handle *domain_handle, char **password)
5113 bool ret = true;
5114 struct dcerpc_binding_handle *b = p->binding_handle;
5116 if (!*password) {
5117 return false;
5120 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5121 ret = false;
5124 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5125 ret = false;
5128 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5129 ret = false;
5132 /* test what happens when setting the old password again */
5133 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5134 ret = false;
5138 char simple_pass[9];
5139 char *v = generate_random_str(tctx, 1);
5141 ZERO_STRUCT(simple_pass);
5142 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5144 /* test what happens when picking a simple password */
5145 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5146 ret = false;
5150 /* set samr_SetDomainInfo level 1 with min_length 5 */
5152 struct samr_QueryDomainInfo r;
5153 union samr_DomainInfo *info = NULL;
5154 struct samr_SetDomainInfo s;
5155 uint16_t len_old, len;
5156 uint32_t pwd_prop_old;
5157 int64_t min_pwd_age_old;
5159 len = 5;
5161 r.in.domain_handle = domain_handle;
5162 r.in.level = 1;
5163 r.out.info = &info;
5165 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5166 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5167 "QueryDomainInfo failed");
5168 if (!NT_STATUS_IS_OK(r.out.result)) {
5169 return false;
5172 s.in.domain_handle = domain_handle;
5173 s.in.level = 1;
5174 s.in.info = info;
5176 /* remember the old min length, so we can reset it */
5177 len_old = s.in.info->info1.min_password_length;
5178 s.in.info->info1.min_password_length = len;
5179 pwd_prop_old = s.in.info->info1.password_properties;
5180 /* turn off password complexity checks for this test */
5181 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5183 min_pwd_age_old = s.in.info->info1.min_password_age;
5184 s.in.info->info1.min_password_age = 0;
5186 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5187 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5188 "SetDomainInfo failed");
5189 if (!NT_STATUS_IS_OK(s.out.result)) {
5190 return false;
5193 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5195 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5196 ret = false;
5199 s.in.info->info1.min_password_length = len_old;
5200 s.in.info->info1.password_properties = pwd_prop_old;
5201 s.in.info->info1.min_password_age = min_pwd_age_old;
5203 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5204 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5205 "SetDomainInfo failed");
5206 if (!NT_STATUS_IS_OK(s.out.result)) {
5207 return false;
5213 struct samr_OpenUser r;
5214 struct samr_QueryUserInfo q;
5215 union samr_UserInfo *info;
5216 struct samr_LookupNames n;
5217 struct policy_handle user_handle;
5218 struct samr_Ids rids, types;
5220 n.in.domain_handle = domain_handle;
5221 n.in.num_names = 1;
5222 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5223 n.in.names[0].string = acct_name;
5224 n.out.rids = &rids;
5225 n.out.types = &types;
5227 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5228 "LookupNames failed");
5229 if (!NT_STATUS_IS_OK(n.out.result)) {
5230 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5231 return false;
5234 r.in.domain_handle = domain_handle;
5235 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5236 r.in.rid = n.out.rids->ids[0];
5237 r.out.user_handle = &user_handle;
5239 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5240 "OpenUser failed");
5241 if (!NT_STATUS_IS_OK(r.out.result)) {
5242 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5243 return false;
5246 q.in.user_handle = &user_handle;
5247 q.in.level = 5;
5248 q.out.info = &info;
5250 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5251 "QueryUserInfo failed");
5252 if (!NT_STATUS_IS_OK(q.out.result)) {
5253 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5254 return false;
5257 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5259 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5260 info->info5.last_password_change, true)) {
5261 ret = false;
5265 /* we change passwords twice - this has the effect of verifying
5266 they were changed correctly for the final call */
5267 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5268 ret = false;
5271 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5272 ret = false;
5275 return ret;
5278 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5279 struct policy_handle *domain_handle,
5280 const char *user_name,
5281 struct policy_handle *user_handle_out,
5282 struct dom_sid *domain_sid,
5283 enum torture_samr_choice which_ops,
5284 struct cli_credentials *machine_credentials,
5285 bool test_user)
5288 TALLOC_CTX *user_ctx;
5290 struct samr_CreateUser r;
5291 struct samr_QueryUserInfo q;
5292 union samr_UserInfo *info;
5293 struct samr_DeleteUser d;
5294 uint32_t rid;
5296 /* This call creates a 'normal' account - check that it really does */
5297 const uint32_t acct_flags = ACB_NORMAL;
5298 struct lsa_String name;
5299 bool ret = true;
5300 struct dcerpc_binding_handle *b = p->binding_handle;
5302 struct policy_handle user_handle;
5303 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5304 init_lsa_String(&name, user_name);
5306 r.in.domain_handle = domain_handle;
5307 r.in.account_name = &name;
5308 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5309 r.out.user_handle = &user_handle;
5310 r.out.rid = &rid;
5312 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5314 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5315 "CreateUser failed");
5317 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5318 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5319 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5320 return true;
5321 } else {
5322 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5323 nt_errstr(r.out.result));
5324 return false;
5328 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5329 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5330 talloc_free(user_ctx);
5331 return false;
5333 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5334 "CreateUser failed");
5337 if (!NT_STATUS_IS_OK(r.out.result)) {
5338 talloc_free(user_ctx);
5339 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5340 return false;
5343 if (!test_user) {
5344 if (user_handle_out) {
5345 *user_handle_out = user_handle;
5347 return ret;
5351 q.in.user_handle = &user_handle;
5352 q.in.level = 16;
5353 q.out.info = &info;
5355 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5356 "QueryUserInfo failed");
5357 if (!NT_STATUS_IS_OK(q.out.result)) {
5358 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5359 q.in.level, nt_errstr(q.out.result));
5360 ret = false;
5361 } else {
5362 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5363 torture_warning(tctx, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5364 info->info16.acct_flags,
5365 acct_flags);
5366 ret = false;
5370 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5371 domain_sid, acct_flags, name.string, which_ops,
5372 machine_credentials)) {
5373 ret = false;
5376 if (user_handle_out) {
5377 *user_handle_out = user_handle;
5378 } else {
5379 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5381 d.in.user_handle = &user_handle;
5382 d.out.user_handle = &user_handle;
5384 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5385 "DeleteUser failed");
5386 if (!NT_STATUS_IS_OK(d.out.result)) {
5387 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5388 ret = false;
5394 talloc_free(user_ctx);
5396 return ret;
5400 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5401 struct policy_handle *domain_handle,
5402 struct dom_sid *domain_sid,
5403 enum torture_samr_choice which_ops,
5404 struct cli_credentials *machine_credentials)
5406 struct samr_CreateUser2 r;
5407 struct samr_QueryUserInfo q;
5408 union samr_UserInfo *info;
5409 struct samr_DeleteUser d;
5410 struct policy_handle user_handle;
5411 uint32_t rid;
5412 struct lsa_String name;
5413 bool ret = true;
5414 int i;
5415 struct dcerpc_binding_handle *b = p->binding_handle;
5417 struct {
5418 uint32_t acct_flags;
5419 const char *account_name;
5420 NTSTATUS nt_status;
5421 } account_types[] = {
5422 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5423 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5424 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5425 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5426 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5427 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5428 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5429 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5430 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5431 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5432 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5433 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5434 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5435 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5436 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5439 for (i = 0; account_types[i].account_name; i++) {
5440 TALLOC_CTX *user_ctx;
5441 uint32_t acct_flags = account_types[i].acct_flags;
5442 uint32_t access_granted;
5443 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5444 init_lsa_String(&name, account_types[i].account_name);
5446 r.in.domain_handle = domain_handle;
5447 r.in.account_name = &name;
5448 r.in.acct_flags = acct_flags;
5449 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5450 r.out.user_handle = &user_handle;
5451 r.out.access_granted = &access_granted;
5452 r.out.rid = &rid;
5454 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5456 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5457 "CreateUser2 failed");
5459 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5460 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5461 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5462 continue;
5463 } else {
5464 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5465 nt_errstr(r.out.result));
5466 ret = false;
5467 continue;
5471 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5472 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5473 talloc_free(user_ctx);
5474 ret = false;
5475 continue;
5477 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5478 "CreateUser2 failed");
5481 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5482 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5483 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5484 ret = false;
5487 if (NT_STATUS_IS_OK(r.out.result)) {
5488 q.in.user_handle = &user_handle;
5489 q.in.level = 5;
5490 q.out.info = &info;
5492 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5493 "QueryUserInfo failed");
5494 if (!NT_STATUS_IS_OK(q.out.result)) {
5495 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5496 q.in.level, nt_errstr(q.out.result));
5497 ret = false;
5498 } else {
5499 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5500 if (acct_flags == ACB_NORMAL) {
5501 expected_flags |= ACB_PW_EXPIRED;
5503 if ((info->info5.acct_flags) != expected_flags) {
5504 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5505 info->info5.acct_flags,
5506 expected_flags);
5507 ret = false;
5509 switch (acct_flags) {
5510 case ACB_SVRTRUST:
5511 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5512 torture_warning(tctx, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5513 DOMAIN_RID_DCS, info->info5.primary_gid);
5514 ret = false;
5516 break;
5517 case ACB_WSTRUST:
5518 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5519 torture_warning(tctx, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5520 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5521 ret = false;
5523 break;
5524 case ACB_NORMAL:
5525 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5526 torture_warning(tctx, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5527 DOMAIN_RID_USERS, info->info5.primary_gid);
5528 ret = false;
5530 break;
5534 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5535 domain_sid, acct_flags, name.string, which_ops,
5536 machine_credentials)) {
5537 ret = false;
5540 if (!ndr_policy_handle_empty(&user_handle)) {
5541 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5543 d.in.user_handle = &user_handle;
5544 d.out.user_handle = &user_handle;
5546 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5547 "DeleteUser failed");
5548 if (!NT_STATUS_IS_OK(d.out.result)) {
5549 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5550 ret = false;
5554 talloc_free(user_ctx);
5557 return ret;
5560 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5561 struct torture_context *tctx,
5562 struct policy_handle *handle)
5564 struct samr_QueryAliasInfo r;
5565 union samr_AliasInfo *info;
5566 uint16_t levels[] = {1, 2, 3};
5567 int i;
5568 bool ret = true;
5570 for (i=0;i<ARRAY_SIZE(levels);i++) {
5571 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5573 r.in.alias_handle = handle;
5574 r.in.level = levels[i];
5575 r.out.info = &info;
5577 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5578 "QueryAliasInfo failed");
5579 if (!NT_STATUS_IS_OK(r.out.result)) {
5580 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5581 levels[i], nt_errstr(r.out.result));
5582 ret = false;
5586 return ret;
5589 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5590 struct torture_context *tctx,
5591 struct policy_handle *handle)
5593 struct samr_QueryGroupInfo r;
5594 union samr_GroupInfo *info;
5595 uint16_t levels[] = {1, 2, 3, 4, 5};
5596 int i;
5597 bool ret = true;
5599 for (i=0;i<ARRAY_SIZE(levels);i++) {
5600 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5602 r.in.group_handle = handle;
5603 r.in.level = levels[i];
5604 r.out.info = &info;
5606 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5607 "QueryGroupInfo failed");
5608 if (!NT_STATUS_IS_OK(r.out.result)) {
5609 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5610 levels[i], nt_errstr(r.out.result));
5611 ret = false;
5615 return ret;
5618 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5619 struct torture_context *tctx,
5620 struct policy_handle *handle)
5622 struct samr_QueryGroupMember r;
5623 struct samr_RidAttrArray *rids = NULL;
5624 bool ret = true;
5626 torture_comment(tctx, "Testing QueryGroupMember\n");
5628 r.in.group_handle = handle;
5629 r.out.rids = &rids;
5631 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5632 "QueryGroupMember failed");
5633 if (!NT_STATUS_IS_OK(r.out.result)) {
5634 torture_warning(tctx, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
5635 ret = false;
5638 return ret;
5642 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5643 struct torture_context *tctx,
5644 struct policy_handle *handle)
5646 struct samr_QueryGroupInfo r;
5647 union samr_GroupInfo *info;
5648 struct samr_SetGroupInfo s;
5649 uint16_t levels[] = {1, 2, 3, 4};
5650 uint16_t set_ok[] = {0, 1, 1, 1};
5651 int i;
5652 bool ret = true;
5654 for (i=0;i<ARRAY_SIZE(levels);i++) {
5655 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5657 r.in.group_handle = handle;
5658 r.in.level = levels[i];
5659 r.out.info = &info;
5661 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5662 "QueryGroupInfo failed");
5663 if (!NT_STATUS_IS_OK(r.out.result)) {
5664 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5665 levels[i], nt_errstr(r.out.result));
5666 ret = false;
5669 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5671 s.in.group_handle = handle;
5672 s.in.level = levels[i];
5673 s.in.info = *r.out.info;
5675 #if 0
5676 /* disabled this, as it changes the name only from the point of view of samr,
5677 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5678 the name is still reserved, so creating the old name fails, but deleting by the old name
5679 also fails */
5680 if (s.in.level == 2) {
5681 init_lsa_String(&s.in.info->string, "NewName");
5683 #endif
5685 if (s.in.level == 4) {
5686 init_lsa_String(&s.in.info->description, "test description");
5689 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5690 "SetGroupInfo failed");
5691 if (set_ok[i]) {
5692 if (!NT_STATUS_IS_OK(s.out.result)) {
5693 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5694 r.in.level, nt_errstr(s.out.result));
5695 ret = false;
5696 continue;
5698 } else {
5699 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5700 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5701 r.in.level, nt_errstr(s.out.result));
5702 ret = false;
5703 continue;
5708 return ret;
5711 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5712 struct torture_context *tctx,
5713 struct policy_handle *handle)
5715 struct samr_QueryUserInfo r;
5716 union samr_UserInfo *info;
5717 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5718 11, 12, 13, 14, 16, 17, 20, 21};
5719 int i;
5720 bool ret = true;
5722 for (i=0;i<ARRAY_SIZE(levels);i++) {
5723 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5725 r.in.user_handle = handle;
5726 r.in.level = levels[i];
5727 r.out.info = &info;
5729 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5730 "QueryUserInfo failed");
5731 if (!NT_STATUS_IS_OK(r.out.result)) {
5732 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5733 levels[i], nt_errstr(r.out.result));
5734 ret = false;
5738 return ret;
5741 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5742 struct torture_context *tctx,
5743 struct policy_handle *handle)
5745 struct samr_QueryUserInfo2 r;
5746 union samr_UserInfo *info;
5747 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5748 11, 12, 13, 14, 16, 17, 20, 21};
5749 int i;
5750 bool ret = true;
5752 for (i=0;i<ARRAY_SIZE(levels);i++) {
5753 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5755 r.in.user_handle = handle;
5756 r.in.level = levels[i];
5757 r.out.info = &info;
5759 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5760 "QueryUserInfo2 failed");
5761 if (!NT_STATUS_IS_OK(r.out.result)) {
5762 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5763 levels[i], nt_errstr(r.out.result));
5764 ret = false;
5768 return ret;
5771 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5772 struct torture_context *tctx,
5773 struct policy_handle *handle, uint32_t rid)
5775 struct samr_OpenUser r;
5776 struct policy_handle user_handle;
5777 bool ret = true;
5779 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5781 r.in.domain_handle = handle;
5782 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5783 r.in.rid = rid;
5784 r.out.user_handle = &user_handle;
5786 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5787 "OpenUser failed");
5788 if (!NT_STATUS_IS_OK(r.out.result)) {
5789 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5790 return false;
5793 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5794 ret = false;
5797 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5798 ret = false;
5801 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5802 ret = false;
5805 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5806 ret = false;
5809 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5810 ret = false;
5813 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5814 ret = false;
5817 return ret;
5820 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5821 struct torture_context *tctx,
5822 struct policy_handle *handle, uint32_t rid)
5824 struct samr_OpenGroup r;
5825 struct policy_handle group_handle;
5826 bool ret = true;
5828 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5830 r.in.domain_handle = handle;
5831 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5832 r.in.rid = rid;
5833 r.out.group_handle = &group_handle;
5835 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5836 "OpenGroup failed");
5837 if (!NT_STATUS_IS_OK(r.out.result)) {
5838 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5839 return false;
5842 if (!torture_setting_bool(tctx, "samba3", false)) {
5843 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5844 ret = false;
5848 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5849 ret = false;
5852 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5853 ret = false;
5856 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5857 ret = false;
5860 return ret;
5863 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5864 struct torture_context *tctx,
5865 struct policy_handle *handle, uint32_t rid)
5867 struct samr_OpenAlias r;
5868 struct policy_handle alias_handle;
5869 bool ret = true;
5871 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5873 r.in.domain_handle = handle;
5874 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5875 r.in.rid = rid;
5876 r.out.alias_handle = &alias_handle;
5878 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5879 "OpenAlias failed");
5880 if (!NT_STATUS_IS_OK(r.out.result)) {
5881 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5882 return false;
5885 if (!torture_setting_bool(tctx, "samba3", false)) {
5886 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
5887 ret = false;
5891 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
5892 ret = false;
5895 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
5896 ret = false;
5899 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
5900 ret = false;
5903 return ret;
5906 static bool check_mask(struct dcerpc_binding_handle *b,
5907 struct torture_context *tctx,
5908 struct policy_handle *handle, uint32_t rid,
5909 uint32_t acct_flag_mask)
5911 struct samr_OpenUser r;
5912 struct samr_QueryUserInfo q;
5913 union samr_UserInfo *info;
5914 struct policy_handle user_handle;
5915 bool ret = true;
5917 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5919 r.in.domain_handle = handle;
5920 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5921 r.in.rid = rid;
5922 r.out.user_handle = &user_handle;
5924 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5925 "OpenUser failed");
5926 if (!NT_STATUS_IS_OK(r.out.result)) {
5927 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5928 return false;
5931 q.in.user_handle = &user_handle;
5932 q.in.level = 16;
5933 q.out.info = &info;
5935 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5936 "QueryUserInfo failed");
5937 if (!NT_STATUS_IS_OK(q.out.result)) {
5938 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5939 nt_errstr(q.out.result));
5940 ret = false;
5941 } else {
5942 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5943 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5944 acct_flag_mask, info->info16.acct_flags, rid);
5945 ret = false;
5949 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5950 ret = false;
5953 return ret;
5956 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
5957 struct torture_context *tctx,
5958 struct policy_handle *handle)
5960 struct samr_EnumDomainUsers r;
5961 uint32_t mask, resume_handle=0;
5962 int i, mask_idx;
5963 bool ret = true;
5964 struct samr_LookupNames n;
5965 struct samr_LookupRids lr ;
5966 struct lsa_Strings names;
5967 struct samr_Ids rids, types;
5968 struct samr_SamArray *sam = NULL;
5969 uint32_t num_entries = 0;
5971 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5972 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5973 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5974 ACB_PWNOEXP, 0};
5976 torture_comment(tctx, "Testing EnumDomainUsers\n");
5978 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5979 r.in.domain_handle = handle;
5980 r.in.resume_handle = &resume_handle;
5981 r.in.acct_flags = mask = masks[mask_idx];
5982 r.in.max_size = (uint32_t)-1;
5983 r.out.resume_handle = &resume_handle;
5984 r.out.num_entries = &num_entries;
5985 r.out.sam = &sam;
5987 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
5988 "EnumDomainUsers failed");
5989 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
5990 !NT_STATUS_IS_OK(r.out.result)) {
5991 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
5992 return false;
5995 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
5997 if (sam->count == 0) {
5998 continue;
6001 for (i=0;i<sam->count;i++) {
6002 if (mask) {
6003 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6004 ret = false;
6006 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6007 ret = false;
6012 torture_comment(tctx, "Testing LookupNames\n");
6013 n.in.domain_handle = handle;
6014 n.in.num_names = sam->count;
6015 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6016 n.out.rids = &rids;
6017 n.out.types = &types;
6018 for (i=0;i<sam->count;i++) {
6019 n.in.names[i].string = sam->entries[i].name.string;
6021 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6022 "LookupNames failed");
6023 if (!NT_STATUS_IS_OK(n.out.result)) {
6024 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6025 ret = false;
6029 torture_comment(tctx, "Testing LookupRids\n");
6030 lr.in.domain_handle = handle;
6031 lr.in.num_rids = sam->count;
6032 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6033 lr.out.names = &names;
6034 lr.out.types = &types;
6035 for (i=0;i<sam->count;i++) {
6036 lr.in.rids[i] = sam->entries[i].idx;
6038 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6039 "LookupRids failed");
6040 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6042 return ret;
6046 try blasting the server with a bunch of sync requests
6048 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6049 struct policy_handle *handle)
6051 struct samr_EnumDomainUsers r;
6052 uint32_t resume_handle=0;
6053 int i;
6054 #define ASYNC_COUNT 100
6055 struct tevent_req *req[ASYNC_COUNT];
6057 if (!torture_setting_bool(tctx, "dangerous", false)) {
6058 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6061 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6063 r.in.domain_handle = handle;
6064 r.in.resume_handle = &resume_handle;
6065 r.in.acct_flags = 0;
6066 r.in.max_size = (uint32_t)-1;
6067 r.out.resume_handle = &resume_handle;
6069 for (i=0;i<ASYNC_COUNT;i++) {
6070 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6073 for (i=0;i<ASYNC_COUNT;i++) {
6074 tevent_req_poll(req[i], tctx->ev);
6075 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6076 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6077 i, nt_errstr(r.out.result)));
6080 torture_comment(tctx, "%d async requests OK\n", i);
6082 return true;
6085 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6086 struct torture_context *tctx,
6087 struct policy_handle *handle)
6089 struct samr_EnumDomainGroups r;
6090 uint32_t resume_handle=0;
6091 struct samr_SamArray *sam = NULL;
6092 uint32_t num_entries = 0;
6093 int i;
6094 bool ret = true;
6095 bool universal_group_found = false;
6097 torture_comment(tctx, "Testing EnumDomainGroups\n");
6099 r.in.domain_handle = handle;
6100 r.in.resume_handle = &resume_handle;
6101 r.in.max_size = (uint32_t)-1;
6102 r.out.resume_handle = &resume_handle;
6103 r.out.num_entries = &num_entries;
6104 r.out.sam = &sam;
6106 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6107 "EnumDomainGroups failed");
6108 if (!NT_STATUS_IS_OK(r.out.result)) {
6109 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6110 return false;
6113 if (!sam) {
6114 return false;
6117 for (i=0;i<sam->count;i++) {
6118 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6119 ret = false;
6121 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6122 "Enterprise Admins") == 0)) {
6123 universal_group_found = true;
6127 /* when we are running this on s4 we should get back at least the
6128 * "Enterprise Admins" universal group. If we don't get a group entry
6129 * at all we probably are performing the test on the builtin domain.
6130 * So ignore this case. */
6131 if (torture_setting_bool(tctx, "samba4", false)) {
6132 if ((sam->count > 0) && (!universal_group_found)) {
6133 ret = false;
6137 return ret;
6140 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6141 struct torture_context *tctx,
6142 struct policy_handle *handle)
6144 struct samr_EnumDomainAliases r;
6145 uint32_t resume_handle=0;
6146 struct samr_SamArray *sam = NULL;
6147 uint32_t num_entries = 0;
6148 int i;
6149 bool ret = true;
6151 torture_comment(tctx, "Testing EnumDomainAliases\n");
6153 r.in.domain_handle = handle;
6154 r.in.resume_handle = &resume_handle;
6155 r.in.max_size = (uint32_t)-1;
6156 r.out.sam = &sam;
6157 r.out.num_entries = &num_entries;
6158 r.out.resume_handle = &resume_handle;
6160 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6161 "EnumDomainAliases failed");
6162 if (!NT_STATUS_IS_OK(r.out.result)) {
6163 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6164 return false;
6167 if (!sam) {
6168 return false;
6171 for (i=0;i<sam->count;i++) {
6172 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6173 ret = false;
6177 return ret;
6180 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6181 struct torture_context *tctx,
6182 struct policy_handle *handle)
6184 struct samr_GetDisplayEnumerationIndex r;
6185 bool ret = true;
6186 uint16_t levels[] = {1, 2, 3, 4, 5};
6187 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6188 struct lsa_String name;
6189 uint32_t idx = 0;
6190 int i;
6192 for (i=0;i<ARRAY_SIZE(levels);i++) {
6193 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6195 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6197 r.in.domain_handle = handle;
6198 r.in.level = levels[i];
6199 r.in.name = &name;
6200 r.out.idx = &idx;
6202 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6203 "GetDisplayEnumerationIndex failed");
6205 if (ok_lvl[i] &&
6206 !NT_STATUS_IS_OK(r.out.result) &&
6207 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6208 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6209 levels[i], nt_errstr(r.out.result));
6210 ret = false;
6213 init_lsa_String(&name, "zzzzzzzz");
6215 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6216 "GetDisplayEnumerationIndex failed");
6218 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6219 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6220 levels[i], nt_errstr(r.out.result));
6221 ret = false;
6225 return ret;
6228 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6229 struct torture_context *tctx,
6230 struct policy_handle *handle)
6232 struct samr_GetDisplayEnumerationIndex2 r;
6233 bool ret = true;
6234 uint16_t levels[] = {1, 2, 3, 4, 5};
6235 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6236 struct lsa_String name;
6237 uint32_t idx = 0;
6238 int i;
6240 for (i=0;i<ARRAY_SIZE(levels);i++) {
6241 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6243 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6245 r.in.domain_handle = handle;
6246 r.in.level = levels[i];
6247 r.in.name = &name;
6248 r.out.idx = &idx;
6250 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6251 "GetDisplayEnumerationIndex2 failed");
6252 if (ok_lvl[i] &&
6253 !NT_STATUS_IS_OK(r.out.result) &&
6254 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6255 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6256 levels[i], nt_errstr(r.out.result));
6257 ret = false;
6260 init_lsa_String(&name, "zzzzzzzz");
6262 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6263 "GetDisplayEnumerationIndex2 failed");
6264 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6265 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6266 levels[i], nt_errstr(r.out.result));
6267 ret = false;
6271 return ret;
6274 #define STRING_EQUAL_QUERY(s1, s2, user) \
6275 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6276 /* odd, but valid */ \
6277 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6278 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6279 #s1, user.string, s1.string, s2.string, __location__); \
6280 ret = false; \
6282 #define INT_EQUAL_QUERY(s1, s2, user) \
6283 if (s1 != s2) { \
6284 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6285 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6286 ret = false; \
6289 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6290 struct torture_context *tctx,
6291 struct samr_QueryDisplayInfo *querydisplayinfo,
6292 bool *seen_testuser)
6294 struct samr_OpenUser r;
6295 struct samr_QueryUserInfo q;
6296 union samr_UserInfo *info;
6297 struct policy_handle user_handle;
6298 int i, ret = true;
6299 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6300 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6301 for (i = 0; ; i++) {
6302 switch (querydisplayinfo->in.level) {
6303 case 1:
6304 if (i >= querydisplayinfo->out.info->info1.count) {
6305 return ret;
6307 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6308 break;
6309 case 2:
6310 if (i >= querydisplayinfo->out.info->info2.count) {
6311 return ret;
6313 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6314 break;
6315 case 3:
6316 /* Groups */
6317 case 4:
6318 case 5:
6319 /* Not interested in validating just the account name */
6320 return true;
6323 r.out.user_handle = &user_handle;
6325 switch (querydisplayinfo->in.level) {
6326 case 1:
6327 case 2:
6328 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6329 "OpenUser failed");
6330 if (!NT_STATUS_IS_OK(r.out.result)) {
6331 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6332 return false;
6336 q.in.user_handle = &user_handle;
6337 q.in.level = 21;
6338 q.out.info = &info;
6339 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6340 "QueryUserInfo failed");
6341 if (!NT_STATUS_IS_OK(r.out.result)) {
6342 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6343 return false;
6346 switch (querydisplayinfo->in.level) {
6347 case 1:
6348 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6349 *seen_testuser = true;
6351 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6352 info->info21.full_name, info->info21.account_name);
6353 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6354 info->info21.account_name, info->info21.account_name);
6355 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6356 info->info21.description, info->info21.account_name);
6357 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6358 info->info21.rid, info->info21.account_name);
6359 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6360 info->info21.acct_flags, info->info21.account_name);
6362 break;
6363 case 2:
6364 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6365 info->info21.account_name, info->info21.account_name);
6366 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6367 info->info21.description, info->info21.account_name);
6368 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6369 info->info21.rid, info->info21.account_name);
6370 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6371 info->info21.acct_flags, info->info21.account_name);
6373 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6374 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6375 info->info21.account_name.string);
6378 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6379 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6380 info->info21.account_name.string,
6381 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6382 info->info21.acct_flags);
6383 return false;
6386 break;
6389 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6390 return false;
6393 return ret;
6396 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6397 struct torture_context *tctx,
6398 struct policy_handle *handle)
6400 struct samr_QueryDisplayInfo r;
6401 struct samr_QueryDomainInfo dom_info;
6402 union samr_DomainInfo *info = NULL;
6403 bool ret = true;
6404 uint16_t levels[] = {1, 2, 3, 4, 5};
6405 int i;
6406 bool seen_testuser = false;
6407 uint32_t total_size;
6408 uint32_t returned_size;
6409 union samr_DispInfo disp_info;
6412 for (i=0;i<ARRAY_SIZE(levels);i++) {
6413 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6415 r.in.start_idx = 0;
6416 r.out.result = STATUS_MORE_ENTRIES;
6417 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6418 r.in.domain_handle = handle;
6419 r.in.level = levels[i];
6420 r.in.max_entries = 2;
6421 r.in.buf_size = (uint32_t)-1;
6422 r.out.total_size = &total_size;
6423 r.out.returned_size = &returned_size;
6424 r.out.info = &disp_info;
6426 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6427 "QueryDisplayInfo failed");
6428 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6429 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6430 levels[i], nt_errstr(r.out.result));
6431 ret = false;
6433 switch (r.in.level) {
6434 case 1:
6435 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6436 ret = false;
6438 r.in.start_idx += r.out.info->info1.count;
6439 break;
6440 case 2:
6441 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6442 ret = false;
6444 r.in.start_idx += r.out.info->info2.count;
6445 break;
6446 case 3:
6447 r.in.start_idx += r.out.info->info3.count;
6448 break;
6449 case 4:
6450 r.in.start_idx += r.out.info->info4.count;
6451 break;
6452 case 5:
6453 r.in.start_idx += r.out.info->info5.count;
6454 break;
6457 dom_info.in.domain_handle = handle;
6458 dom_info.in.level = 2;
6459 dom_info.out.info = &info;
6461 /* Check number of users returned is correct */
6462 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6463 "QueryDomainInfo failed");
6464 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6465 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6466 r.in.level, nt_errstr(dom_info.out.result));
6467 ret = false;
6468 break;
6470 switch (r.in.level) {
6471 case 1:
6472 case 4:
6473 if (info->general.num_users < r.in.start_idx) {
6474 /* On AD deployments this numbers don't match
6475 * since QueryDisplayInfo returns universal and
6476 * global groups, QueryDomainInfo only global
6477 * ones. */
6478 if (torture_setting_bool(tctx, "samba3", false)) {
6479 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6480 r.in.start_idx, info->general.num_groups,
6481 info->general.domain_name.string);
6482 ret = false;
6485 if (!seen_testuser) {
6486 struct policy_handle user_handle;
6487 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6488 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6489 info->general.domain_name.string);
6490 ret = false;
6491 test_samr_handle_Close(b, tctx, &user_handle);
6494 break;
6495 case 3:
6496 case 5:
6497 if (info->general.num_groups != r.in.start_idx) {
6498 /* On AD deployments this numbers don't match
6499 * since QueryDisplayInfo returns universal and
6500 * global groups, QueryDomainInfo only global
6501 * ones. */
6502 if (torture_setting_bool(tctx, "samba3", false)) {
6503 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6504 r.in.start_idx, info->general.num_groups,
6505 info->general.domain_name.string);
6506 ret = false;
6510 break;
6515 return ret;
6518 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6519 struct torture_context *tctx,
6520 struct policy_handle *handle)
6522 struct samr_QueryDisplayInfo2 r;
6523 bool ret = true;
6524 uint16_t levels[] = {1, 2, 3, 4, 5};
6525 int i;
6526 uint32_t total_size;
6527 uint32_t returned_size;
6528 union samr_DispInfo info;
6530 for (i=0;i<ARRAY_SIZE(levels);i++) {
6531 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6533 r.in.domain_handle = handle;
6534 r.in.level = levels[i];
6535 r.in.start_idx = 0;
6536 r.in.max_entries = 1000;
6537 r.in.buf_size = (uint32_t)-1;
6538 r.out.total_size = &total_size;
6539 r.out.returned_size = &returned_size;
6540 r.out.info = &info;
6542 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6543 "QueryDisplayInfo2 failed");
6544 if (!NT_STATUS_IS_OK(r.out.result)) {
6545 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6546 levels[i], nt_errstr(r.out.result));
6547 ret = false;
6551 return ret;
6554 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6555 struct torture_context *tctx,
6556 struct policy_handle *handle)
6558 struct samr_QueryDisplayInfo3 r;
6559 bool ret = true;
6560 uint16_t levels[] = {1, 2, 3, 4, 5};
6561 int i;
6562 uint32_t total_size;
6563 uint32_t returned_size;
6564 union samr_DispInfo info;
6566 for (i=0;i<ARRAY_SIZE(levels);i++) {
6567 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6569 r.in.domain_handle = handle;
6570 r.in.level = levels[i];
6571 r.in.start_idx = 0;
6572 r.in.max_entries = 1000;
6573 r.in.buf_size = (uint32_t)-1;
6574 r.out.total_size = &total_size;
6575 r.out.returned_size = &returned_size;
6576 r.out.info = &info;
6578 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6579 "QueryDisplayInfo3 failed");
6580 if (!NT_STATUS_IS_OK(r.out.result)) {
6581 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6582 levels[i], nt_errstr(r.out.result));
6583 ret = false;
6587 return ret;
6591 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6592 struct torture_context *tctx,
6593 struct policy_handle *handle)
6595 struct samr_QueryDisplayInfo r;
6596 bool ret = true;
6597 uint32_t total_size;
6598 uint32_t returned_size;
6599 union samr_DispInfo info;
6601 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6603 r.in.domain_handle = handle;
6604 r.in.level = 1;
6605 r.in.start_idx = 0;
6606 r.in.max_entries = 1;
6607 r.in.buf_size = (uint32_t)-1;
6608 r.out.total_size = &total_size;
6609 r.out.returned_size = &returned_size;
6610 r.out.info = &info;
6612 do {
6613 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6614 "QueryDisplayInfo failed");
6615 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6616 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6617 torture_warning(tctx, "expected idx %d but got %d\n",
6618 r.in.start_idx + 1,
6619 r.out.info->info1.entries[0].idx);
6620 break;
6623 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6624 !NT_STATUS_IS_OK(r.out.result)) {
6625 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6626 r.in.level, nt_errstr(r.out.result));
6627 ret = false;
6628 break;
6630 r.in.start_idx++;
6631 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6632 NT_STATUS_IS_OK(r.out.result)) &&
6633 *r.out.returned_size != 0);
6635 return ret;
6638 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6639 struct torture_context *tctx,
6640 struct policy_handle *handle)
6642 struct samr_QueryDomainInfo r;
6643 union samr_DomainInfo *info = NULL;
6644 struct samr_SetDomainInfo s;
6645 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6646 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6647 int i;
6648 bool ret = true;
6649 struct dcerpc_binding_handle *b = p->binding_handle;
6650 const char *domain_comment = talloc_asprintf(tctx,
6651 "Tortured by Samba4 RPC-SAMR: %s",
6652 timestring(tctx, time(NULL)));
6654 s.in.domain_handle = handle;
6655 s.in.level = 4;
6656 s.in.info = talloc(tctx, union samr_DomainInfo);
6658 s.in.info->oem.oem_information.string = domain_comment;
6659 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6660 "SetDomainInfo failed");
6661 if (!NT_STATUS_IS_OK(s.out.result)) {
6662 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6663 s.in.level, nt_errstr(s.out.result));
6664 return false;
6667 for (i=0;i<ARRAY_SIZE(levels);i++) {
6668 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6670 r.in.domain_handle = handle;
6671 r.in.level = levels[i];
6672 r.out.info = &info;
6674 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6675 "QueryDomainInfo failed");
6676 if (!NT_STATUS_IS_OK(r.out.result)) {
6677 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6678 r.in.level, nt_errstr(r.out.result));
6679 ret = false;
6680 continue;
6683 switch (levels[i]) {
6684 case 2:
6685 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6686 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6687 levels[i], info->general.oem_information.string, domain_comment);
6688 if (!torture_setting_bool(tctx, "samba3", false)) {
6689 ret = false;
6692 if (!info->general.primary.string) {
6693 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6694 levels[i]);
6695 ret = false;
6696 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6697 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6698 if (torture_setting_bool(tctx, "samba3", false)) {
6699 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6700 levels[i], info->general.primary.string, dcerpc_server_name(p));
6704 break;
6705 case 4:
6706 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6707 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6708 levels[i], info->oem.oem_information.string, domain_comment);
6709 if (!torture_setting_bool(tctx, "samba3", false)) {
6710 ret = false;
6713 break;
6714 case 6:
6715 if (!info->info6.primary.string) {
6716 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6717 levels[i]);
6718 ret = false;
6720 break;
6721 case 11:
6722 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6723 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6724 levels[i], info->general2.general.oem_information.string, domain_comment);
6725 if (!torture_setting_bool(tctx, "samba3", false)) {
6726 ret = false;
6729 break;
6732 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6734 s.in.domain_handle = handle;
6735 s.in.level = levels[i];
6736 s.in.info = info;
6738 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6739 "SetDomainInfo failed");
6740 if (set_ok[i]) {
6741 if (!NT_STATUS_IS_OK(s.out.result)) {
6742 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6743 r.in.level, nt_errstr(s.out.result));
6744 ret = false;
6745 continue;
6747 } else {
6748 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6749 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6750 r.in.level, nt_errstr(s.out.result));
6751 ret = false;
6752 continue;
6756 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6757 "QueryDomainInfo failed");
6758 if (!NT_STATUS_IS_OK(r.out.result)) {
6759 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6760 r.in.level, nt_errstr(r.out.result));
6761 ret = false;
6762 continue;
6766 return ret;
6770 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6771 struct torture_context *tctx,
6772 struct policy_handle *handle)
6774 struct samr_QueryDomainInfo2 r;
6775 union samr_DomainInfo *info = NULL;
6776 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6777 int i;
6778 bool ret = true;
6780 for (i=0;i<ARRAY_SIZE(levels);i++) {
6781 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6783 r.in.domain_handle = handle;
6784 r.in.level = levels[i];
6785 r.out.info = &info;
6787 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6788 "QueryDomainInfo2 failed");
6789 if (!NT_STATUS_IS_OK(r.out.result)) {
6790 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6791 r.in.level, nt_errstr(r.out.result));
6792 ret = false;
6793 continue;
6797 return true;
6800 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6801 set of group names. */
6802 static bool test_GroupList(struct dcerpc_binding_handle *b,
6803 struct torture_context *tctx,
6804 struct dom_sid *domain_sid,
6805 struct policy_handle *handle)
6807 struct samr_EnumDomainGroups q1;
6808 struct samr_QueryDisplayInfo q2;
6809 NTSTATUS status;
6810 uint32_t resume_handle=0;
6811 struct samr_SamArray *sam = NULL;
6812 uint32_t num_entries = 0;
6813 int i;
6814 bool ret = true;
6815 uint32_t total_size;
6816 uint32_t returned_size;
6817 union samr_DispInfo info;
6819 int num_names = 0;
6820 const char **names = NULL;
6822 bool builtin_domain = dom_sid_compare(domain_sid,
6823 &global_sid_Builtin) == 0;
6825 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6827 q1.in.domain_handle = handle;
6828 q1.in.resume_handle = &resume_handle;
6829 q1.in.max_size = 5;
6830 q1.out.resume_handle = &resume_handle;
6831 q1.out.num_entries = &num_entries;
6832 q1.out.sam = &sam;
6834 status = STATUS_MORE_ENTRIES;
6835 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6836 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6837 "EnumDomainGroups failed");
6838 status = q1.out.result;
6840 if (!NT_STATUS_IS_OK(status) &&
6841 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6842 break;
6844 for (i=0; i<*q1.out.num_entries; i++) {
6845 add_string_to_array(tctx,
6846 sam->entries[i].name.string,
6847 &names, &num_names);
6851 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6853 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6855 if (builtin_domain) {
6856 torture_assert(tctx, num_names == 0,
6857 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6860 q2.in.domain_handle = handle;
6861 q2.in.level = 5;
6862 q2.in.start_idx = 0;
6863 q2.in.max_entries = 5;
6864 q2.in.buf_size = (uint32_t)-1;
6865 q2.out.total_size = &total_size;
6866 q2.out.returned_size = &returned_size;
6867 q2.out.info = &info;
6869 status = STATUS_MORE_ENTRIES;
6870 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6871 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6872 "QueryDisplayInfo failed");
6873 status = q2.out.result;
6874 if (!NT_STATUS_IS_OK(status) &&
6875 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6876 break;
6878 for (i=0; i<q2.out.info->info5.count; i++) {
6879 int j;
6880 const char *name = q2.out.info->info5.entries[i].account_name.string;
6881 bool found = false;
6882 for (j=0; j<num_names; j++) {
6883 if (names[j] == NULL)
6884 continue;
6885 if (strequal(names[j], name)) {
6886 names[j] = NULL;
6887 found = true;
6888 break;
6892 if ((!found) && (!builtin_domain)) {
6893 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6894 name);
6895 ret = false;
6898 q2.in.start_idx += q2.out.info->info5.count;
6901 if (!NT_STATUS_IS_OK(status)) {
6902 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6903 nt_errstr(status));
6904 ret = false;
6907 if (builtin_domain) {
6908 torture_assert(tctx, q2.in.start_idx != 0,
6909 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
6912 for (i=0; i<num_names; i++) {
6913 if (names[i] != NULL) {
6914 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6915 names[i]);
6916 ret = false;
6920 return ret;
6923 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
6924 struct torture_context *tctx,
6925 struct policy_handle *group_handle)
6927 struct samr_DeleteDomainGroup d;
6929 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6931 d.in.group_handle = group_handle;
6932 d.out.group_handle = group_handle;
6934 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
6935 "DeleteDomainGroup failed");
6936 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
6938 return true;
6941 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
6942 struct torture_context *tctx,
6943 struct policy_handle *domain_handle)
6945 struct samr_TestPrivateFunctionsDomain r;
6946 bool ret = true;
6948 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6950 r.in.domain_handle = domain_handle;
6952 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
6953 "TestPrivateFunctionsDomain failed");
6954 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6956 return ret;
6959 static bool test_RidToSid(struct dcerpc_binding_handle *b,
6960 struct torture_context *tctx,
6961 struct dom_sid *domain_sid,
6962 struct policy_handle *domain_handle)
6964 struct samr_RidToSid r;
6965 bool ret = true;
6966 struct dom_sid *calc_sid, *out_sid;
6967 int rids[] = { 0, 42, 512, 10200 };
6968 int i;
6970 for (i=0;i<ARRAY_SIZE(rids);i++) {
6971 torture_comment(tctx, "Testing RidToSid\n");
6973 calc_sid = dom_sid_dup(tctx, domain_sid);
6974 r.in.domain_handle = domain_handle;
6975 r.in.rid = rids[i];
6976 r.out.sid = &out_sid;
6978 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
6979 "RidToSid failed");
6980 if (!NT_STATUS_IS_OK(r.out.result)) {
6981 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
6982 ret = false;
6983 } else {
6984 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6986 if (!dom_sid_equal(calc_sid, out_sid)) {
6987 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6988 dom_sid_string(tctx, out_sid),
6989 dom_sid_string(tctx, calc_sid));
6990 ret = false;
6995 return ret;
6998 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
6999 struct torture_context *tctx,
7000 struct policy_handle *domain_handle)
7002 struct samr_GetBootKeyInformation r;
7003 bool ret = true;
7004 uint32_t unknown = 0;
7005 NTSTATUS status;
7007 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7009 r.in.domain_handle = domain_handle;
7010 r.out.unknown = &unknown;
7012 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7013 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7014 status = r.out.result;
7016 if (!NT_STATUS_IS_OK(status)) {
7017 /* w2k3 seems to fail this sometimes and pass it sometimes */
7018 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7021 return ret;
7024 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7025 struct torture_context *tctx,
7026 struct policy_handle *domain_handle,
7027 struct policy_handle *group_handle)
7029 NTSTATUS status;
7030 struct samr_AddGroupMember r;
7031 struct samr_DeleteGroupMember d;
7032 struct samr_QueryGroupMember q;
7033 struct samr_RidAttrArray *rids = NULL;
7034 struct samr_SetMemberAttributesOfGroup s;
7035 uint32_t rid;
7036 bool found_member = false;
7037 int i;
7039 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7040 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7042 r.in.group_handle = group_handle;
7043 r.in.rid = rid;
7044 r.in.flags = 0; /* ??? */
7046 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7048 d.in.group_handle = group_handle;
7049 d.in.rid = rid;
7051 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7052 "DeleteGroupMember failed");
7053 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7055 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7056 "AddGroupMember failed");
7057 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7059 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7060 "AddGroupMember failed");
7061 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7063 if (torture_setting_bool(tctx, "samba4", false) ||
7064 torture_setting_bool(tctx, "samba3", false)) {
7065 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7066 } else {
7067 /* this one is quite strange. I am using random inputs in the
7068 hope of triggering an error that might give us a clue */
7070 s.in.group_handle = group_handle;
7071 s.in.unknown1 = random();
7072 s.in.unknown2 = random();
7074 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7075 "SetMemberAttributesOfGroup failed");
7076 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7079 q.in.group_handle = group_handle;
7080 q.out.rids = &rids;
7082 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7083 "QueryGroupMember failed");
7084 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7085 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7087 for (i=0; i < rids->count; i++) {
7088 if (rids->rids[i] == rid) {
7089 found_member = true;
7093 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7095 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7096 "DeleteGroupMember failed");
7097 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7099 rids = NULL;
7100 found_member = false;
7102 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7103 "QueryGroupMember failed");
7104 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7105 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7107 for (i=0; i < rids->count; i++) {
7108 if (rids->rids[i] == rid) {
7109 found_member = true;
7113 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7115 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7116 "AddGroupMember failed");
7117 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7119 return true;
7123 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7124 struct torture_context *tctx,
7125 struct policy_handle *domain_handle,
7126 const char *group_name,
7127 struct policy_handle *group_handle,
7128 struct dom_sid *domain_sid,
7129 bool test_group)
7131 struct samr_CreateDomainGroup r;
7132 uint32_t rid;
7133 struct lsa_String name;
7134 bool ret = true;
7136 init_lsa_String(&name, group_name);
7138 r.in.domain_handle = domain_handle;
7139 r.in.name = &name;
7140 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7141 r.out.group_handle = group_handle;
7142 r.out.rid = &rid;
7144 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7146 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7147 "CreateDomainGroup failed");
7149 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7150 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7151 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7152 return true;
7153 } else {
7154 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7155 nt_errstr(r.out.result));
7156 return false;
7160 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7161 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7162 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7163 nt_errstr(r.out.result));
7164 return false;
7166 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7167 "CreateDomainGroup failed");
7169 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7170 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7172 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7173 nt_errstr(r.out.result));
7174 return false;
7176 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7177 "CreateDomainGroup failed");
7179 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7181 if (!test_group) {
7182 return ret;
7185 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7186 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7187 ret = false;
7190 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7191 ret = false;
7194 return ret;
7199 its not totally clear what this does. It seems to accept any sid you like.
7201 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7202 struct torture_context *tctx,
7203 struct policy_handle *domain_handle)
7205 struct samr_RemoveMemberFromForeignDomain r;
7207 r.in.domain_handle = domain_handle;
7208 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7210 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7211 "RemoveMemberFromForeignDomain failed");
7212 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7214 return true;
7217 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7218 struct torture_context *tctx,
7219 struct policy_handle *domain_handle,
7220 uint32_t *total_num_entries_p)
7222 NTSTATUS status;
7223 struct samr_EnumDomainUsers r;
7224 uint32_t resume_handle = 0;
7225 uint32_t num_entries = 0;
7226 uint32_t total_num_entries = 0;
7227 struct samr_SamArray *sam;
7229 r.in.domain_handle = domain_handle;
7230 r.in.acct_flags = 0;
7231 r.in.max_size = (uint32_t)-1;
7232 r.in.resume_handle = &resume_handle;
7234 r.out.sam = &sam;
7235 r.out.num_entries = &num_entries;
7236 r.out.resume_handle = &resume_handle;
7238 torture_comment(tctx, "Testing EnumDomainUsers\n");
7240 do {
7241 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7242 "EnumDomainUsers failed");
7243 if (NT_STATUS_IS_ERR(r.out.result)) {
7244 torture_assert_ntstatus_ok(tctx, r.out.result,
7245 "failed to enumerate users");
7247 status = r.out.result;
7249 total_num_entries += num_entries;
7250 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7252 if (total_num_entries_p) {
7253 *total_num_entries_p = total_num_entries;
7256 return true;
7259 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7260 struct torture_context *tctx,
7261 struct policy_handle *domain_handle,
7262 uint32_t *total_num_entries_p)
7264 NTSTATUS status;
7265 struct samr_EnumDomainGroups r;
7266 uint32_t resume_handle = 0;
7267 uint32_t num_entries = 0;
7268 uint32_t total_num_entries = 0;
7269 struct samr_SamArray *sam;
7271 r.in.domain_handle = domain_handle;
7272 r.in.max_size = (uint32_t)-1;
7273 r.in.resume_handle = &resume_handle;
7275 r.out.sam = &sam;
7276 r.out.num_entries = &num_entries;
7277 r.out.resume_handle = &resume_handle;
7279 torture_comment(tctx, "Testing EnumDomainGroups\n");
7281 do {
7282 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7283 "EnumDomainGroups failed");
7284 if (NT_STATUS_IS_ERR(r.out.result)) {
7285 torture_assert_ntstatus_ok(tctx, r.out.result,
7286 "failed to enumerate groups");
7288 status = r.out.result;
7290 total_num_entries += num_entries;
7291 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7293 if (total_num_entries_p) {
7294 *total_num_entries_p = total_num_entries;
7297 return true;
7300 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7301 struct torture_context *tctx,
7302 struct policy_handle *domain_handle,
7303 uint32_t *total_num_entries_p)
7305 NTSTATUS status;
7306 struct samr_EnumDomainAliases r;
7307 uint32_t resume_handle = 0;
7308 uint32_t num_entries = 0;
7309 uint32_t total_num_entries = 0;
7310 struct samr_SamArray *sam;
7312 r.in.domain_handle = domain_handle;
7313 r.in.max_size = (uint32_t)-1;
7314 r.in.resume_handle = &resume_handle;
7316 r.out.sam = &sam;
7317 r.out.num_entries = &num_entries;
7318 r.out.resume_handle = &resume_handle;
7320 torture_comment(tctx, "Testing EnumDomainAliases\n");
7322 do {
7323 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7324 "EnumDomainAliases failed");
7325 if (NT_STATUS_IS_ERR(r.out.result)) {
7326 torture_assert_ntstatus_ok(tctx, r.out.result,
7327 "failed to enumerate aliases");
7329 status = r.out.result;
7331 total_num_entries += num_entries;
7332 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7334 if (total_num_entries_p) {
7335 *total_num_entries_p = total_num_entries;
7338 return true;
7341 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7342 struct torture_context *tctx,
7343 struct policy_handle *handle,
7344 uint16_t level,
7345 uint32_t *total_num_entries_p)
7347 NTSTATUS status;
7348 struct samr_QueryDisplayInfo r;
7349 uint32_t total_num_entries = 0;
7351 r.in.domain_handle = handle;
7352 r.in.level = level;
7353 r.in.start_idx = 0;
7354 r.in.max_entries = (uint32_t)-1;
7355 r.in.buf_size = (uint32_t)-1;
7357 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7359 do {
7360 uint32_t total_size;
7361 uint32_t returned_size;
7362 union samr_DispInfo info;
7364 r.out.total_size = &total_size;
7365 r.out.returned_size = &returned_size;
7366 r.out.info = &info;
7368 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7369 "failed to query displayinfo");
7370 if (NT_STATUS_IS_ERR(r.out.result)) {
7371 torture_assert_ntstatus_ok(tctx, r.out.result,
7372 "failed to query displayinfo");
7374 status = r.out.result;
7376 if (*r.out.returned_size == 0) {
7377 break;
7380 switch (r.in.level) {
7381 case 1:
7382 total_num_entries += info.info1.count;
7383 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7384 break;
7385 case 2:
7386 total_num_entries += info.info2.count;
7387 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7388 break;
7389 case 3:
7390 total_num_entries += info.info3.count;
7391 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7392 break;
7393 case 4:
7394 total_num_entries += info.info4.count;
7395 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7396 break;
7397 case 5:
7398 total_num_entries += info.info5.count;
7399 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7400 break;
7401 default:
7402 return false;
7405 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7407 if (total_num_entries_p) {
7408 *total_num_entries_p = total_num_entries;
7411 return true;
7414 static bool test_ManyObjects(struct dcerpc_pipe *p,
7415 struct torture_context *tctx,
7416 struct policy_handle *domain_handle,
7417 struct dom_sid *domain_sid,
7418 struct torture_samr_context *ctx)
7420 uint32_t num_total = ctx->num_objects_large_dc;
7421 uint32_t num_enum = 0;
7422 uint32_t num_disp = 0;
7423 uint32_t num_created = 0;
7424 uint32_t num_anounced = 0;
7425 uint32_t i;
7426 struct dcerpc_binding_handle *b = p->binding_handle;
7428 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7430 /* query */
7433 struct samr_QueryDomainInfo2 r;
7434 union samr_DomainInfo *info;
7435 r.in.domain_handle = domain_handle;
7436 r.in.level = 2;
7437 r.out.info = &info;
7439 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7440 "QueryDomainInfo2 failed");
7441 torture_assert_ntstatus_ok(tctx, r.out.result,
7442 "failed to query domain info");
7444 switch (ctx->choice) {
7445 case TORTURE_SAMR_MANY_ACCOUNTS:
7446 num_anounced = info->general.num_users;
7447 break;
7448 case TORTURE_SAMR_MANY_GROUPS:
7449 num_anounced = info->general.num_groups;
7450 break;
7451 case TORTURE_SAMR_MANY_ALIASES:
7452 num_anounced = info->general.num_aliases;
7453 break;
7454 default:
7455 return false;
7459 /* create */
7461 for (i=0; i < num_total; i++) {
7463 const char *name = NULL;
7465 switch (ctx->choice) {
7466 case TORTURE_SAMR_MANY_ACCOUNTS:
7467 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7468 torture_assert(tctx,
7469 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7470 "failed to create user");
7471 break;
7472 case TORTURE_SAMR_MANY_GROUPS:
7473 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7474 torture_assert(tctx,
7475 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7476 "failed to create group");
7477 break;
7478 case TORTURE_SAMR_MANY_ALIASES:
7479 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7480 torture_assert(tctx,
7481 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7482 "failed to create alias");
7483 break;
7484 default:
7485 return false;
7487 if (!ndr_policy_handle_empty(&handles[i])) {
7488 num_created++;
7492 /* enum */
7494 switch (ctx->choice) {
7495 case TORTURE_SAMR_MANY_ACCOUNTS:
7496 torture_assert(tctx,
7497 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7498 "failed to enum users");
7499 break;
7500 case TORTURE_SAMR_MANY_GROUPS:
7501 torture_assert(tctx,
7502 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7503 "failed to enum groups");
7504 break;
7505 case TORTURE_SAMR_MANY_ALIASES:
7506 torture_assert(tctx,
7507 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7508 "failed to enum aliases");
7509 break;
7510 default:
7511 return false;
7514 /* dispinfo */
7516 switch (ctx->choice) {
7517 case TORTURE_SAMR_MANY_ACCOUNTS:
7518 torture_assert(tctx,
7519 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7520 "failed to query display info");
7521 break;
7522 case TORTURE_SAMR_MANY_GROUPS:
7523 torture_assert(tctx,
7524 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7525 "failed to query display info");
7526 break;
7527 case TORTURE_SAMR_MANY_ALIASES:
7528 /* no aliases in dispinfo */
7529 break;
7530 default:
7531 return false;
7534 /* close or delete */
7536 for (i=0; i < num_total; i++) {
7538 if (ndr_policy_handle_empty(&handles[i])) {
7539 continue;
7542 if (torture_setting_bool(tctx, "samba3", false)) {
7543 torture_assert(tctx,
7544 test_samr_handle_Close(b, tctx, &handles[i]),
7545 "failed to close handle");
7546 } else {
7547 switch (ctx->choice) {
7548 case TORTURE_SAMR_MANY_ACCOUNTS:
7549 torture_assert(tctx,
7550 test_DeleteUser(b, tctx, &handles[i]),
7551 "failed to delete user");
7552 break;
7553 case TORTURE_SAMR_MANY_GROUPS:
7554 torture_assert(tctx,
7555 test_DeleteDomainGroup(b, tctx, &handles[i]),
7556 "failed to delete group");
7557 break;
7558 case TORTURE_SAMR_MANY_ALIASES:
7559 torture_assert(tctx,
7560 test_DeleteAlias(b, tctx, &handles[i]),
7561 "failed to delete alias");
7562 break;
7563 default:
7564 return false;
7569 talloc_free(handles);
7571 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7572 torture_comment(tctx,
7573 "unexpected number of results (%u) returned in enum call, expected %u\n",
7574 num_enum, num_anounced + num_created);
7576 torture_comment(tctx,
7577 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7578 num_disp, num_anounced + num_created);
7581 return true;
7584 static bool test_Connect(struct dcerpc_binding_handle *b,
7585 struct torture_context *tctx,
7586 struct policy_handle *handle);
7588 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7589 struct torture_samr_context *ctx, struct dom_sid *sid)
7591 struct samr_OpenDomain r;
7592 struct policy_handle domain_handle;
7593 struct policy_handle alias_handle;
7594 struct policy_handle user_handle;
7595 struct policy_handle group_handle;
7596 bool ret = true;
7597 struct dcerpc_binding_handle *b = p->binding_handle;
7599 ZERO_STRUCT(alias_handle);
7600 ZERO_STRUCT(user_handle);
7601 ZERO_STRUCT(group_handle);
7602 ZERO_STRUCT(domain_handle);
7604 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7606 r.in.connect_handle = &ctx->handle;
7607 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7608 r.in.sid = sid;
7609 r.out.domain_handle = &domain_handle;
7611 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7612 "OpenDomain failed");
7613 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7615 /* run the domain tests with the main handle closed - this tests
7616 the servers reference counting */
7617 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7619 switch (ctx->choice) {
7620 case TORTURE_SAMR_PASSWORDS:
7621 case TORTURE_SAMR_USER_PRIVILEGES:
7622 if (!torture_setting_bool(tctx, "samba3", false)) {
7623 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7625 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7626 if (!ret) {
7627 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7629 break;
7630 case TORTURE_SAMR_USER_ATTRIBUTES:
7631 if (!torture_setting_bool(tctx, "samba3", false)) {
7632 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7634 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7635 /* This test needs 'complex' users to validate */
7636 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7637 if (!ret) {
7638 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7640 break;
7641 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7642 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7643 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7644 if (!torture_setting_bool(tctx, "samba3", false)) {
7645 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7647 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7648 if (!ret) {
7649 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7651 break;
7652 case TORTURE_SAMR_MANY_ACCOUNTS:
7653 case TORTURE_SAMR_MANY_GROUPS:
7654 case TORTURE_SAMR_MANY_ALIASES:
7655 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7656 if (!ret) {
7657 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7659 break;
7660 case TORTURE_SAMR_OTHER:
7661 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7662 if (!ret) {
7663 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7665 if (!torture_setting_bool(tctx, "samba3", false)) {
7666 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7668 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7669 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7670 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7671 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7672 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7673 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7674 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7675 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7676 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7677 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7678 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7679 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7680 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7682 if (torture_setting_bool(tctx, "samba4", false)) {
7683 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7684 } else {
7685 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7686 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7688 ret &= test_GroupList(b, tctx, sid, &domain_handle);
7689 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7690 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7691 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7692 if (!ret) {
7693 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7695 break;
7698 if (!ndr_policy_handle_empty(&user_handle) &&
7699 !test_DeleteUser(b, tctx, &user_handle)) {
7700 ret = false;
7703 if (!ndr_policy_handle_empty(&alias_handle) &&
7704 !test_DeleteAlias(b, tctx, &alias_handle)) {
7705 ret = false;
7708 if (!ndr_policy_handle_empty(&group_handle) &&
7709 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7710 ret = false;
7713 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7715 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7716 /* reconnect the main handle */
7718 if (!ret) {
7719 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7722 return ret;
7725 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7726 struct torture_samr_context *ctx, const char *domain)
7728 struct samr_LookupDomain r;
7729 struct dom_sid2 *sid = NULL;
7730 struct lsa_String n1;
7731 struct lsa_String n2;
7732 bool ret = true;
7733 struct dcerpc_binding_handle *b = p->binding_handle;
7735 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7737 /* check for correct error codes */
7738 r.in.connect_handle = &ctx->handle;
7739 r.in.domain_name = &n2;
7740 r.out.sid = &sid;
7741 n2.string = NULL;
7743 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7744 "LookupDomain failed");
7745 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7747 init_lsa_String(&n2, "xxNODOMAINxx");
7749 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7750 "LookupDomain failed");
7751 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7753 r.in.connect_handle = &ctx->handle;
7755 init_lsa_String(&n1, domain);
7756 r.in.domain_name = &n1;
7758 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7759 "LookupDomain failed");
7760 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7762 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7763 ret = false;
7766 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7767 ret = false;
7770 return ret;
7774 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7775 struct torture_samr_context *ctx)
7777 struct samr_EnumDomains r;
7778 uint32_t resume_handle = 0;
7779 uint32_t num_entries = 0;
7780 struct samr_SamArray *sam = NULL;
7781 int i;
7782 bool ret = true;
7783 struct dcerpc_binding_handle *b = p->binding_handle;
7785 r.in.connect_handle = &ctx->handle;
7786 r.in.resume_handle = &resume_handle;
7787 r.in.buf_size = (uint32_t)-1;
7788 r.out.resume_handle = &resume_handle;
7789 r.out.num_entries = &num_entries;
7790 r.out.sam = &sam;
7792 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7793 "EnumDomains failed");
7794 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7796 if (!*r.out.sam) {
7797 return false;
7800 for (i=0;i<sam->count;i++) {
7801 if (!test_LookupDomain(p, tctx, ctx,
7802 sam->entries[i].name.string)) {
7803 ret = false;
7807 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7808 "EnumDomains failed");
7809 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7811 return ret;
7815 static bool test_Connect(struct dcerpc_binding_handle *b,
7816 struct torture_context *tctx,
7817 struct policy_handle *handle)
7819 struct samr_Connect r;
7820 struct samr_Connect2 r2;
7821 struct samr_Connect3 r3;
7822 struct samr_Connect4 r4;
7823 struct samr_Connect5 r5;
7824 union samr_ConnectInfo info;
7825 struct policy_handle h;
7826 uint32_t level_out = 0;
7827 bool ret = true, got_handle = false;
7829 torture_comment(tctx, "Testing samr_Connect\n");
7831 r.in.system_name = NULL;
7832 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7833 r.out.connect_handle = &h;
7835 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7836 "Connect failed");
7837 if (!NT_STATUS_IS_OK(r.out.result)) {
7838 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7839 ret = false;
7840 } else {
7841 got_handle = true;
7842 *handle = h;
7845 torture_comment(tctx, "Testing samr_Connect2\n");
7847 r2.in.system_name = NULL;
7848 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7849 r2.out.connect_handle = &h;
7851 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7852 "Connect2 failed");
7853 if (!NT_STATUS_IS_OK(r2.out.result)) {
7854 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7855 ret = false;
7856 } else {
7857 if (got_handle) {
7858 test_samr_handle_Close(b, tctx, handle);
7860 got_handle = true;
7861 *handle = h;
7864 torture_comment(tctx, "Testing samr_Connect3\n");
7866 r3.in.system_name = NULL;
7867 r3.in.unknown = 0;
7868 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7869 r3.out.connect_handle = &h;
7871 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7872 "Connect3 failed");
7873 if (!NT_STATUS_IS_OK(r3.out.result)) {
7874 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
7875 ret = false;
7876 } else {
7877 if (got_handle) {
7878 test_samr_handle_Close(b, tctx, handle);
7880 got_handle = true;
7881 *handle = h;
7884 torture_comment(tctx, "Testing samr_Connect4\n");
7886 r4.in.system_name = "";
7887 r4.in.client_version = 0;
7888 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7889 r4.out.connect_handle = &h;
7891 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
7892 "Connect4 failed");
7893 if (!NT_STATUS_IS_OK(r4.out.result)) {
7894 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
7895 ret = false;
7896 } else {
7897 if (got_handle) {
7898 test_samr_handle_Close(b, tctx, handle);
7900 got_handle = true;
7901 *handle = h;
7904 torture_comment(tctx, "Testing samr_Connect5\n");
7906 info.info1.client_version = 0;
7907 info.info1.unknown2 = 0;
7909 r5.in.system_name = "";
7910 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7911 r5.in.level_in = 1;
7912 r5.out.level_out = &level_out;
7913 r5.in.info_in = &info;
7914 r5.out.info_out = &info;
7915 r5.out.connect_handle = &h;
7917 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
7918 "Connect5 failed");
7919 if (!NT_STATUS_IS_OK(r5.out.result)) {
7920 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
7921 ret = false;
7922 } else {
7923 if (got_handle) {
7924 test_samr_handle_Close(b, tctx, handle);
7926 got_handle = true;
7927 *handle = h;
7930 return ret;
7934 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p,
7935 struct torture_context *tctx)
7937 struct samr_ValidatePassword r;
7938 union samr_ValidatePasswordReq req;
7939 union samr_ValidatePasswordRep *repp = NULL;
7940 NTSTATUS status;
7941 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7942 int i;
7943 struct dcerpc_binding_handle *b = p->binding_handle;
7945 torture_comment(tctx, "Testing samr_ValidatePassword\n");
7947 ZERO_STRUCT(r);
7948 r.in.level = NetValidatePasswordReset;
7949 r.in.req = &req;
7950 r.out.rep = &repp;
7952 ZERO_STRUCT(req);
7953 req.req3.account.string = "non-existant-account-aklsdji";
7955 for (i=0; passwords[i]; i++) {
7956 req.req3.password.string = passwords[i];
7958 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
7959 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
7960 torture_skip(tctx, "ValidatePassword not supported by server\n");
7962 torture_assert_ntstatus_ok(tctx, status,
7963 "samr_ValidatePassword failed");
7964 torture_assert_ntstatus_ok(tctx, r.out.result,
7965 "samr_ValidatePassword failed");
7966 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7967 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7968 req.req3.password.string, repp->ctr3.status);
7971 return true;
7974 bool torture_rpc_samr(struct torture_context *torture)
7976 NTSTATUS status;
7977 struct dcerpc_pipe *p;
7978 bool ret = true;
7979 struct torture_samr_context *ctx;
7980 struct dcerpc_binding_handle *b;
7982 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7983 if (!NT_STATUS_IS_OK(status)) {
7984 return false;
7986 b = p->binding_handle;
7988 ctx = talloc_zero(torture, struct torture_samr_context);
7990 ctx->choice = TORTURE_SAMR_OTHER;
7992 ret &= test_Connect(b, torture, &ctx->handle);
7994 if (!torture_setting_bool(torture, "samba3", false)) {
7995 ret &= test_QuerySecurity(b, torture, &ctx->handle);
7998 ret &= test_EnumDomains(p, torture, ctx);
8000 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8002 ret &= test_Shutdown(b, torture, &ctx->handle);
8004 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8006 return ret;
8010 bool torture_rpc_samr_users(struct torture_context *torture)
8012 NTSTATUS status;
8013 struct dcerpc_pipe *p;
8014 bool ret = true;
8015 struct torture_samr_context *ctx;
8016 struct dcerpc_binding_handle *b;
8018 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8019 if (!NT_STATUS_IS_OK(status)) {
8020 return false;
8022 b = p->binding_handle;
8024 ctx = talloc_zero(torture, struct torture_samr_context);
8026 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8028 ret &= test_Connect(b, torture, &ctx->handle);
8030 if (!torture_setting_bool(torture, "samba3", false)) {
8031 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8034 ret &= test_EnumDomains(p, torture, ctx);
8036 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8038 ret &= test_Shutdown(b, torture, &ctx->handle);
8040 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8042 return ret;
8046 bool torture_rpc_samr_passwords(struct torture_context *torture)
8048 NTSTATUS status;
8049 struct dcerpc_pipe *p;
8050 bool ret = true;
8051 struct torture_samr_context *ctx;
8052 struct dcerpc_binding_handle *b;
8054 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8055 if (!NT_STATUS_IS_OK(status)) {
8056 return false;
8058 b = p->binding_handle;
8060 ctx = talloc_zero(torture, struct torture_samr_context);
8062 ctx->choice = TORTURE_SAMR_PASSWORDS;
8064 ret &= test_Connect(b, torture, &ctx->handle);
8066 ret &= test_EnumDomains(p, torture, ctx);
8068 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8070 ret &= test_samr_ValidatePassword(p, torture);
8072 return ret;
8075 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8076 struct dcerpc_pipe *p2,
8077 struct cli_credentials *machine_credentials)
8079 NTSTATUS status;
8080 struct dcerpc_pipe *p;
8081 bool ret = true;
8082 struct torture_samr_context *ctx;
8083 struct dcerpc_binding_handle *b;
8085 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8086 if (!NT_STATUS_IS_OK(status)) {
8087 return false;
8089 b = p->binding_handle;
8091 ctx = talloc_zero(torture, struct torture_samr_context);
8093 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8094 ctx->machine_credentials = machine_credentials;
8096 ret &= test_Connect(b, torture, &ctx->handle);
8098 ret &= test_EnumDomains(p, torture, ctx);
8100 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8102 return ret;
8105 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8107 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8108 struct torture_rpc_tcase *tcase;
8110 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8111 &ndr_table_samr,
8112 TEST_ACCOUNT_NAME_PWD);
8114 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8115 torture_rpc_samr_pwdlastset);
8117 return suite;
8120 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8121 struct dcerpc_pipe *p2,
8122 struct cli_credentials *machine_credentials)
8124 NTSTATUS status;
8125 struct dcerpc_pipe *p;
8126 bool ret = true;
8127 struct torture_samr_context *ctx;
8128 struct dcerpc_binding_handle *b;
8130 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8131 if (!NT_STATUS_IS_OK(status)) {
8132 return false;
8134 b = p->binding_handle;
8136 ctx = talloc_zero(torture, struct torture_samr_context);
8138 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8139 ctx->machine_credentials = machine_credentials;
8141 ret &= test_Connect(b, torture, &ctx->handle);
8143 ret &= test_EnumDomains(p, torture, ctx);
8145 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8147 return ret;
8150 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8152 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8153 struct torture_rpc_tcase *tcase;
8155 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8156 &ndr_table_samr,
8157 TEST_ACCOUNT_NAME_PWD);
8159 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8160 torture_rpc_samr_users_privileges_delete_user);
8162 return suite;
8165 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8166 struct dcerpc_pipe *p2,
8167 void *data)
8169 NTSTATUS status;
8170 struct dcerpc_pipe *p;
8171 bool ret = true;
8172 struct torture_samr_context *ctx =
8173 talloc_get_type_abort(data, struct torture_samr_context);
8174 struct dcerpc_binding_handle *b;
8176 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8177 if (!NT_STATUS_IS_OK(status)) {
8178 return false;
8180 b = p->binding_handle;
8182 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8183 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8184 ctx->num_objects_large_dc);
8186 ret &= test_Connect(b, torture, &ctx->handle);
8188 ret &= test_EnumDomains(p, torture, ctx);
8190 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8192 return ret;
8195 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8196 struct dcerpc_pipe *p2,
8197 void *data)
8199 NTSTATUS status;
8200 struct dcerpc_pipe *p;
8201 bool ret = true;
8202 struct torture_samr_context *ctx =
8203 talloc_get_type_abort(data, struct torture_samr_context);
8204 struct dcerpc_binding_handle *b;
8206 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8207 if (!NT_STATUS_IS_OK(status)) {
8208 return false;
8210 b = p->binding_handle;
8212 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8213 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8214 ctx->num_objects_large_dc);
8216 ret &= test_Connect(b, torture, &ctx->handle);
8218 ret &= test_EnumDomains(p, torture, ctx);
8220 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8222 return ret;
8225 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8226 struct dcerpc_pipe *p2,
8227 void *data)
8229 NTSTATUS status;
8230 struct dcerpc_pipe *p;
8231 bool ret = true;
8232 struct torture_samr_context *ctx =
8233 talloc_get_type_abort(data, struct torture_samr_context);
8234 struct dcerpc_binding_handle *b;
8236 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8237 if (!NT_STATUS_IS_OK(status)) {
8238 return false;
8240 b = p->binding_handle;
8242 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8243 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8244 ctx->num_objects_large_dc);
8246 ret &= test_Connect(b, torture, &ctx->handle);
8248 ret &= test_EnumDomains(p, torture, ctx);
8250 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8252 return ret;
8255 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8257 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8258 struct torture_rpc_tcase *tcase;
8259 struct torture_samr_context *ctx;
8261 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8263 ctx = talloc_zero(suite, struct torture_samr_context);
8264 ctx->num_objects_large_dc = 150;
8266 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8267 torture_rpc_samr_many_aliases, ctx);
8268 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8269 torture_rpc_samr_many_groups, ctx);
8270 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8271 torture_rpc_samr_many_accounts, ctx);
8273 return suite;
8276 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8277 struct dcerpc_pipe *p2,
8278 struct cli_credentials *machine_credentials)
8280 NTSTATUS status;
8281 struct dcerpc_pipe *p;
8282 bool ret = true;
8283 struct torture_samr_context *ctx;
8284 struct dcerpc_binding_handle *b;
8286 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8287 if (!NT_STATUS_IS_OK(status)) {
8288 return false;
8290 b = p->binding_handle;
8292 ctx = talloc_zero(torture, struct torture_samr_context);
8294 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8295 ctx->machine_credentials = machine_credentials;
8297 ret &= test_Connect(b, torture, &ctx->handle);
8299 ret &= test_EnumDomains(p, torture, ctx);
8301 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8303 return ret;
8306 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8308 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8309 struct torture_rpc_tcase *tcase;
8311 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8312 &ndr_table_samr,
8313 TEST_ACCOUNT_NAME_PWD);
8315 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8316 torture_rpc_samr_badpwdcount);
8318 return suite;
8321 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8322 struct dcerpc_pipe *p2,
8323 struct cli_credentials *machine_credentials)
8325 NTSTATUS status;
8326 struct dcerpc_pipe *p;
8327 bool ret = true;
8328 struct torture_samr_context *ctx;
8329 struct dcerpc_binding_handle *b;
8331 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8332 if (!NT_STATUS_IS_OK(status)) {
8333 return false;
8335 b = p->binding_handle;
8337 ctx = talloc_zero(torture, struct torture_samr_context);
8339 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8340 ctx->machine_credentials = machine_credentials;
8342 ret &= test_Connect(b, torture, &ctx->handle);
8344 ret &= test_EnumDomains(p, torture, ctx);
8346 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8348 return ret;
8351 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8353 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8354 struct torture_rpc_tcase *tcase;
8356 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8357 &ndr_table_samr,
8358 TEST_ACCOUNT_NAME_PWD);
8360 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8361 torture_rpc_samr_lockout);
8363 return suite;