s4-smbtorture: use torture_comment & torture_warning in RPC samr tests.
[Samba/nivanova.git] / source4 / torture / rpc / samr.c
blobf8853c1093b5defd469c1a5450ce69b8e089c19b
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7 Copyright (C) Guenther Deschner 2008,2009
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
37 #include <unistd.h>
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
46 enum torture_samr_choice {
47 TORTURE_SAMR_PASSWORDS,
48 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
49 TORTURE_SAMR_USER_ATTRIBUTES,
50 TORTURE_SAMR_USER_PRIVILEGES,
51 TORTURE_SAMR_OTHER,
52 TORTURE_SAMR_MANY_ACCOUNTS,
53 TORTURE_SAMR_MANY_GROUPS,
54 TORTURE_SAMR_MANY_ALIASES
57 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
58 struct torture_context *tctx,
59 struct policy_handle *handle);
61 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
62 struct torture_context *tctx,
63 struct policy_handle *handle);
65 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
66 struct torture_context *tctx,
67 struct policy_handle *handle);
69 static bool test_ChangePassword(struct dcerpc_pipe *p,
70 struct torture_context *tctx,
71 const char *acct_name,
72 struct policy_handle *domain_handle, char **password);
74 static void init_lsa_String(struct lsa_String *string, const char *s)
76 string->string = s;
79 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
81 string->string = s;
84 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
86 string->length = length;
87 string->size = length;
88 string->array = (uint16_t *)discard_const(s);
91 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
92 struct policy_handle *handle)
94 NTSTATUS status;
95 struct samr_Close r;
97 r.in.handle = handle;
98 r.out.handle = handle;
100 status = dcerpc_samr_Close(p, tctx, &r);
101 torture_assert_ntstatus_ok(tctx, status, "Close");
103 return true;
106 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
107 struct policy_handle *handle)
109 NTSTATUS status;
110 struct samr_Shutdown r;
112 if (!torture_setting_bool(tctx, "dangerous", false)) {
113 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
114 return true;
117 r.in.connect_handle = handle;
119 torture_comment(tctx, "testing samr_Shutdown\n");
121 status = dcerpc_samr_Shutdown(p, tctx, &r);
122 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
124 return true;
127 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
128 struct policy_handle *handle)
130 NTSTATUS status;
131 struct samr_SetDsrmPassword r;
132 struct lsa_String string;
133 struct samr_Password hash;
135 if (!torture_setting_bool(tctx, "dangerous", false)) {
136 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
139 E_md4hash("TeSTDSRM123", hash.hash);
141 init_lsa_String(&string, "Administrator");
143 r.in.name = &string;
144 r.in.unknown = 0;
145 r.in.hash = &hash;
147 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
149 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
150 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
152 return true;
156 static bool test_QuerySecurity(struct dcerpc_pipe *p,
157 struct torture_context *tctx,
158 struct policy_handle *handle)
160 NTSTATUS status;
161 struct samr_QuerySecurity r;
162 struct samr_SetSecurity s;
163 struct sec_desc_buf *sdbuf = NULL;
165 r.in.handle = handle;
166 r.in.sec_info = 7;
167 r.out.sdbuf = &sdbuf;
169 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
170 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
172 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
174 s.in.handle = handle;
175 s.in.sec_info = 7;
176 s.in.sdbuf = sdbuf;
178 if (torture_setting_bool(tctx, "samba4", false)) {
179 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
182 status = dcerpc_samr_SetSecurity(p, tctx, &s);
183 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
185 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
186 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
188 return true;
192 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
193 struct policy_handle *handle, uint32_t base_acct_flags,
194 const char *base_account_name)
196 NTSTATUS status;
197 struct samr_SetUserInfo s;
198 struct samr_SetUserInfo2 s2;
199 struct samr_QueryUserInfo q;
200 struct samr_QueryUserInfo q0;
201 union samr_UserInfo u;
202 union samr_UserInfo *info;
203 bool ret = true;
204 const char *test_account_name;
206 uint32_t user_extra_flags = 0;
208 if (!torture_setting_bool(tctx, "samba3", false)) {
209 if (base_acct_flags == ACB_NORMAL) {
210 /* When created, accounts are expired by default */
211 user_extra_flags = ACB_PW_EXPIRED;
215 s.in.user_handle = handle;
216 s.in.info = &u;
218 s2.in.user_handle = handle;
219 s2.in.info = &u;
221 q.in.user_handle = handle;
222 q.out.info = &info;
223 q0 = q;
225 #define TESTCALL(call, r) \
226 status = dcerpc_samr_ ##call(p, tctx, &r); \
227 if (!NT_STATUS_IS_OK(status)) { \
228 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
229 r.in.level, nt_errstr(status), __location__); \
230 ret = false; \
231 break; \
234 #define STRING_EQUAL(s1, s2, field) \
235 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
236 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
237 #field, s2, __location__); \
238 ret = false; \
239 break; \
242 #define MEM_EQUAL(s1, s2, length, field) \
243 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
244 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
245 #field, (const char *)s2, __location__); \
246 ret = false; \
247 break; \
250 #define INT_EQUAL(i1, i2, field) \
251 if (i1 != i2) { \
252 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
253 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
254 ret = false; \
255 break; \
258 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
259 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
260 q.in.level = lvl1; \
261 TESTCALL(QueryUserInfo, q) \
262 s.in.level = lvl1; \
263 s2.in.level = lvl1; \
264 u = *info; \
265 if (lvl1 == 21) { \
266 ZERO_STRUCT(u.info21); \
267 u.info21.fields_present = fpval; \
269 init_lsa_String(&u.info ## lvl1.field1, value); \
270 TESTCALL(SetUserInfo, s) \
271 TESTCALL(SetUserInfo2, s2) \
272 init_lsa_String(&u.info ## lvl1.field1, ""); \
273 TESTCALL(QueryUserInfo, q); \
274 u = *info; \
275 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
276 q.in.level = lvl2; \
277 TESTCALL(QueryUserInfo, q) \
278 u = *info; \
279 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
280 } while (0)
282 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
283 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
284 q.in.level = lvl1; \
285 TESTCALL(QueryUserInfo, q) \
286 s.in.level = lvl1; \
287 s2.in.level = lvl1; \
288 u = *info; \
289 if (lvl1 == 21) { \
290 ZERO_STRUCT(u.info21); \
291 u.info21.fields_present = fpval; \
293 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
294 TESTCALL(SetUserInfo, s) \
295 TESTCALL(SetUserInfo2, s2) \
296 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
297 TESTCALL(QueryUserInfo, q); \
298 u = *info; \
299 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
300 q.in.level = lvl2; \
301 TESTCALL(QueryUserInfo, q) \
302 u = *info; \
303 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
304 } while (0)
306 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
307 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
308 q.in.level = lvl1; \
309 TESTCALL(QueryUserInfo, q) \
310 s.in.level = lvl1; \
311 s2.in.level = lvl1; \
312 u = *info; \
313 if (lvl1 == 21) { \
314 uint8_t *bits = u.info21.logon_hours.bits; \
315 ZERO_STRUCT(u.info21); \
316 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
317 u.info21.logon_hours.units_per_week = 168; \
318 u.info21.logon_hours.bits = bits; \
320 u.info21.fields_present = fpval; \
322 u.info ## lvl1.field1 = value; \
323 TESTCALL(SetUserInfo, s) \
324 TESTCALL(SetUserInfo2, s2) \
325 u.info ## lvl1.field1 = 0; \
326 TESTCALL(QueryUserInfo, q); \
327 u = *info; \
328 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
329 q.in.level = lvl2; \
330 TESTCALL(QueryUserInfo, q) \
331 u = *info; \
332 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
333 } while (0)
335 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
336 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
337 } while (0)
339 q0.in.level = 12;
340 do { TESTCALL(QueryUserInfo, q0) } while (0);
342 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
343 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
344 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
345 SAMR_FIELD_COMMENT);
347 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
348 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
349 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
350 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
351 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
352 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
353 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
354 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
355 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
356 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
357 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
358 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
359 test_account_name = base_account_name;
360 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
361 SAMR_FIELD_ACCOUNT_NAME);
363 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
364 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
365 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
366 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
367 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
368 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
369 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
370 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
371 SAMR_FIELD_FULL_NAME);
373 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
374 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
375 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
376 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
377 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
378 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
379 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
380 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
381 SAMR_FIELD_FULL_NAME);
383 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
384 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
385 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
386 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
387 SAMR_FIELD_LOGON_SCRIPT);
389 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
390 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
391 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
392 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
393 SAMR_FIELD_PROFILE_PATH);
395 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
396 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
397 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
398 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
399 SAMR_FIELD_HOME_DIRECTORY);
400 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
401 SAMR_FIELD_HOME_DIRECTORY);
403 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
404 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
405 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
406 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
407 SAMR_FIELD_HOME_DRIVE);
408 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
409 SAMR_FIELD_HOME_DRIVE);
411 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
412 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
413 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
414 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
415 SAMR_FIELD_DESCRIPTION);
417 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
418 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
419 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
420 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
421 SAMR_FIELD_WORKSTATIONS);
422 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
423 SAMR_FIELD_WORKSTATIONS);
424 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
425 SAMR_FIELD_WORKSTATIONS);
426 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
427 SAMR_FIELD_WORKSTATIONS);
429 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
430 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
431 SAMR_FIELD_PARAMETERS);
432 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
433 SAMR_FIELD_PARAMETERS);
434 /* also empty user parameters are allowed */
435 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
436 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
437 SAMR_FIELD_PARAMETERS);
438 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
439 SAMR_FIELD_PARAMETERS);
441 /* Samba 3 cannot store country_code and copy_page atm. - gd */
442 if (!torture_setting_bool(tctx, "samba3", false)) {
443 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
444 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
445 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
446 SAMR_FIELD_COUNTRY_CODE);
447 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
448 SAMR_FIELD_COUNTRY_CODE);
450 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
451 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
452 SAMR_FIELD_CODE_PAGE);
453 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
454 SAMR_FIELD_CODE_PAGE);
457 if (!torture_setting_bool(tctx, "samba3", false)) {
458 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
459 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
460 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
461 SAMR_FIELD_ACCT_EXPIRY);
462 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
463 SAMR_FIELD_ACCT_EXPIRY);
464 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
465 SAMR_FIELD_ACCT_EXPIRY);
466 } else {
467 /* Samba 3 can only store seconds / time_t in passdb - gd */
468 NTTIME nt;
469 unix_to_nt_time(&nt, time(NULL) + __LINE__);
470 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
471 unix_to_nt_time(&nt, time(NULL) + __LINE__);
472 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
473 unix_to_nt_time(&nt, time(NULL) + __LINE__);
474 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
475 unix_to_nt_time(&nt, time(NULL) + __LINE__);
476 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
477 unix_to_nt_time(&nt, time(NULL) + __LINE__);
478 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
481 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
482 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
483 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
484 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
485 SAMR_FIELD_LOGON_HOURS);
487 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
488 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
489 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
491 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
492 (base_acct_flags | ACB_DISABLED),
493 (base_acct_flags | ACB_DISABLED | user_extra_flags),
496 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
497 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
498 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
499 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
501 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
502 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
503 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
507 /* The 'autolock' flag doesn't stick - check this */
508 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
509 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
510 (base_acct_flags | ACB_DISABLED | user_extra_flags),
512 #if 0
513 /* Removing the 'disabled' flag doesn't stick - check this */
514 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
515 (base_acct_flags),
516 (base_acct_flags | ACB_DISABLED | user_extra_flags),
518 #endif
520 /* Samba3 cannot store these atm */
521 if (!torture_setting_bool(tctx, "samba3", false)) {
522 /* The 'store plaintext' flag does stick */
523 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
524 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
525 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
527 /* The 'use DES' flag does stick */
528 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
529 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
530 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
532 /* The 'don't require kerberos pre-authentication flag does stick */
533 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
534 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
535 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
537 /* The 'no kerberos PAC required' flag sticks */
538 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
539 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
540 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
543 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
544 (base_acct_flags | ACB_DISABLED),
545 (base_acct_flags | ACB_DISABLED | user_extra_flags),
546 SAMR_FIELD_ACCT_FLAGS);
548 #if 0
549 /* these fail with win2003 - it appears you can't set the primary gid?
550 the set succeeds, but the gid isn't changed. Very weird! */
551 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
552 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
553 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
554 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
555 #endif
557 return ret;
561 generate a random password for password change tests
563 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
565 size_t len = MAX(8, min_len) + (random() % 6);
566 char *s = generate_random_str(mem_ctx, len);
567 return s;
570 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
572 char *s = samr_rand_pass_silent(mem_ctx, min_len);
573 printf("Generated password '%s'\n", s);
574 return s;
579 generate a random password for password change tests
581 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
583 int i;
584 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
585 generate_random_buffer(password.data, password.length);
587 for (i=0; i < len; i++) {
588 if (((uint16_t *)password.data)[i] == 0) {
589 ((uint16_t *)password.data)[i] = 1;
593 return password;
597 generate a random password for password change tests (fixed length)
599 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
601 char *s = generate_random_str(mem_ctx, len);
602 printf("Generated password '%s'\n", s);
603 return s;
606 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
607 struct policy_handle *handle, char **password)
609 NTSTATUS status;
610 struct samr_SetUserInfo s;
611 union samr_UserInfo u;
612 bool ret = true;
613 DATA_BLOB session_key;
614 char *newpass;
615 struct samr_GetUserPwInfo pwp;
616 struct samr_PwInfo info;
617 int policy_min_pw_len = 0;
618 pwp.in.user_handle = handle;
619 pwp.out.info = &info;
621 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
622 if (NT_STATUS_IS_OK(status)) {
623 policy_min_pw_len = pwp.out.info->min_password_length;
625 newpass = samr_rand_pass(tctx, policy_min_pw_len);
627 s.in.user_handle = handle;
628 s.in.info = &u;
629 s.in.level = 24;
631 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
632 u.info24.password_expired = 0;
634 status = dcerpc_fetch_session_key(p, &session_key);
635 if (!NT_STATUS_IS_OK(status)) {
636 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
637 s.in.level, nt_errstr(status));
638 return false;
641 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
643 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
645 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
646 if (!NT_STATUS_IS_OK(status)) {
647 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
648 s.in.level, nt_errstr(status));
649 ret = false;
650 } else {
651 *password = newpass;
654 return ret;
658 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
659 struct policy_handle *handle, uint32_t fields_present,
660 char **password)
662 NTSTATUS status;
663 struct samr_SetUserInfo s;
664 union samr_UserInfo u;
665 bool ret = true;
666 DATA_BLOB session_key;
667 char *newpass;
668 struct samr_GetUserPwInfo pwp;
669 struct samr_PwInfo info;
670 int policy_min_pw_len = 0;
671 pwp.in.user_handle = handle;
672 pwp.out.info = &info;
674 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
675 if (NT_STATUS_IS_OK(status)) {
676 policy_min_pw_len = pwp.out.info->min_password_length;
678 newpass = samr_rand_pass(tctx, policy_min_pw_len);
680 s.in.user_handle = handle;
681 s.in.info = &u;
682 s.in.level = 23;
684 ZERO_STRUCT(u);
686 u.info23.info.fields_present = fields_present;
688 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
690 status = dcerpc_fetch_session_key(p, &session_key);
691 if (!NT_STATUS_IS_OK(status)) {
692 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
693 s.in.level, nt_errstr(status));
694 return false;
697 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
699 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
701 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
702 if (!NT_STATUS_IS_OK(status)) {
703 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
704 s.in.level, nt_errstr(status));
705 ret = false;
706 } else {
707 *password = newpass;
710 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
712 status = dcerpc_fetch_session_key(p, &session_key);
713 if (!NT_STATUS_IS_OK(status)) {
714 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
715 s.in.level, nt_errstr(status));
716 return false;
719 /* This should break the key nicely */
720 session_key.length--;
721 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
723 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
725 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
726 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
727 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
728 s.in.level, nt_errstr(status));
729 ret = false;
732 return ret;
736 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
737 struct policy_handle *handle, bool makeshort,
738 char **password)
740 NTSTATUS status;
741 struct samr_SetUserInfo s;
742 union samr_UserInfo u;
743 bool ret = true;
744 DATA_BLOB session_key;
745 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
746 uint8_t confounder[16];
747 char *newpass;
748 struct MD5Context ctx;
749 struct samr_GetUserPwInfo pwp;
750 struct samr_PwInfo info;
751 int policy_min_pw_len = 0;
752 pwp.in.user_handle = handle;
753 pwp.out.info = &info;
755 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
756 if (NT_STATUS_IS_OK(status)) {
757 policy_min_pw_len = pwp.out.info->min_password_length;
759 if (makeshort && policy_min_pw_len) {
760 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
761 } else {
762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
765 s.in.user_handle = handle;
766 s.in.info = &u;
767 s.in.level = 26;
769 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
770 u.info26.password_expired = 0;
772 status = dcerpc_fetch_session_key(p, &session_key);
773 if (!NT_STATUS_IS_OK(status)) {
774 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
775 s.in.level, nt_errstr(status));
776 return false;
779 generate_random_buffer((uint8_t *)confounder, 16);
781 MD5Init(&ctx);
782 MD5Update(&ctx, confounder, 16);
783 MD5Update(&ctx, session_key.data, session_key.length);
784 MD5Final(confounded_session_key.data, &ctx);
786 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
787 memcpy(&u.info26.password.data[516], confounder, 16);
789 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
791 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
792 if (!NT_STATUS_IS_OK(status)) {
793 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
794 s.in.level, nt_errstr(status));
795 ret = false;
796 } else {
797 *password = newpass;
800 /* This should break the key nicely */
801 confounded_session_key.data[0]++;
803 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
804 memcpy(&u.info26.password.data[516], confounder, 16);
806 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
808 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
809 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
810 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
811 s.in.level, nt_errstr(status));
812 ret = false;
813 } else {
814 *password = newpass;
817 return ret;
820 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
821 struct policy_handle *handle, uint32_t fields_present,
822 char **password)
824 NTSTATUS status;
825 struct samr_SetUserInfo s;
826 union samr_UserInfo u;
827 bool ret = true;
828 DATA_BLOB session_key;
829 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
830 struct MD5Context ctx;
831 uint8_t confounder[16];
832 char *newpass;
833 struct samr_GetUserPwInfo pwp;
834 struct samr_PwInfo info;
835 int policy_min_pw_len = 0;
836 pwp.in.user_handle = handle;
837 pwp.out.info = &info;
839 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
840 if (NT_STATUS_IS_OK(status)) {
841 policy_min_pw_len = pwp.out.info->min_password_length;
843 newpass = samr_rand_pass(tctx, policy_min_pw_len);
845 s.in.user_handle = handle;
846 s.in.info = &u;
847 s.in.level = 25;
849 ZERO_STRUCT(u);
851 u.info25.info.fields_present = fields_present;
853 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
855 status = dcerpc_fetch_session_key(p, &session_key);
856 if (!NT_STATUS_IS_OK(status)) {
857 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
858 s.in.level, nt_errstr(status));
859 return false;
862 generate_random_buffer((uint8_t *)confounder, 16);
864 MD5Init(&ctx);
865 MD5Update(&ctx, confounder, 16);
866 MD5Update(&ctx, session_key.data, session_key.length);
867 MD5Final(confounded_session_key.data, &ctx);
869 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
870 memcpy(&u.info25.password.data[516], confounder, 16);
872 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
874 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
875 if (!NT_STATUS_IS_OK(status)) {
876 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
877 s.in.level, nt_errstr(status));
878 ret = false;
879 } else {
880 *password = newpass;
883 /* This should break the key nicely */
884 confounded_session_key.data[0]++;
886 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
887 memcpy(&u.info25.password.data[516], confounder, 16);
889 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
891 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
892 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
893 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
894 s.in.level, nt_errstr(status));
895 ret = false;
898 return ret;
901 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
902 struct policy_handle *handle, char **password)
904 NTSTATUS status;
905 struct samr_SetUserInfo s;
906 union samr_UserInfo u;
907 bool ret = true;
908 DATA_BLOB session_key;
909 char *newpass;
910 struct samr_GetUserPwInfo pwp;
911 struct samr_PwInfo info;
912 int policy_min_pw_len = 0;
913 uint8_t lm_hash[16], nt_hash[16];
915 pwp.in.user_handle = handle;
916 pwp.out.info = &info;
918 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
919 if (NT_STATUS_IS_OK(status)) {
920 policy_min_pw_len = pwp.out.info->min_password_length;
922 newpass = samr_rand_pass(tctx, policy_min_pw_len);
924 s.in.user_handle = handle;
925 s.in.info = &u;
926 s.in.level = 18;
928 ZERO_STRUCT(u);
930 u.info18.nt_pwd_active = true;
931 u.info18.lm_pwd_active = true;
933 E_md4hash(newpass, nt_hash);
934 E_deshash(newpass, lm_hash);
936 status = dcerpc_fetch_session_key(p, &session_key);
937 if (!NT_STATUS_IS_OK(status)) {
938 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
939 s.in.level, nt_errstr(status));
940 return false;
944 DATA_BLOB in,out;
945 in = data_blob_const(nt_hash, 16);
946 out = data_blob_talloc_zero(tctx, 16);
947 sess_crypt_blob(&out, &in, &session_key, true);
948 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
951 DATA_BLOB in,out;
952 in = data_blob_const(lm_hash, 16);
953 out = data_blob_talloc_zero(tctx, 16);
954 sess_crypt_blob(&out, &in, &session_key, true);
955 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
958 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
960 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
961 if (!NT_STATUS_IS_OK(status)) {
962 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
963 s.in.level, nt_errstr(status));
964 ret = false;
965 } else {
966 *password = newpass;
969 return ret;
972 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
973 struct policy_handle *handle, uint32_t fields_present,
974 char **password)
976 NTSTATUS status;
977 struct samr_SetUserInfo s;
978 union samr_UserInfo u;
979 bool ret = true;
980 DATA_BLOB session_key;
981 char *newpass;
982 struct samr_GetUserPwInfo pwp;
983 struct samr_PwInfo info;
984 int policy_min_pw_len = 0;
985 uint8_t lm_hash[16], nt_hash[16];
987 pwp.in.user_handle = handle;
988 pwp.out.info = &info;
990 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
991 if (NT_STATUS_IS_OK(status)) {
992 policy_min_pw_len = pwp.out.info->min_password_length;
994 newpass = samr_rand_pass(tctx, policy_min_pw_len);
996 s.in.user_handle = handle;
997 s.in.info = &u;
998 s.in.level = 21;
1000 E_md4hash(newpass, nt_hash);
1001 E_deshash(newpass, lm_hash);
1003 ZERO_STRUCT(u);
1005 u.info21.fields_present = fields_present;
1007 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1008 u.info21.lm_owf_password.length = 16;
1009 u.info21.lm_owf_password.size = 16;
1010 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1011 u.info21.lm_password_set = true;
1014 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1015 u.info21.nt_owf_password.length = 16;
1016 u.info21.nt_owf_password.size = 16;
1017 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1018 u.info21.nt_password_set = true;
1021 status = dcerpc_fetch_session_key(p, &session_key);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1024 s.in.level, nt_errstr(status));
1025 return false;
1028 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1029 DATA_BLOB in,out;
1030 in = data_blob_const(u.info21.lm_owf_password.array,
1031 u.info21.lm_owf_password.length);
1032 out = data_blob_talloc_zero(tctx, 16);
1033 sess_crypt_blob(&out, &in, &session_key, true);
1034 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1037 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1038 DATA_BLOB in,out;
1039 in = data_blob_const(u.info21.nt_owf_password.array,
1040 u.info21.nt_owf_password.length);
1041 out = data_blob_talloc_zero(tctx, 16);
1042 sess_crypt_blob(&out, &in, &session_key, true);
1043 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1046 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1048 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1049 if (!NT_STATUS_IS_OK(status)) {
1050 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1051 s.in.level, nt_errstr(status));
1052 ret = false;
1053 } else {
1054 *password = newpass;
1057 /* try invalid length */
1058 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1060 u.info21.nt_owf_password.length++;
1062 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1064 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1065 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1066 s.in.level, nt_errstr(status));
1067 ret = false;
1071 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1073 u.info21.lm_owf_password.length++;
1075 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1077 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1078 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1079 s.in.level, nt_errstr(status));
1080 ret = false;
1084 return ret;
1087 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1088 struct torture_context *tctx,
1089 struct policy_handle *handle,
1090 uint16_t level,
1091 uint32_t fields_present,
1092 char **password, uint8_t password_expired,
1093 bool use_setinfo2,
1094 bool *matched_expected_error)
1096 NTSTATUS status;
1097 NTSTATUS expected_error = NT_STATUS_OK;
1098 struct samr_SetUserInfo s;
1099 struct samr_SetUserInfo2 s2;
1100 union samr_UserInfo u;
1101 bool ret = true;
1102 DATA_BLOB session_key;
1103 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1104 struct MD5Context ctx;
1105 uint8_t confounder[16];
1106 char *newpass;
1107 struct samr_GetUserPwInfo pwp;
1108 struct samr_PwInfo info;
1109 int policy_min_pw_len = 0;
1110 const char *comment = NULL;
1111 uint8_t lm_hash[16], nt_hash[16];
1113 pwp.in.user_handle = handle;
1114 pwp.out.info = &info;
1116 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1117 if (NT_STATUS_IS_OK(status)) {
1118 policy_min_pw_len = pwp.out.info->min_password_length;
1120 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1122 if (use_setinfo2) {
1123 s2.in.user_handle = handle;
1124 s2.in.info = &u;
1125 s2.in.level = level;
1126 } else {
1127 s.in.user_handle = handle;
1128 s.in.info = &u;
1129 s.in.level = level;
1132 if (fields_present & SAMR_FIELD_COMMENT) {
1133 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1136 ZERO_STRUCT(u);
1138 switch (level) {
1139 case 18:
1140 E_md4hash(newpass, nt_hash);
1141 E_deshash(newpass, lm_hash);
1143 u.info18.nt_pwd_active = true;
1144 u.info18.lm_pwd_active = true;
1145 u.info18.password_expired = password_expired;
1147 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1148 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1150 break;
1151 case 21:
1152 E_md4hash(newpass, nt_hash);
1153 E_deshash(newpass, lm_hash);
1155 u.info21.fields_present = fields_present;
1156 u.info21.password_expired = password_expired;
1157 u.info21.comment.string = comment;
1159 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1160 u.info21.lm_owf_password.length = 16;
1161 u.info21.lm_owf_password.size = 16;
1162 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1163 u.info21.lm_password_set = true;
1166 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1167 u.info21.nt_owf_password.length = 16;
1168 u.info21.nt_owf_password.size = 16;
1169 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1170 u.info21.nt_password_set = true;
1173 break;
1174 case 23:
1175 u.info23.info.fields_present = fields_present;
1176 u.info23.info.password_expired = password_expired;
1177 u.info23.info.comment.string = comment;
1179 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1181 break;
1182 case 24:
1183 u.info24.password_expired = password_expired;
1185 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1187 break;
1188 case 25:
1189 u.info25.info.fields_present = fields_present;
1190 u.info25.info.password_expired = password_expired;
1191 u.info25.info.comment.string = comment;
1193 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1195 break;
1196 case 26:
1197 u.info26.password_expired = password_expired;
1199 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1201 break;
1204 status = dcerpc_fetch_session_key(p, &session_key);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1207 s.in.level, nt_errstr(status));
1208 return false;
1211 generate_random_buffer((uint8_t *)confounder, 16);
1213 MD5Init(&ctx);
1214 MD5Update(&ctx, confounder, 16);
1215 MD5Update(&ctx, session_key.data, session_key.length);
1216 MD5Final(confounded_session_key.data, &ctx);
1218 switch (level) {
1219 case 18:
1221 DATA_BLOB in,out;
1222 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1223 out = data_blob_talloc_zero(tctx, 16);
1224 sess_crypt_blob(&out, &in, &session_key, true);
1225 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1228 DATA_BLOB in,out;
1229 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1230 out = data_blob_talloc_zero(tctx, 16);
1231 sess_crypt_blob(&out, &in, &session_key, true);
1232 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1235 break;
1236 case 21:
1237 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1238 DATA_BLOB in,out;
1239 in = data_blob_const(u.info21.lm_owf_password.array,
1240 u.info21.lm_owf_password.length);
1241 out = data_blob_talloc_zero(tctx, 16);
1242 sess_crypt_blob(&out, &in, &session_key, true);
1243 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1245 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1246 DATA_BLOB in,out;
1247 in = data_blob_const(u.info21.nt_owf_password.array,
1248 u.info21.nt_owf_password.length);
1249 out = data_blob_talloc_zero(tctx, 16);
1250 sess_crypt_blob(&out, &in, &session_key, true);
1251 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1253 break;
1254 case 23:
1255 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1256 break;
1257 case 24:
1258 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1259 break;
1260 case 25:
1261 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1262 memcpy(&u.info25.password.data[516], confounder, 16);
1263 break;
1264 case 26:
1265 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1266 memcpy(&u.info26.password.data[516], confounder, 16);
1267 break;
1270 if (use_setinfo2) {
1271 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1272 } else {
1273 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1276 if (!NT_STATUS_IS_OK(status)) {
1277 if (fields_present == 0) {
1278 expected_error = NT_STATUS_INVALID_PARAMETER;
1280 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1281 expected_error = NT_STATUS_ACCESS_DENIED;
1285 if (!NT_STATUS_IS_OK(expected_error)) {
1286 if (use_setinfo2) {
1287 torture_assert_ntstatus_equal(tctx,
1288 s2.out.result,
1289 expected_error, "SetUserInfo2 failed");
1290 } else {
1291 torture_assert_ntstatus_equal(tctx,
1292 s.out.result,
1293 expected_error, "SetUserInfo failed");
1295 *matched_expected_error = true;
1296 return true;
1299 if (!NT_STATUS_IS_OK(status)) {
1300 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1301 use_setinfo2 ? "2":"", level, nt_errstr(status));
1302 ret = false;
1303 } else {
1304 *password = newpass;
1307 return ret;
1310 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1311 struct policy_handle *handle)
1313 NTSTATUS status;
1314 struct samr_SetAliasInfo r;
1315 struct samr_QueryAliasInfo q;
1316 union samr_AliasInfo *info;
1317 uint16_t levels[] = {2, 3};
1318 int i;
1319 bool ret = true;
1321 /* Ignoring switch level 1, as that includes the number of members for the alias
1322 * and setting this to a wrong value might have negative consequences
1325 for (i=0;i<ARRAY_SIZE(levels);i++) {
1326 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1328 r.in.alias_handle = handle;
1329 r.in.level = levels[i];
1330 r.in.info = talloc(tctx, union samr_AliasInfo);
1331 switch (r.in.level) {
1332 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1333 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1334 "Test Description, should test I18N as well"); break;
1335 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1338 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1341 levels[i], nt_errstr(status));
1342 ret = false;
1345 q.in.alias_handle = handle;
1346 q.in.level = levels[i];
1347 q.out.info = &info;
1349 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1352 levels[i], nt_errstr(status));
1353 ret = false;
1357 return ret;
1360 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1361 struct policy_handle *user_handle)
1363 struct samr_GetGroupsForUser r;
1364 struct samr_RidWithAttributeArray *rids = NULL;
1365 NTSTATUS status;
1367 torture_comment(tctx, "testing GetGroupsForUser\n");
1369 r.in.user_handle = user_handle;
1370 r.out.rids = &rids;
1372 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1373 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1375 return true;
1379 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1380 struct lsa_String *domain_name)
1382 NTSTATUS status;
1383 struct samr_GetDomPwInfo r;
1384 struct samr_PwInfo info;
1386 r.in.domain_name = domain_name;
1387 r.out.info = &info;
1389 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1391 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1392 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1394 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1395 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1397 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1398 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1400 r.in.domain_name->string = "\\\\__NONAME__";
1401 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1403 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1404 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1406 r.in.domain_name->string = "\\\\Builtin";
1407 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1409 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1410 torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1412 return true;
1415 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1416 struct policy_handle *handle)
1418 NTSTATUS status;
1419 struct samr_GetUserPwInfo r;
1420 struct samr_PwInfo info;
1422 torture_comment(tctx, "Testing GetUserPwInfo\n");
1424 r.in.user_handle = handle;
1425 r.out.info = &info;
1427 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1428 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1430 return true;
1433 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1434 struct policy_handle *domain_handle, const char *name,
1435 uint32_t *rid)
1437 NTSTATUS status;
1438 struct samr_LookupNames n;
1439 struct lsa_String sname[2];
1440 struct samr_Ids rids, types;
1442 init_lsa_String(&sname[0], name);
1444 n.in.domain_handle = domain_handle;
1445 n.in.num_names = 1;
1446 n.in.names = sname;
1447 n.out.rids = &rids;
1448 n.out.types = &types;
1449 status = dcerpc_samr_LookupNames(p, tctx, &n);
1450 if (NT_STATUS_IS_OK(status)) {
1451 *rid = n.out.rids->ids[0];
1452 } else {
1453 return status;
1456 init_lsa_String(&sname[1], "xxNONAMExx");
1457 n.in.num_names = 2;
1458 status = dcerpc_samr_LookupNames(p, tctx, &n);
1459 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1460 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(status));
1461 if (NT_STATUS_IS_OK(status)) {
1462 return NT_STATUS_UNSUCCESSFUL;
1464 return status;
1467 n.in.num_names = 0;
1468 status = dcerpc_samr_LookupNames(p, tctx, &n);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1471 return status;
1474 init_lsa_String(&sname[0], "xxNONAMExx");
1475 n.in.num_names = 1;
1476 status = dcerpc_samr_LookupNames(p, tctx, &n);
1477 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1478 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1479 if (NT_STATUS_IS_OK(status)) {
1480 return NT_STATUS_UNSUCCESSFUL;
1482 return status;
1485 init_lsa_String(&sname[0], "xxNONAMExx");
1486 init_lsa_String(&sname[1], "xxNONAME2xx");
1487 n.in.num_names = 2;
1488 status = dcerpc_samr_LookupNames(p, tctx, &n);
1489 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1490 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1491 if (NT_STATUS_IS_OK(status)) {
1492 return NT_STATUS_UNSUCCESSFUL;
1494 return status;
1497 return NT_STATUS_OK;
1500 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1501 struct torture_context *tctx,
1502 struct policy_handle *domain_handle,
1503 const char *name, struct policy_handle *user_handle)
1505 NTSTATUS status;
1506 struct samr_OpenUser r;
1507 uint32_t rid;
1509 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1510 if (!NT_STATUS_IS_OK(status)) {
1511 return status;
1514 r.in.domain_handle = domain_handle;
1515 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1516 r.in.rid = rid;
1517 r.out.user_handle = user_handle;
1518 status = dcerpc_samr_OpenUser(p, tctx, &r);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1523 return status;
1526 #if 0
1527 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1528 struct torture_context *tctx,
1529 struct policy_handle *handle)
1531 NTSTATUS status;
1532 struct samr_ChangePasswordUser r;
1533 bool ret = true;
1534 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1535 struct policy_handle user_handle;
1536 char *oldpass = "test";
1537 char *newpass = "test2";
1538 uint8_t old_nt_hash[16], new_nt_hash[16];
1539 uint8_t old_lm_hash[16], new_lm_hash[16];
1541 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1542 if (!NT_STATUS_IS_OK(status)) {
1543 return false;
1546 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1548 torture_comment(tctx, "old password: %s\n", oldpass);
1549 torture_comment(tctx, "new password: %s\n", newpass);
1551 E_md4hash(oldpass, old_nt_hash);
1552 E_md4hash(newpass, new_nt_hash);
1553 E_deshash(oldpass, old_lm_hash);
1554 E_deshash(newpass, new_lm_hash);
1556 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1557 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1558 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1559 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1560 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1561 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1563 r.in.handle = &user_handle;
1564 r.in.lm_present = 1;
1565 r.in.old_lm_crypted = &hash1;
1566 r.in.new_lm_crypted = &hash2;
1567 r.in.nt_present = 1;
1568 r.in.old_nt_crypted = &hash3;
1569 r.in.new_nt_crypted = &hash4;
1570 r.in.cross1_present = 1;
1571 r.in.nt_cross = &hash5;
1572 r.in.cross2_present = 1;
1573 r.in.lm_cross = &hash6;
1575 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1578 ret = false;
1581 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1582 ret = false;
1585 return ret;
1587 #endif
1589 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1590 const char *acct_name,
1591 struct policy_handle *handle, char **password)
1593 NTSTATUS status;
1594 struct samr_ChangePasswordUser r;
1595 bool ret = true;
1596 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1597 struct policy_handle user_handle;
1598 char *oldpass;
1599 uint8_t old_nt_hash[16], new_nt_hash[16];
1600 uint8_t old_lm_hash[16], new_lm_hash[16];
1601 bool changed = true;
1603 char *newpass;
1604 struct samr_GetUserPwInfo pwp;
1605 struct samr_PwInfo info;
1606 int policy_min_pw_len = 0;
1608 status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1609 if (!NT_STATUS_IS_OK(status)) {
1610 return false;
1612 pwp.in.user_handle = &user_handle;
1613 pwp.out.info = &info;
1615 status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1616 if (NT_STATUS_IS_OK(status)) {
1617 policy_min_pw_len = pwp.out.info->min_password_length;
1619 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1621 torture_comment(tctx, "Testing ChangePasswordUser\n");
1623 torture_assert(tctx, *password != NULL,
1624 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1626 oldpass = *password;
1628 E_md4hash(oldpass, old_nt_hash);
1629 E_md4hash(newpass, new_nt_hash);
1630 E_deshash(oldpass, old_lm_hash);
1631 E_deshash(newpass, new_lm_hash);
1633 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1634 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1635 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1636 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1637 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1638 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1640 r.in.user_handle = &user_handle;
1641 r.in.lm_present = 1;
1642 /* Break the LM hash */
1643 hash1.hash[0]++;
1644 r.in.old_lm_crypted = &hash1;
1645 r.in.new_lm_crypted = &hash2;
1646 r.in.nt_present = 1;
1647 r.in.old_nt_crypted = &hash3;
1648 r.in.new_nt_crypted = &hash4;
1649 r.in.cross1_present = 1;
1650 r.in.nt_cross = &hash5;
1651 r.in.cross2_present = 1;
1652 r.in.lm_cross = &hash6;
1654 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1655 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1656 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1658 /* Unbreak the LM hash */
1659 hash1.hash[0]--;
1661 r.in.user_handle = &user_handle;
1662 r.in.lm_present = 1;
1663 r.in.old_lm_crypted = &hash1;
1664 r.in.new_lm_crypted = &hash2;
1665 /* Break the NT hash */
1666 hash3.hash[0]--;
1667 r.in.nt_present = 1;
1668 r.in.old_nt_crypted = &hash3;
1669 r.in.new_nt_crypted = &hash4;
1670 r.in.cross1_present = 1;
1671 r.in.nt_cross = &hash5;
1672 r.in.cross2_present = 1;
1673 r.in.lm_cross = &hash6;
1675 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1676 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1677 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1679 /* Unbreak the NT hash */
1680 hash3.hash[0]--;
1682 r.in.user_handle = &user_handle;
1683 r.in.lm_present = 1;
1684 r.in.old_lm_crypted = &hash1;
1685 r.in.new_lm_crypted = &hash2;
1686 r.in.nt_present = 1;
1687 r.in.old_nt_crypted = &hash3;
1688 r.in.new_nt_crypted = &hash4;
1689 r.in.cross1_present = 1;
1690 r.in.nt_cross = &hash5;
1691 r.in.cross2_present = 1;
1692 /* Break the LM cross */
1693 hash6.hash[0]++;
1694 r.in.lm_cross = &hash6;
1696 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1697 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1698 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1699 ret = false;
1702 /* Unbreak the LM cross */
1703 hash6.hash[0]--;
1705 r.in.user_handle = &user_handle;
1706 r.in.lm_present = 1;
1707 r.in.old_lm_crypted = &hash1;
1708 r.in.new_lm_crypted = &hash2;
1709 r.in.nt_present = 1;
1710 r.in.old_nt_crypted = &hash3;
1711 r.in.new_nt_crypted = &hash4;
1712 r.in.cross1_present = 1;
1713 /* Break the NT cross */
1714 hash5.hash[0]++;
1715 r.in.nt_cross = &hash5;
1716 r.in.cross2_present = 1;
1717 r.in.lm_cross = &hash6;
1719 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1720 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1721 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1722 ret = false;
1725 /* Unbreak the NT cross */
1726 hash5.hash[0]--;
1729 /* Reset the hashes to not broken values */
1730 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1731 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1732 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1733 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1734 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1735 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1737 r.in.user_handle = &user_handle;
1738 r.in.lm_present = 1;
1739 r.in.old_lm_crypted = &hash1;
1740 r.in.new_lm_crypted = &hash2;
1741 r.in.nt_present = 1;
1742 r.in.old_nt_crypted = &hash3;
1743 r.in.new_nt_crypted = &hash4;
1744 r.in.cross1_present = 1;
1745 r.in.nt_cross = &hash5;
1746 r.in.cross2_present = 0;
1747 r.in.lm_cross = NULL;
1749 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1750 if (NT_STATUS_IS_OK(status)) {
1751 changed = true;
1752 *password = newpass;
1753 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1754 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1755 ret = false;
1758 oldpass = newpass;
1759 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1761 E_md4hash(oldpass, old_nt_hash);
1762 E_md4hash(newpass, new_nt_hash);
1763 E_deshash(oldpass, old_lm_hash);
1764 E_deshash(newpass, new_lm_hash);
1767 /* Reset the hashes to not broken values */
1768 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1769 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1770 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1771 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1772 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1773 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1775 r.in.user_handle = &user_handle;
1776 r.in.lm_present = 1;
1777 r.in.old_lm_crypted = &hash1;
1778 r.in.new_lm_crypted = &hash2;
1779 r.in.nt_present = 1;
1780 r.in.old_nt_crypted = &hash3;
1781 r.in.new_nt_crypted = &hash4;
1782 r.in.cross1_present = 0;
1783 r.in.nt_cross = NULL;
1784 r.in.cross2_present = 1;
1785 r.in.lm_cross = &hash6;
1787 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1788 if (NT_STATUS_IS_OK(status)) {
1789 changed = true;
1790 *password = newpass;
1791 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1792 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1793 ret = false;
1796 oldpass = newpass;
1797 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1799 E_md4hash(oldpass, old_nt_hash);
1800 E_md4hash(newpass, new_nt_hash);
1801 E_deshash(oldpass, old_lm_hash);
1802 E_deshash(newpass, new_lm_hash);
1805 /* Reset the hashes to not broken values */
1806 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1807 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1808 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1809 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1810 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1811 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1813 r.in.user_handle = &user_handle;
1814 r.in.lm_present = 1;
1815 r.in.old_lm_crypted = &hash1;
1816 r.in.new_lm_crypted = &hash2;
1817 r.in.nt_present = 1;
1818 r.in.old_nt_crypted = &hash3;
1819 r.in.new_nt_crypted = &hash4;
1820 r.in.cross1_present = 1;
1821 r.in.nt_cross = &hash5;
1822 r.in.cross2_present = 1;
1823 r.in.lm_cross = &hash6;
1825 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1826 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1827 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1828 } else if (!NT_STATUS_IS_OK(status)) {
1829 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1830 ret = false;
1831 } else {
1832 changed = true;
1833 *password = newpass;
1836 r.in.user_handle = &user_handle;
1837 r.in.lm_present = 1;
1838 r.in.old_lm_crypted = &hash1;
1839 r.in.new_lm_crypted = &hash2;
1840 r.in.nt_present = 1;
1841 r.in.old_nt_crypted = &hash3;
1842 r.in.new_nt_crypted = &hash4;
1843 r.in.cross1_present = 1;
1844 r.in.nt_cross = &hash5;
1845 r.in.cross2_present = 1;
1846 r.in.lm_cross = &hash6;
1848 if (changed) {
1849 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1850 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1851 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1852 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1853 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1854 ret = false;
1859 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1860 ret = false;
1863 return ret;
1867 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1868 const char *acct_name,
1869 struct policy_handle *handle, char **password)
1871 NTSTATUS status;
1872 struct samr_OemChangePasswordUser2 r;
1873 bool ret = true;
1874 struct samr_Password lm_verifier;
1875 struct samr_CryptPassword lm_pass;
1876 struct lsa_AsciiString server, account, account_bad;
1877 char *oldpass;
1878 char *newpass;
1879 uint8_t old_lm_hash[16], new_lm_hash[16];
1881 struct samr_GetDomPwInfo dom_pw_info;
1882 struct samr_PwInfo info;
1883 int policy_min_pw_len = 0;
1885 struct lsa_String domain_name;
1887 domain_name.string = "";
1888 dom_pw_info.in.domain_name = &domain_name;
1889 dom_pw_info.out.info = &info;
1891 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1893 torture_assert(tctx, *password != NULL,
1894 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1896 oldpass = *password;
1898 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1899 if (NT_STATUS_IS_OK(status)) {
1900 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1903 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1905 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1906 account.string = acct_name;
1908 E_deshash(oldpass, old_lm_hash);
1909 E_deshash(newpass, new_lm_hash);
1911 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1912 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1913 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1915 r.in.server = &server;
1916 r.in.account = &account;
1917 r.in.password = &lm_pass;
1918 r.in.hash = &lm_verifier;
1920 /* Break the verification */
1921 lm_verifier.hash[0]++;
1923 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1925 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1926 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1927 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1928 nt_errstr(status));
1929 ret = false;
1932 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1933 /* Break the old password */
1934 old_lm_hash[0]++;
1935 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1936 /* unbreak it for the next operation */
1937 old_lm_hash[0]--;
1938 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1940 r.in.server = &server;
1941 r.in.account = &account;
1942 r.in.password = &lm_pass;
1943 r.in.hash = &lm_verifier;
1945 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1947 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1948 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1949 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1950 nt_errstr(status));
1951 ret = false;
1954 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1955 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1957 r.in.server = &server;
1958 r.in.account = &account;
1959 r.in.password = &lm_pass;
1960 r.in.hash = NULL;
1962 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1964 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1965 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1966 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1967 nt_errstr(status));
1968 ret = false;
1971 /* This shouldn't be a valid name */
1972 account_bad.string = TEST_ACCOUNT_NAME "XX";
1973 r.in.account = &account_bad;
1975 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1977 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1978 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1979 nt_errstr(status));
1980 ret = false;
1983 /* This shouldn't be a valid name */
1984 account_bad.string = TEST_ACCOUNT_NAME "XX";
1985 r.in.account = &account_bad;
1986 r.in.password = &lm_pass;
1987 r.in.hash = &lm_verifier;
1989 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1991 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1992 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1993 nt_errstr(status));
1994 ret = false;
1997 /* This shouldn't be a valid name */
1998 account_bad.string = TEST_ACCOUNT_NAME "XX";
1999 r.in.account = &account_bad;
2000 r.in.password = NULL;
2001 r.in.hash = &lm_verifier;
2003 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2005 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2006 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2007 nt_errstr(status));
2008 ret = false;
2011 E_deshash(oldpass, old_lm_hash);
2012 E_deshash(newpass, new_lm_hash);
2014 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2015 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2016 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2018 r.in.server = &server;
2019 r.in.account = &account;
2020 r.in.password = &lm_pass;
2021 r.in.hash = &lm_verifier;
2023 status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2024 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2025 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2026 } else if (!NT_STATUS_IS_OK(status)) {
2027 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2028 ret = false;
2029 } else {
2030 *password = newpass;
2033 return ret;
2037 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2038 const char *acct_name,
2039 char **password,
2040 char *newpass, bool allow_password_restriction)
2042 NTSTATUS status;
2043 struct samr_ChangePasswordUser2 r;
2044 bool ret = true;
2045 struct lsa_String server, account;
2046 struct samr_CryptPassword nt_pass, lm_pass;
2047 struct samr_Password nt_verifier, lm_verifier;
2048 char *oldpass;
2049 uint8_t old_nt_hash[16], new_nt_hash[16];
2050 uint8_t old_lm_hash[16], new_lm_hash[16];
2052 struct samr_GetDomPwInfo dom_pw_info;
2053 struct samr_PwInfo info;
2055 struct lsa_String domain_name;
2057 domain_name.string = "";
2058 dom_pw_info.in.domain_name = &domain_name;
2059 dom_pw_info.out.info = &info;
2061 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2063 torture_assert(tctx, *password != NULL,
2064 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2065 oldpass = *password;
2067 if (!newpass) {
2068 int policy_min_pw_len = 0;
2069 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2070 if (NT_STATUS_IS_OK(status)) {
2071 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2074 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2077 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2078 init_lsa_String(&account, acct_name);
2080 E_md4hash(oldpass, old_nt_hash);
2081 E_md4hash(newpass, new_nt_hash);
2083 E_deshash(oldpass, old_lm_hash);
2084 E_deshash(newpass, new_lm_hash);
2086 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2087 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2088 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2090 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2091 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2092 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2094 r.in.server = &server;
2095 r.in.account = &account;
2096 r.in.nt_password = &nt_pass;
2097 r.in.nt_verifier = &nt_verifier;
2098 r.in.lm_change = 1;
2099 r.in.lm_password = &lm_pass;
2100 r.in.lm_verifier = &lm_verifier;
2102 status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2103 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2104 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2105 } else if (!NT_STATUS_IS_OK(status)) {
2106 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2107 ret = false;
2108 } else {
2109 *password = newpass;
2112 return ret;
2116 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2117 const char *account_string,
2118 int policy_min_pw_len,
2119 char **password,
2120 const char *newpass,
2121 NTTIME last_password_change,
2122 bool handle_reject_reason)
2124 NTSTATUS status;
2125 struct samr_ChangePasswordUser3 r;
2126 bool ret = true;
2127 struct lsa_String server, account, account_bad;
2128 struct samr_CryptPassword nt_pass, lm_pass;
2129 struct samr_Password nt_verifier, lm_verifier;
2130 char *oldpass;
2131 uint8_t old_nt_hash[16], new_nt_hash[16];
2132 uint8_t old_lm_hash[16], new_lm_hash[16];
2133 NTTIME t;
2134 struct samr_DomInfo1 *dominfo = NULL;
2135 struct samr_ChangeReject *reject = NULL;
2137 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2139 if (newpass == NULL) {
2140 do {
2141 if (policy_min_pw_len == 0) {
2142 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2143 } else {
2144 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2146 } while (check_password_quality(newpass) == false);
2147 } else {
2148 torture_comment(tctx, "Using password '%s'\n", newpass);
2151 torture_assert(tctx, *password != NULL,
2152 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2154 oldpass = *password;
2155 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2156 init_lsa_String(&account, account_string);
2158 E_md4hash(oldpass, old_nt_hash);
2159 E_md4hash(newpass, new_nt_hash);
2161 E_deshash(oldpass, old_lm_hash);
2162 E_deshash(newpass, new_lm_hash);
2164 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2165 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2166 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2168 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2169 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2170 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2172 /* Break the verification */
2173 nt_verifier.hash[0]++;
2175 r.in.server = &server;
2176 r.in.account = &account;
2177 r.in.nt_password = &nt_pass;
2178 r.in.nt_verifier = &nt_verifier;
2179 r.in.lm_change = 1;
2180 r.in.lm_password = &lm_pass;
2181 r.in.lm_verifier = &lm_verifier;
2182 r.in.password3 = NULL;
2183 r.out.dominfo = &dominfo;
2184 r.out.reject = &reject;
2186 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2187 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2188 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2189 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2190 nt_errstr(status));
2191 ret = false;
2194 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2195 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2196 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2198 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2199 /* Break the NT hash */
2200 old_nt_hash[0]++;
2201 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2202 /* Unbreak it again */
2203 old_nt_hash[0]--;
2204 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2206 r.in.server = &server;
2207 r.in.account = &account;
2208 r.in.nt_password = &nt_pass;
2209 r.in.nt_verifier = &nt_verifier;
2210 r.in.lm_change = 1;
2211 r.in.lm_password = &lm_pass;
2212 r.in.lm_verifier = &lm_verifier;
2213 r.in.password3 = NULL;
2214 r.out.dominfo = &dominfo;
2215 r.out.reject = &reject;
2217 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2218 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2219 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2220 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2221 nt_errstr(status));
2222 ret = false;
2225 /* This shouldn't be a valid name */
2226 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2228 r.in.account = &account_bad;
2229 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2230 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2231 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2232 nt_errstr(status));
2233 ret = false;
2236 E_md4hash(oldpass, old_nt_hash);
2237 E_md4hash(newpass, new_nt_hash);
2239 E_deshash(oldpass, old_lm_hash);
2240 E_deshash(newpass, new_lm_hash);
2242 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2243 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2244 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2246 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2247 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2248 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2250 r.in.server = &server;
2251 r.in.account = &account;
2252 r.in.nt_password = &nt_pass;
2253 r.in.nt_verifier = &nt_verifier;
2254 r.in.lm_change = 1;
2255 r.in.lm_password = &lm_pass;
2256 r.in.lm_verifier = &lm_verifier;
2257 r.in.password3 = NULL;
2258 r.out.dominfo = &dominfo;
2259 r.out.reject = &reject;
2261 unix_to_nt_time(&t, time(NULL));
2263 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2265 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2266 && dominfo
2267 && reject
2268 && handle_reject_reason
2269 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2270 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2272 if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2273 torture_warning(tctx, "expected SAMR_REJECT_OTHER (%d), got %d\n",
2274 SAMR_REJECT_OTHER, reject->reason);
2275 return false;
2279 /* We tested the order of precendence which is as follows:
2281 * pwd min_age
2282 * pwd length
2283 * pwd complexity
2284 * pwd history
2286 Guenther */
2288 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2289 (last_password_change + dominfo->min_password_age > t)) {
2291 if (reject->reason != SAMR_REJECT_OTHER) {
2292 torture_warning(tctx, "expected SAMR_REJECT_OTHER (%d), got %d\n",
2293 SAMR_REJECT_OTHER, reject->reason);
2294 return false;
2297 } else if ((dominfo->min_password_length > 0) &&
2298 (strlen(newpass) < dominfo->min_password_length)) {
2300 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2301 torture_warning(tctx, "expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2302 SAMR_REJECT_TOO_SHORT, reject->reason);
2303 return false;
2306 } else if ((dominfo->password_history_length > 0) &&
2307 strequal(oldpass, newpass)) {
2309 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2310 torture_warning(tctx, "expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2311 SAMR_REJECT_IN_HISTORY, reject->reason);
2312 return false;
2314 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2316 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2317 torture_warning(tctx, "expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2318 SAMR_REJECT_COMPLEXITY, reject->reason);
2319 return false;
2324 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2325 /* retry with adjusted size */
2326 return test_ChangePasswordUser3(p, tctx, account_string,
2327 dominfo->min_password_length,
2328 password, NULL, 0, false);
2332 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2333 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2334 torture_warning(tctx, "expected SAMR_REJECT_OTHER (%d), got %d\n",
2335 SAMR_REJECT_OTHER, reject->reason);
2336 return false;
2338 /* Perhaps the server has a 'min password age' set? */
2340 } else {
2341 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2342 *password = talloc_strdup(tctx, newpass);
2345 return ret;
2348 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2349 const char *account_string,
2350 struct policy_handle *handle,
2351 char **password)
2353 NTSTATUS status;
2354 struct samr_ChangePasswordUser3 r;
2355 struct samr_SetUserInfo s;
2356 union samr_UserInfo u;
2357 DATA_BLOB session_key;
2358 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2359 uint8_t confounder[16];
2360 struct MD5Context ctx;
2362 bool ret = true;
2363 struct lsa_String server, account;
2364 struct samr_CryptPassword nt_pass;
2365 struct samr_Password nt_verifier;
2366 DATA_BLOB new_random_pass;
2367 char *newpass;
2368 char *oldpass;
2369 uint8_t old_nt_hash[16], new_nt_hash[16];
2370 NTTIME t;
2371 struct samr_DomInfo1 *dominfo = NULL;
2372 struct samr_ChangeReject *reject = NULL;
2374 new_random_pass = samr_very_rand_pass(tctx, 128);
2376 torture_assert(tctx, *password != NULL,
2377 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2379 oldpass = *password;
2380 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2381 init_lsa_String(&account, account_string);
2383 s.in.user_handle = handle;
2384 s.in.info = &u;
2385 s.in.level = 25;
2387 ZERO_STRUCT(u);
2389 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2391 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2393 status = dcerpc_fetch_session_key(p, &session_key);
2394 if (!NT_STATUS_IS_OK(status)) {
2395 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2396 s.in.level, nt_errstr(status));
2397 return false;
2400 generate_random_buffer((uint8_t *)confounder, 16);
2402 MD5Init(&ctx);
2403 MD5Update(&ctx, confounder, 16);
2404 MD5Update(&ctx, session_key.data, session_key.length);
2405 MD5Final(confounded_session_key.data, &ctx);
2407 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2408 memcpy(&u.info25.password.data[516], confounder, 16);
2410 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2412 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2415 s.in.level, nt_errstr(status));
2416 ret = false;
2419 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2421 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2423 new_random_pass = samr_very_rand_pass(tctx, 128);
2425 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2427 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2428 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2429 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2431 r.in.server = &server;
2432 r.in.account = &account;
2433 r.in.nt_password = &nt_pass;
2434 r.in.nt_verifier = &nt_verifier;
2435 r.in.lm_change = 0;
2436 r.in.lm_password = NULL;
2437 r.in.lm_verifier = NULL;
2438 r.in.password3 = NULL;
2439 r.out.dominfo = &dominfo;
2440 r.out.reject = &reject;
2442 unix_to_nt_time(&t, time(NULL));
2444 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2446 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2447 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2448 torture_warning(tctx, "expected SAMR_REJECT_OTHER (%d), got %d\n",
2449 SAMR_REJECT_OTHER, reject->reason);
2450 return false;
2452 /* Perhaps the server has a 'min password age' set? */
2454 } else if (!NT_STATUS_IS_OK(status)) {
2455 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2456 ret = false;
2459 newpass = samr_rand_pass(tctx, 128);
2461 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2463 E_md4hash(newpass, new_nt_hash);
2465 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2466 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2467 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2469 r.in.server = &server;
2470 r.in.account = &account;
2471 r.in.nt_password = &nt_pass;
2472 r.in.nt_verifier = &nt_verifier;
2473 r.in.lm_change = 0;
2474 r.in.lm_password = NULL;
2475 r.in.lm_verifier = NULL;
2476 r.in.password3 = NULL;
2477 r.out.dominfo = &dominfo;
2478 r.out.reject = &reject;
2480 unix_to_nt_time(&t, time(NULL));
2482 status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2484 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2485 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2486 torture_warning(tctx, "expected SAMR_REJECT_OTHER (%d), got %d\n",
2487 SAMR_REJECT_OTHER, reject->reason);
2488 return false;
2490 /* Perhaps the server has a 'min password age' set? */
2492 } else {
2493 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2494 *password = talloc_strdup(tctx, newpass);
2497 return ret;
2501 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2502 struct policy_handle *alias_handle)
2504 struct samr_GetMembersInAlias r;
2505 struct lsa_SidArray sids;
2506 NTSTATUS status;
2508 torture_comment(tctx, "Testing GetMembersInAlias\n");
2510 r.in.alias_handle = alias_handle;
2511 r.out.sids = &sids;
2513 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2514 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2516 return true;
2519 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2520 struct policy_handle *alias_handle,
2521 const struct dom_sid *domain_sid)
2523 struct samr_AddAliasMember r;
2524 struct samr_DeleteAliasMember d;
2525 NTSTATUS status;
2526 struct dom_sid *sid;
2528 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2530 torture_comment(tctx, "testing AddAliasMember\n");
2531 r.in.alias_handle = alias_handle;
2532 r.in.sid = sid;
2534 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2535 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2537 d.in.alias_handle = alias_handle;
2538 d.in.sid = sid;
2540 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2541 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2543 return true;
2546 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2547 struct policy_handle *alias_handle)
2549 struct samr_AddMultipleMembersToAlias a;
2550 struct samr_RemoveMultipleMembersFromAlias r;
2551 NTSTATUS status;
2552 struct lsa_SidArray sids;
2554 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2555 a.in.alias_handle = alias_handle;
2556 a.in.sids = &sids;
2558 sids.num_sids = 3;
2559 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2561 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2562 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2563 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2565 status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2566 torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2569 torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2570 r.in.alias_handle = alias_handle;
2571 r.in.sids = &sids;
2573 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2574 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2576 /* strange! removing twice doesn't give any error */
2577 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2578 torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2580 /* but removing an alias that isn't there does */
2581 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2583 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2584 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2586 return true;
2589 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2590 struct policy_handle *user_handle)
2592 struct samr_TestPrivateFunctionsUser r;
2593 NTSTATUS status;
2595 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2597 r.in.user_handle = user_handle;
2599 status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2600 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2602 return true;
2605 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2606 struct torture_context *tctx,
2607 struct policy_handle *handle,
2608 bool use_info2,
2609 NTTIME *pwdlastset)
2611 NTSTATUS status;
2612 uint16_t levels[] = { /* 3, */ 5, 21 };
2613 int i;
2614 NTTIME pwdlastset3 = 0;
2615 NTTIME pwdlastset5 = 0;
2616 NTTIME pwdlastset21 = 0;
2618 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2619 use_info2 ? "2":"");
2621 for (i=0; i<ARRAY_SIZE(levels); i++) {
2623 struct samr_QueryUserInfo r;
2624 struct samr_QueryUserInfo2 r2;
2625 union samr_UserInfo *info;
2627 if (use_info2) {
2628 r2.in.user_handle = handle;
2629 r2.in.level = levels[i];
2630 r2.out.info = &info;
2631 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2633 } else {
2634 r.in.user_handle = handle;
2635 r.in.level = levels[i];
2636 r.out.info = &info;
2637 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2640 if (!NT_STATUS_IS_OK(status) &&
2641 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2642 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2643 use_info2 ? "2":"", levels[i], nt_errstr(status));
2644 return false;
2647 switch (levels[i]) {
2648 case 3:
2649 pwdlastset3 = info->info3.last_password_change;
2650 break;
2651 case 5:
2652 pwdlastset5 = info->info5.last_password_change;
2653 break;
2654 case 21:
2655 pwdlastset21 = info->info21.last_password_change;
2656 break;
2657 default:
2658 return false;
2661 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2662 "pwdlastset mixup"); */
2663 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2664 "pwdlastset mixup");
2666 *pwdlastset = pwdlastset21;
2668 torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2670 return true;
2673 static bool test_SamLogon(struct torture_context *tctx,
2674 struct dcerpc_pipe *p,
2675 struct cli_credentials *test_credentials,
2676 NTSTATUS expected_result)
2678 NTSTATUS status;
2679 struct netr_LogonSamLogonEx r;
2680 union netr_LogonLevel logon;
2681 union netr_Validation validation;
2682 uint8_t authoritative;
2683 struct netr_NetworkInfo ninfo;
2684 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2685 int flags = CLI_CRED_NTLM_AUTH;
2686 uint32_t samlogon_flags = 0;
2688 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2689 flags |= CLI_CRED_LANMAN_AUTH;
2692 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2693 flags |= CLI_CRED_NTLMv2_AUTH;
2696 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2697 &ninfo.identity_info.account_name.string,
2698 &ninfo.identity_info.domain_name.string);
2700 generate_random_buffer(ninfo.challenge,
2701 sizeof(ninfo.challenge));
2702 chal = data_blob_const(ninfo.challenge,
2703 sizeof(ninfo.challenge));
2705 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2706 cli_credentials_get_domain(test_credentials));
2708 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2709 &flags,
2710 chal,
2711 names_blob,
2712 &lm_resp, &nt_resp,
2713 NULL, NULL);
2714 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2716 ninfo.lm.data = lm_resp.data;
2717 ninfo.lm.length = lm_resp.length;
2719 ninfo.nt.data = nt_resp.data;
2720 ninfo.nt.length = nt_resp.length;
2722 ninfo.identity_info.parameter_control =
2723 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2724 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2725 ninfo.identity_info.logon_id_low = 0;
2726 ninfo.identity_info.logon_id_high = 0;
2727 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
2729 logon.network = &ninfo;
2731 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2732 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2733 r.in.logon_level = NetlogonNetworkInformation;
2734 r.in.logon = &logon;
2735 r.in.flags = &samlogon_flags;
2736 r.out.flags = &samlogon_flags;
2737 r.out.validation = &validation;
2738 r.out.authoritative = &authoritative;
2740 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2742 r.in.validation_level = 6;
2744 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2745 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2746 r.in.validation_level = 3;
2747 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2749 if (!NT_STATUS_IS_OK(status)) {
2750 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2751 return true;
2752 } else {
2753 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2756 return true;
2759 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2760 struct dcerpc_pipe *p,
2761 struct cli_credentials *machine_creds,
2762 const char *acct_name,
2763 char *password,
2764 NTSTATUS expected_samlogon_result)
2766 bool ret = true;
2767 struct cli_credentials *test_credentials;
2769 test_credentials = cli_credentials_init(tctx);
2771 cli_credentials_set_workstation(test_credentials,
2772 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2773 cli_credentials_set_domain(test_credentials,
2774 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2775 cli_credentials_set_username(test_credentials,
2776 acct_name, CRED_SPECIFIED);
2777 cli_credentials_set_password(test_credentials,
2778 password, CRED_SPECIFIED);
2780 torture_comment(tctx, "testing samlogon as %s password: %s\n",
2781 acct_name, password);
2783 if (!test_SamLogon(tctx, p, test_credentials,
2784 expected_samlogon_result)) {
2785 torture_warning(tctx, "new password did not work\n");
2786 ret = false;
2789 return ret;
2792 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2793 struct dcerpc_pipe *np,
2794 struct torture_context *tctx,
2795 struct policy_handle *handle,
2796 uint16_t level,
2797 uint32_t fields_present,
2798 uint8_t password_expired,
2799 bool *matched_expected_error,
2800 bool use_setinfo2,
2801 const char *acct_name,
2802 char **password,
2803 struct cli_credentials *machine_creds,
2804 bool use_queryinfo2,
2805 NTTIME *pwdlastset,
2806 NTSTATUS expected_samlogon_result)
2808 const char *fields = NULL;
2809 bool ret = true;
2811 switch (level) {
2812 case 21:
2813 case 23:
2814 case 25:
2815 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2816 fields_present);
2817 break;
2818 default:
2819 break;
2822 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2823 "(password_expired: %d) %s\n",
2824 use_setinfo2 ? "2":"", level, password_expired,
2825 fields ? fields : "");
2827 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2828 fields_present,
2829 password,
2830 password_expired,
2831 use_setinfo2,
2832 matched_expected_error)) {
2833 ret = false;
2836 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2837 use_queryinfo2,
2838 pwdlastset)) {
2839 ret = false;
2842 if (*matched_expected_error == true) {
2843 return ret;
2846 if (!test_SamLogon_with_creds(tctx, np,
2847 machine_creds,
2848 acct_name,
2849 *password,
2850 expected_samlogon_result)) {
2851 ret = false;
2854 return ret;
2857 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2858 struct torture_context *tctx,
2859 uint32_t acct_flags,
2860 const char *acct_name,
2861 struct policy_handle *handle,
2862 char **password,
2863 struct cli_credentials *machine_credentials)
2865 int s = 0, q = 0, f = 0, l = 0, z = 0;
2866 struct dcerpc_binding *b;
2867 bool ret = true;
2868 int delay = 50000;
2869 bool set_levels[] = { false, true };
2870 bool query_levels[] = { false, true };
2871 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2872 uint32_t nonzeros[] = { 1, 24 };
2873 uint32_t fields_present[] = {
2875 SAMR_FIELD_EXPIRED_FLAG,
2876 SAMR_FIELD_LAST_PWD_CHANGE,
2877 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2878 SAMR_FIELD_COMMENT,
2879 SAMR_FIELD_NT_PASSWORD_PRESENT,
2880 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2881 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2882 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2883 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2884 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2885 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2887 NTSTATUS status;
2888 struct dcerpc_pipe *np = NULL;
2890 if (torture_setting_bool(tctx, "samba3", false)) {
2891 delay = 999999;
2892 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
2893 delay);
2896 status = torture_rpc_binding(tctx, &b);
2897 if (!NT_STATUS_IS_OK(status)) {
2898 ret = false;
2899 return ret;
2902 /* We have to use schannel, otherwise the SamLogonEx fails
2903 * with INTERNAL_ERROR */
2905 b->flags &= ~DCERPC_AUTH_OPTIONS;
2906 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2908 status = dcerpc_pipe_connect_b(tctx, &np, b,
2909 &ndr_table_netlogon,
2910 machine_credentials, tctx->ev, tctx->lp_ctx);
2912 if (!NT_STATUS_IS_OK(status)) {
2913 torture_warning(tctx, "RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2914 ret = false;
2915 return ret;
2918 /* set to 1 to enable testing for all possible opcode
2919 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2920 combinations */
2921 #if 0
2922 #define TEST_ALL_LEVELS 1
2923 #define TEST_SET_LEVELS 1
2924 #define TEST_QUERY_LEVELS 1
2925 #endif
2926 #ifdef TEST_ALL_LEVELS
2927 for (l=0; l<ARRAY_SIZE(levels); l++) {
2928 #else
2929 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
2930 #endif
2931 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2932 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2933 #ifdef TEST_SET_LEVELS
2934 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2935 #endif
2936 #ifdef TEST_QUERY_LEVELS
2937 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2938 #endif
2939 NTTIME pwdlastset_old = 0;
2940 NTTIME pwdlastset_new = 0;
2941 bool matched_expected_error = false;
2942 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2944 torture_comment(tctx, "------------------------------\n"
2945 "Testing pwdLastSet attribute for flags: 0x%08x "
2946 "(s: %d (l: %d), q: %d)\n",
2947 acct_flags, s, levels[l], q);
2949 switch (levels[l]) {
2950 case 21:
2951 case 23:
2952 case 25:
2953 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2954 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2955 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2957 break;
2961 /* set #1 */
2963 /* set a password and force password change (pwdlastset 0) by
2964 * setting the password expired flag to a non-0 value */
2966 if (!test_SetPassword_level(p, np, tctx, handle,
2967 levels[l],
2968 fields_present[f],
2969 nonzeros[z],
2970 &matched_expected_error,
2971 set_levels[s],
2972 acct_name,
2973 password,
2974 machine_credentials,
2975 query_levels[q],
2976 &pwdlastset_old,
2977 expected_samlogon_result)) {
2978 ret = false;
2981 if (matched_expected_error == true) {
2982 /* skipping on expected failure */
2983 continue;
2986 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2987 * set without the SAMR_FIELD_EXPIRED_FLAG */
2989 switch (levels[l]) {
2990 case 21:
2991 case 23:
2992 case 25:
2993 if ((pwdlastset_new != 0) &&
2994 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2995 torture_comment(tctx, "not considering a non-0 "
2996 "pwdLastSet as a an error as the "
2997 "SAMR_FIELD_EXPIRED_FLAG has not "
2998 "been set\n");
2999 break;
3001 default:
3002 if (pwdlastset_new != 0) {
3003 torture_warning(tctx, "pwdLastSet test failed: "
3004 "expected pwdLastSet 0 but got %lld\n",
3005 pwdlastset_old);
3006 ret = false;
3008 break;
3011 switch (levels[l]) {
3012 case 21:
3013 case 23:
3014 case 25:
3015 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3016 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3017 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3018 (pwdlastset_old >= pwdlastset_new)) {
3019 torture_warning(tctx, "pwdlastset not increasing\n");
3020 ret = false;
3022 break;
3023 default:
3024 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3025 (pwdlastset_old >= pwdlastset_new)) {
3026 torture_warning(tctx, "pwdlastset not increasing\n");
3027 ret = false;
3029 break;
3032 usleep(delay);
3034 /* set #2 */
3036 /* set a password, pwdlastset needs to get updated (increased
3037 * value), password_expired value used here is 0 */
3039 if (!test_SetPassword_level(p, np, tctx, handle,
3040 levels[l],
3041 fields_present[f],
3043 &matched_expected_error,
3044 set_levels[s],
3045 acct_name,
3046 password,
3047 machine_credentials,
3048 query_levels[q],
3049 &pwdlastset_new,
3050 expected_samlogon_result)) {
3051 ret = false;
3054 /* when a password has been changed, pwdlastset must not be 0 afterwards
3055 * and must be larger then the old value */
3057 switch (levels[l]) {
3058 case 21:
3059 case 23:
3060 case 25:
3062 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3063 * password has been changed, old and new pwdlastset
3064 * need to be the same value */
3066 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3067 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3068 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3070 torture_assert_int_equal(tctx, pwdlastset_old,
3071 pwdlastset_new, "pwdlastset must be equal");
3072 break;
3074 default:
3075 if (pwdlastset_old >= pwdlastset_new) {
3076 torture_warning(tctx, "pwdLastSet test failed: "
3077 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3078 pwdlastset_old, pwdlastset_new);
3079 ret = false;
3081 if (pwdlastset_new == 0) {
3082 torture_warning(tctx, "pwdLastSet test failed: "
3083 "expected non-0 pwdlastset, got: %lld\n",
3084 pwdlastset_new);
3085 ret = false;
3089 switch (levels[l]) {
3090 case 21:
3091 case 23:
3092 case 25:
3093 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3094 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3095 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3096 (pwdlastset_old >= pwdlastset_new)) {
3097 torture_warning(tctx, "pwdlastset not increasing\n");
3098 ret = false;
3100 break;
3101 default:
3102 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3103 (pwdlastset_old >= pwdlastset_new)) {
3104 torture_warning(tctx, "pwdlastset not increasing\n");
3105 ret = false;
3107 break;
3110 pwdlastset_old = pwdlastset_new;
3112 usleep(delay);
3114 /* set #2b */
3116 /* set a password, pwdlastset needs to get updated (increased
3117 * value), password_expired value used here is 0 */
3119 if (!test_SetPassword_level(p, np, tctx, handle,
3120 levels[l],
3121 fields_present[f],
3123 &matched_expected_error,
3124 set_levels[s],
3125 acct_name,
3126 password,
3127 machine_credentials,
3128 query_levels[q],
3129 &pwdlastset_new,
3130 expected_samlogon_result)) {
3131 ret = false;
3134 /* when a password has been changed, pwdlastset must not be 0 afterwards
3135 * and must be larger then the old value */
3137 switch (levels[l]) {
3138 case 21:
3139 case 23:
3140 case 25:
3142 /* if no password has been changed, old and new pwdlastset
3143 * need to be the same value */
3145 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3146 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3148 torture_assert_int_equal(tctx, pwdlastset_old,
3149 pwdlastset_new, "pwdlastset must be equal");
3150 break;
3152 default:
3153 if (pwdlastset_old >= pwdlastset_new) {
3154 torture_warning(tctx, "pwdLastSet test failed: "
3155 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3156 pwdlastset_old, pwdlastset_new);
3157 ret = false;
3159 if (pwdlastset_new == 0) {
3160 torture_warning(tctx, "pwdLastSet test failed: "
3161 "expected non-0 pwdlastset, got: %lld\n",
3162 pwdlastset_new);
3163 ret = false;
3167 /* set #3 */
3169 /* set a password and force password change (pwdlastset 0) by
3170 * setting the password expired flag to a non-0 value */
3172 if (!test_SetPassword_level(p, np, tctx, handle,
3173 levels[l],
3174 fields_present[f],
3175 nonzeros[z],
3176 &matched_expected_error,
3177 set_levels[s],
3178 acct_name,
3179 password,
3180 machine_credentials,
3181 query_levels[q],
3182 &pwdlastset_new,
3183 expected_samlogon_result)) {
3184 ret = false;
3187 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3188 * set without the SAMR_FIELD_EXPIRED_FLAG */
3190 switch (levels[l]) {
3191 case 21:
3192 case 23:
3193 case 25:
3194 if ((pwdlastset_new != 0) &&
3195 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3196 torture_comment(tctx, "not considering a non-0 "
3197 "pwdLastSet as a an error as the "
3198 "SAMR_FIELD_EXPIRED_FLAG has not "
3199 "been set\n");
3200 break;
3203 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3204 * password has been changed, old and new pwdlastset
3205 * need to be the same value */
3207 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3208 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3209 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3211 torture_assert_int_equal(tctx, pwdlastset_old,
3212 pwdlastset_new, "pwdlastset must be equal");
3213 break;
3215 default:
3217 if (pwdlastset_old == pwdlastset_new) {
3218 torture_warning(tctx, "pwdLastSet test failed: "
3219 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3220 pwdlastset_old, pwdlastset_new);
3221 ret = false;
3224 if (pwdlastset_new != 0) {
3225 torture_warning(tctx, "pwdLastSet test failed: "
3226 "expected pwdLastSet 0, got %lld\n",
3227 pwdlastset_old);
3228 ret = false;
3230 break;
3233 switch (levels[l]) {
3234 case 21:
3235 case 23:
3236 case 25:
3237 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3238 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3239 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3240 (pwdlastset_old >= pwdlastset_new)) {
3241 torture_warning(tctx, "pwdlastset not increasing\n");
3242 ret = false;
3244 break;
3245 default:
3246 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3247 (pwdlastset_old >= pwdlastset_new)) {
3248 torture_warning(tctx, "pwdlastset not increasing\n");
3249 ret = false;
3251 break;
3254 /* if the level we are testing does not have a fields_present
3255 * field, skip all fields present tests by setting f to to
3256 * arraysize */
3257 switch (levels[l]) {
3258 case 18:
3259 case 24:
3260 case 26:
3261 f = ARRAY_SIZE(fields_present);
3262 break;
3265 #ifdef TEST_QUERY_LEVELS
3267 #endif
3268 #ifdef TEST_SET_LEVELS
3270 #endif
3271 } /* fields present */
3272 } /* nonzeros */
3273 } /* levels */
3275 #undef TEST_SET_LEVELS
3276 #undef TEST_QUERY_LEVELS
3278 return ret;
3281 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3282 struct dcerpc_pipe *lp,
3283 struct torture_context *tctx,
3284 struct policy_handle *domain_handle,
3285 struct policy_handle *lsa_handle,
3286 struct policy_handle *user_handle,
3287 const struct dom_sid *domain_sid,
3288 uint32_t rid,
3289 struct cli_credentials *machine_credentials)
3291 NTSTATUS status;
3292 bool ret = true;
3294 struct policy_handle lsa_acct_handle;
3295 struct dom_sid *user_sid;
3297 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3300 struct lsa_EnumAccountRights r;
3301 struct lsa_RightSet rights;
3303 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3305 r.in.handle = lsa_handle;
3306 r.in.sid = user_sid;
3307 r.out.rights = &rights;
3309 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3310 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3311 "Expected enum rights for account to fail");
3315 struct lsa_RightSet rights;
3316 struct lsa_StringLarge names[2];
3317 struct lsa_AddAccountRights r;
3319 torture_comment(tctx, "Testing LSA AddAccountRights\n");
3321 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3322 init_lsa_StringLarge(&names[1], NULL);
3324 rights.count = 1;
3325 rights.names = names;
3327 r.in.handle = lsa_handle;
3328 r.in.sid = user_sid;
3329 r.in.rights = &rights;
3331 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3332 torture_assert_ntstatus_ok(tctx, status,
3333 "Failed to add privileges");
3337 struct lsa_EnumAccounts r;
3338 uint32_t resume_handle = 0;
3339 struct lsa_SidArray lsa_sid_array;
3340 int i;
3341 bool found_sid = false;
3343 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3345 r.in.handle = lsa_handle;
3346 r.in.num_entries = 0x1000;
3347 r.in.resume_handle = &resume_handle;
3348 r.out.sids = &lsa_sid_array;
3349 r.out.resume_handle = &resume_handle;
3351 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3352 torture_assert_ntstatus_ok(tctx, status,
3353 "Failed to enum accounts");
3355 for (i=0; i < lsa_sid_array.num_sids; i++) {
3356 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3357 found_sid = true;
3361 torture_assert(tctx, found_sid,
3362 "failed to list privileged account");
3366 struct lsa_EnumAccountRights r;
3367 struct lsa_RightSet user_rights;
3369 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3371 r.in.handle = lsa_handle;
3372 r.in.sid = user_sid;
3373 r.out.rights = &user_rights;
3375 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3376 torture_assert_ntstatus_ok(tctx, status,
3377 "Failed to enum rights for account");
3379 if (user_rights.count < 1) {
3380 torture_warning(tctx, "failed to find newly added rights");
3381 return false;
3386 struct lsa_OpenAccount r;
3388 torture_comment(tctx, "Testing LSA OpenAccount\n");
3390 r.in.handle = lsa_handle;
3391 r.in.sid = user_sid;
3392 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3393 r.out.acct_handle = &lsa_acct_handle;
3395 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3396 torture_assert_ntstatus_ok(tctx, status,
3397 "Failed to open lsa account");
3401 struct lsa_GetSystemAccessAccount r;
3402 uint32_t access_mask;
3404 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3406 r.in.handle = &lsa_acct_handle;
3407 r.out.access_mask = &access_mask;
3409 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3410 torture_assert_ntstatus_ok(tctx, status,
3411 "Failed to get lsa system access account");
3415 struct lsa_Close r;
3417 torture_comment(tctx, "Testing LSA Close\n");
3419 r.in.handle = &lsa_acct_handle;
3420 r.out.handle = &lsa_acct_handle;
3422 status = dcerpc_lsa_Close(lp, tctx, &r);
3423 torture_assert_ntstatus_ok(tctx, status,
3424 "Failed to close lsa");
3428 struct samr_DeleteUser r;
3430 torture_comment(tctx, "Testing SAMR DeleteUser\n");
3432 r.in.user_handle = user_handle;
3433 r.out.user_handle = user_handle;
3435 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3436 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3440 struct lsa_EnumAccounts r;
3441 uint32_t resume_handle = 0;
3442 struct lsa_SidArray lsa_sid_array;
3443 int i;
3444 bool found_sid = false;
3446 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3448 r.in.handle = lsa_handle;
3449 r.in.num_entries = 0x1000;
3450 r.in.resume_handle = &resume_handle;
3451 r.out.sids = &lsa_sid_array;
3452 r.out.resume_handle = &resume_handle;
3454 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3455 torture_assert_ntstatus_ok(tctx, status,
3456 "Failed to enum accounts");
3458 for (i=0; i < lsa_sid_array.num_sids; i++) {
3459 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3460 found_sid = true;
3464 torture_assert(tctx, found_sid,
3465 "failed to list privileged account");
3469 struct lsa_EnumAccountRights r;
3470 struct lsa_RightSet user_rights;
3472 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3474 r.in.handle = lsa_handle;
3475 r.in.sid = user_sid;
3476 r.out.rights = &user_rights;
3478 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3479 torture_assert_ntstatus_ok(tctx, status,
3480 "Failed to enum rights for account");
3482 if (user_rights.count < 1) {
3483 torture_warning(tctx, "failed to find newly added rights");
3484 return false;
3489 struct lsa_OpenAccount r;
3491 torture_comment(tctx, "Testing LSA OpenAccount\n");
3493 r.in.handle = lsa_handle;
3494 r.in.sid = user_sid;
3495 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3496 r.out.acct_handle = &lsa_acct_handle;
3498 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3499 torture_assert_ntstatus_ok(tctx, status,
3500 "Failed to open lsa account");
3504 struct lsa_GetSystemAccessAccount r;
3505 uint32_t access_mask;
3507 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3509 r.in.handle = &lsa_acct_handle;
3510 r.out.access_mask = &access_mask;
3512 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3513 torture_assert_ntstatus_ok(tctx, status,
3514 "Failed to get lsa system access account");
3518 struct lsa_DeleteObject r;
3520 torture_comment(tctx, "Testing LSA DeleteObject\n");
3522 r.in.handle = &lsa_acct_handle;
3523 r.out.handle = &lsa_acct_handle;
3525 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3526 torture_assert_ntstatus_ok(tctx, status,
3527 "Failed to delete object");
3531 struct lsa_EnumAccounts r;
3532 uint32_t resume_handle = 0;
3533 struct lsa_SidArray lsa_sid_array;
3534 int i;
3535 bool found_sid = false;
3537 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3539 r.in.handle = lsa_handle;
3540 r.in.num_entries = 0x1000;
3541 r.in.resume_handle = &resume_handle;
3542 r.out.sids = &lsa_sid_array;
3543 r.out.resume_handle = &resume_handle;
3545 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3546 torture_assert_ntstatus_ok(tctx, status,
3547 "Failed to enum accounts");
3549 for (i=0; i < lsa_sid_array.num_sids; i++) {
3550 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3551 found_sid = true;
3555 torture_assert(tctx, !found_sid,
3556 "should not have listed privileged account");
3560 struct lsa_EnumAccountRights r;
3561 struct lsa_RightSet user_rights;
3563 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3565 r.in.handle = lsa_handle;
3566 r.in.sid = user_sid;
3567 r.out.rights = &user_rights;
3569 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3570 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3571 "Failed to enum rights for account");
3574 return ret;
3577 static bool test_user_ops(struct dcerpc_pipe *p,
3578 struct torture_context *tctx,
3579 struct policy_handle *user_handle,
3580 struct policy_handle *domain_handle,
3581 const struct dom_sid *domain_sid,
3582 uint32_t base_acct_flags,
3583 const char *base_acct_name, enum torture_samr_choice which_ops,
3584 struct cli_credentials *machine_credentials)
3586 char *password = NULL;
3587 struct samr_QueryUserInfo q;
3588 union samr_UserInfo *info;
3589 NTSTATUS status;
3591 bool ret = true;
3592 int i;
3593 uint32_t rid;
3594 const uint32_t password_fields[] = {
3595 SAMR_FIELD_NT_PASSWORD_PRESENT,
3596 SAMR_FIELD_LM_PASSWORD_PRESENT,
3597 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3601 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3602 if (!NT_STATUS_IS_OK(status)) {
3603 ret = false;
3606 switch (which_ops) {
3607 case TORTURE_SAMR_USER_ATTRIBUTES:
3608 if (!test_QuerySecurity(p, tctx, user_handle)) {
3609 ret = false;
3612 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3613 ret = false;
3616 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3617 ret = false;
3620 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3621 base_acct_name)) {
3622 ret = false;
3625 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3626 ret = false;
3629 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3630 ret = false;
3633 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3634 ret = false;
3636 break;
3637 case TORTURE_SAMR_PASSWORDS:
3638 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3639 char simple_pass[9];
3640 char *v = generate_random_str(tctx, 1);
3642 ZERO_STRUCT(simple_pass);
3643 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3645 torture_comment(tctx, "Testing machine account password policy rules\n");
3647 /* Workstation trust accounts don't seem to need to honour password quality policy */
3648 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3649 ret = false;
3652 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3653 ret = false;
3656 /* reset again, to allow another 'user' password change */
3657 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3658 ret = false;
3661 /* Try a 'short' password */
3662 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3663 ret = false;
3666 /* Try a compleatly random password */
3667 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3668 ret = false;
3672 for (i = 0; password_fields[i]; i++) {
3673 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3674 ret = false;
3677 /* check it was set right */
3678 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3679 ret = false;
3683 for (i = 0; password_fields[i]; i++) {
3684 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3685 ret = false;
3688 /* check it was set right */
3689 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3690 ret = false;
3694 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3695 ret = false;
3698 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3699 ret = false;
3702 if (torture_setting_bool(tctx, "samba4", false)) {
3703 torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
3704 } else {
3706 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3707 ret = false;
3710 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3711 ret = false;
3714 for (i = 0; password_fields[i]; i++) {
3716 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3717 /* we need to skip as that would break
3718 * the ChangePasswordUser3 verify */
3719 continue;
3722 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3723 ret = false;
3726 /* check it was set right */
3727 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3728 ret = false;
3733 q.in.user_handle = user_handle;
3734 q.in.level = 5;
3735 q.out.info = &info;
3737 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3738 if (!NT_STATUS_IS_OK(status)) {
3739 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
3740 q.in.level, nt_errstr(status));
3741 ret = false;
3742 } else {
3743 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3744 if ((info->info5.acct_flags) != expected_flags) {
3745 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3746 info->info5.acct_flags,
3747 expected_flags);
3748 /* FIXME: GD */
3749 if (!torture_setting_bool(tctx, "samba3", false)) {
3750 ret = false;
3753 if (info->info5.rid != rid) {
3754 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3755 info->info5.rid, rid);
3760 break;
3762 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3764 /* test last password change timestamp behaviour */
3765 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3766 base_acct_name,
3767 user_handle, &password,
3768 machine_credentials)) {
3769 ret = false;
3772 if (ret == true) {
3773 torture_comment(tctx, "pwdLastSet test succeeded\n");
3774 } else {
3775 torture_warning(tctx, "pwdLastSet test failed\n");
3778 break;
3780 case TORTURE_SAMR_USER_PRIVILEGES: {
3782 struct dcerpc_pipe *lp;
3783 struct policy_handle *lsa_handle;
3785 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3786 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3788 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3789 ret = false;
3792 if (!test_DeleteUser_with_privs(p, lp, tctx,
3793 domain_handle, lsa_handle, user_handle,
3794 domain_sid, rid,
3795 machine_credentials)) {
3796 ret = false;
3799 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3800 ret = false;
3803 if (!ret) {
3804 torture_warning(tctx, "privileged user delete test failed\n");
3807 break;
3809 case TORTURE_SAMR_OTHER:
3810 /* We just need the account to exist */
3811 break;
3813 return ret;
3816 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3817 struct policy_handle *alias_handle,
3818 const struct dom_sid *domain_sid)
3820 bool ret = true;
3822 if (!torture_setting_bool(tctx, "samba3", false)) {
3823 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3824 ret = false;
3828 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3829 ret = false;
3832 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3833 ret = false;
3836 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3837 ret = false;
3840 if (torture_setting_bool(tctx, "samba3", false) ||
3841 torture_setting_bool(tctx, "samba4", false)) {
3842 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
3843 return ret;
3846 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3847 ret = false;
3850 return ret;
3854 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3855 struct policy_handle *user_handle)
3857 struct samr_DeleteUser d;
3858 NTSTATUS status;
3859 torture_comment(tctx, "Testing DeleteUser\n");
3861 d.in.user_handle = user_handle;
3862 d.out.user_handle = user_handle;
3864 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3865 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3867 return true;
3870 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3871 struct torture_context *tctx,
3872 struct policy_handle *handle, const char *name)
3874 NTSTATUS status;
3875 struct samr_DeleteUser d;
3876 struct policy_handle user_handle;
3877 uint32_t rid;
3879 status = test_LookupName(p, tctx, handle, name, &rid);
3880 if (!NT_STATUS_IS_OK(status)) {
3881 goto failed;
3884 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3885 if (!NT_STATUS_IS_OK(status)) {
3886 goto failed;
3889 d.in.user_handle = &user_handle;
3890 d.out.user_handle = &user_handle;
3891 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3892 if (!NT_STATUS_IS_OK(status)) {
3893 goto failed;
3896 return true;
3898 failed:
3899 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3900 return false;
3904 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3905 struct torture_context *tctx,
3906 struct policy_handle *handle, const char *name)
3908 NTSTATUS status;
3909 struct samr_OpenGroup r;
3910 struct samr_DeleteDomainGroup d;
3911 struct policy_handle group_handle;
3912 uint32_t rid;
3914 status = test_LookupName(p, tctx, handle, name, &rid);
3915 if (!NT_STATUS_IS_OK(status)) {
3916 goto failed;
3919 r.in.domain_handle = handle;
3920 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3921 r.in.rid = rid;
3922 r.out.group_handle = &group_handle;
3923 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3924 if (!NT_STATUS_IS_OK(status)) {
3925 goto failed;
3928 d.in.group_handle = &group_handle;
3929 d.out.group_handle = &group_handle;
3930 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3931 if (!NT_STATUS_IS_OK(status)) {
3932 goto failed;
3935 return true;
3937 failed:
3938 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3939 return false;
3943 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3944 struct torture_context *tctx,
3945 struct policy_handle *domain_handle,
3946 const char *name)
3948 NTSTATUS status;
3949 struct samr_OpenAlias r;
3950 struct samr_DeleteDomAlias d;
3951 struct policy_handle alias_handle;
3952 uint32_t rid;
3954 torture_comment(tctx, "testing DeleteAlias_byname\n");
3956 status = test_LookupName(p, tctx, domain_handle, name, &rid);
3957 if (!NT_STATUS_IS_OK(status)) {
3958 goto failed;
3961 r.in.domain_handle = domain_handle;
3962 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3963 r.in.rid = rid;
3964 r.out.alias_handle = &alias_handle;
3965 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3966 if (!NT_STATUS_IS_OK(status)) {
3967 goto failed;
3970 d.in.alias_handle = &alias_handle;
3971 d.out.alias_handle = &alias_handle;
3972 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3973 if (!NT_STATUS_IS_OK(status)) {
3974 goto failed;
3977 return true;
3979 failed:
3980 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3981 return false;
3984 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3985 struct torture_context *tctx,
3986 struct policy_handle *alias_handle)
3988 struct samr_DeleteDomAlias d;
3989 NTSTATUS status;
3990 bool ret = true;
3992 torture_comment(tctx, "Testing DeleteAlias\n");
3994 d.in.alias_handle = alias_handle;
3995 d.out.alias_handle = alias_handle;
3997 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3998 if (!NT_STATUS_IS_OK(status)) {
3999 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(status));
4000 ret = false;
4003 return ret;
4006 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4007 struct policy_handle *domain_handle,
4008 const char *alias_name,
4009 struct policy_handle *alias_handle,
4010 const struct dom_sid *domain_sid,
4011 bool test_alias)
4013 NTSTATUS status;
4014 struct samr_CreateDomAlias r;
4015 struct lsa_String name;
4016 uint32_t rid;
4017 bool ret = true;
4019 init_lsa_String(&name, alias_name);
4020 r.in.domain_handle = domain_handle;
4021 r.in.alias_name = &name;
4022 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4023 r.out.alias_handle = alias_handle;
4024 r.out.rid = &rid;
4026 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
4028 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4030 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4031 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4032 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
4033 return true;
4034 } else {
4035 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4036 nt_errstr(status));
4037 return false;
4041 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4042 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4043 return false;
4045 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4048 if (!NT_STATUS_IS_OK(status)) {
4049 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(status));
4050 return false;
4053 if (!test_alias) {
4054 return ret;
4057 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4058 ret = false;
4061 return ret;
4064 static bool test_ChangePassword(struct dcerpc_pipe *p,
4065 struct torture_context *tctx,
4066 const char *acct_name,
4067 struct policy_handle *domain_handle, char **password)
4069 bool ret = true;
4071 if (!*password) {
4072 return false;
4075 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4076 ret = false;
4079 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4080 ret = false;
4083 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4084 ret = false;
4087 /* test what happens when setting the old password again */
4088 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4089 ret = false;
4093 char simple_pass[9];
4094 char *v = generate_random_str(tctx, 1);
4096 ZERO_STRUCT(simple_pass);
4097 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4099 /* test what happens when picking a simple password */
4100 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4101 ret = false;
4105 /* set samr_SetDomainInfo level 1 with min_length 5 */
4107 struct samr_QueryDomainInfo r;
4108 union samr_DomainInfo *info = NULL;
4109 struct samr_SetDomainInfo s;
4110 uint16_t len_old, len;
4111 uint32_t pwd_prop_old;
4112 int64_t min_pwd_age_old;
4113 NTSTATUS status;
4115 len = 5;
4117 r.in.domain_handle = domain_handle;
4118 r.in.level = 1;
4119 r.out.info = &info;
4121 torture_comment(tctx, "testing samr_QueryDomainInfo level 1\n");
4122 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4123 if (!NT_STATUS_IS_OK(status)) {
4124 return false;
4127 s.in.domain_handle = domain_handle;
4128 s.in.level = 1;
4129 s.in.info = info;
4131 /* remember the old min length, so we can reset it */
4132 len_old = s.in.info->info1.min_password_length;
4133 s.in.info->info1.min_password_length = len;
4134 pwd_prop_old = s.in.info->info1.password_properties;
4135 /* turn off password complexity checks for this test */
4136 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4138 min_pwd_age_old = s.in.info->info1.min_password_age;
4139 s.in.info->info1.min_password_age = 0;
4141 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4142 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4143 if (!NT_STATUS_IS_OK(status)) {
4144 return false;
4147 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
4149 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4150 ret = false;
4153 s.in.info->info1.min_password_length = len_old;
4154 s.in.info->info1.password_properties = pwd_prop_old;
4155 s.in.info->info1.min_password_age = min_pwd_age_old;
4157 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4158 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4159 if (!NT_STATUS_IS_OK(status)) {
4160 return false;
4166 NTSTATUS status;
4167 struct samr_OpenUser r;
4168 struct samr_QueryUserInfo q;
4169 union samr_UserInfo *info;
4170 struct samr_LookupNames n;
4171 struct policy_handle user_handle;
4172 struct samr_Ids rids, types;
4174 n.in.domain_handle = domain_handle;
4175 n.in.num_names = 1;
4176 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4177 n.in.names[0].string = acct_name;
4178 n.out.rids = &rids;
4179 n.out.types = &types;
4181 status = dcerpc_samr_LookupNames(p, tctx, &n);
4182 if (!NT_STATUS_IS_OK(status)) {
4183 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4184 return false;
4187 r.in.domain_handle = domain_handle;
4188 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4189 r.in.rid = n.out.rids->ids[0];
4190 r.out.user_handle = &user_handle;
4192 status = dcerpc_samr_OpenUser(p, tctx, &r);
4193 if (!NT_STATUS_IS_OK(status)) {
4194 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4195 return false;
4198 q.in.user_handle = &user_handle;
4199 q.in.level = 5;
4200 q.out.info = &info;
4202 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4203 if (!NT_STATUS_IS_OK(status)) {
4204 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(status));
4205 return false;
4208 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
4210 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4211 info->info5.last_password_change, true)) {
4212 ret = false;
4216 /* we change passwords twice - this has the effect of verifying
4217 they were changed correctly for the final call */
4218 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4219 ret = false;
4222 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4223 ret = false;
4226 return ret;
4229 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4230 struct policy_handle *domain_handle,
4231 const char *user_name,
4232 struct policy_handle *user_handle_out,
4233 struct dom_sid *domain_sid,
4234 enum torture_samr_choice which_ops,
4235 struct cli_credentials *machine_credentials,
4236 bool test_user)
4239 TALLOC_CTX *user_ctx;
4241 NTSTATUS status;
4242 struct samr_CreateUser r;
4243 struct samr_QueryUserInfo q;
4244 union samr_UserInfo *info;
4245 struct samr_DeleteUser d;
4246 uint32_t rid;
4248 /* This call creates a 'normal' account - check that it really does */
4249 const uint32_t acct_flags = ACB_NORMAL;
4250 struct lsa_String name;
4251 bool ret = true;
4253 struct policy_handle user_handle;
4254 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4255 init_lsa_String(&name, user_name);
4257 r.in.domain_handle = domain_handle;
4258 r.in.account_name = &name;
4259 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4260 r.out.user_handle = &user_handle;
4261 r.out.rid = &rid;
4263 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
4265 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4267 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4268 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4269 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4270 return true;
4271 } else {
4272 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4273 nt_errstr(status));
4274 return false;
4278 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4279 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4280 talloc_free(user_ctx);
4281 return false;
4283 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4286 if (!NT_STATUS_IS_OK(status)) {
4287 talloc_free(user_ctx);
4288 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(status));
4289 return false;
4292 if (!test_user) {
4293 if (user_handle_out) {
4294 *user_handle_out = user_handle;
4296 return ret;
4300 q.in.user_handle = &user_handle;
4301 q.in.level = 16;
4302 q.out.info = &info;
4304 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4305 if (!NT_STATUS_IS_OK(status)) {
4306 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4307 q.in.level, nt_errstr(status));
4308 ret = false;
4309 } else {
4310 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4311 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4312 info->info16.acct_flags,
4313 acct_flags);
4314 ret = false;
4318 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4319 domain_sid, acct_flags, name.string, which_ops,
4320 machine_credentials)) {
4321 ret = false;
4324 if (user_handle_out) {
4325 *user_handle_out = user_handle;
4326 } else {
4327 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
4329 d.in.user_handle = &user_handle;
4330 d.out.user_handle = &user_handle;
4332 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4333 if (!NT_STATUS_IS_OK(status)) {
4334 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4335 ret = false;
4341 talloc_free(user_ctx);
4343 return ret;
4347 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4348 struct policy_handle *domain_handle,
4349 struct dom_sid *domain_sid,
4350 enum torture_samr_choice which_ops,
4351 struct cli_credentials *machine_credentials)
4353 NTSTATUS status;
4354 struct samr_CreateUser2 r;
4355 struct samr_QueryUserInfo q;
4356 union samr_UserInfo *info;
4357 struct samr_DeleteUser d;
4358 struct policy_handle user_handle;
4359 uint32_t rid;
4360 struct lsa_String name;
4361 bool ret = true;
4362 int i;
4364 struct {
4365 uint32_t acct_flags;
4366 const char *account_name;
4367 NTSTATUS nt_status;
4368 } account_types[] = {
4369 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4370 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4371 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4372 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4373 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4374 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4375 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4376 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4377 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4378 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
4379 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4380 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4381 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4382 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4383 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4386 for (i = 0; account_types[i].account_name; i++) {
4387 TALLOC_CTX *user_ctx;
4388 uint32_t acct_flags = account_types[i].acct_flags;
4389 uint32_t access_granted;
4390 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4391 init_lsa_String(&name, account_types[i].account_name);
4393 r.in.domain_handle = domain_handle;
4394 r.in.account_name = &name;
4395 r.in.acct_flags = acct_flags;
4396 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4397 r.out.user_handle = &user_handle;
4398 r.out.access_granted = &access_granted;
4399 r.out.rid = &rid;
4401 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4403 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4405 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4406 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4407 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4408 continue;
4409 } else {
4410 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4411 nt_errstr(status));
4412 ret = false;
4413 continue;
4417 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4418 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4419 talloc_free(user_ctx);
4420 ret = false;
4421 continue;
4423 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4426 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4427 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4428 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4429 ret = false;
4432 if (NT_STATUS_IS_OK(status)) {
4433 q.in.user_handle = &user_handle;
4434 q.in.level = 5;
4435 q.out.info = &info;
4437 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4438 if (!NT_STATUS_IS_OK(status)) {
4439 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4440 q.in.level, nt_errstr(status));
4441 ret = false;
4442 } else {
4443 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4444 if (acct_flags == ACB_NORMAL) {
4445 expected_flags |= ACB_PW_EXPIRED;
4447 if ((info->info5.acct_flags) != expected_flags) {
4448 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4449 info->info5.acct_flags,
4450 expected_flags);
4451 ret = false;
4453 switch (acct_flags) {
4454 case ACB_SVRTRUST:
4455 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4456 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4457 DOMAIN_RID_DCS, info->info5.primary_gid);
4458 ret = false;
4460 break;
4461 case ACB_WSTRUST:
4462 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4463 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4464 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4465 ret = false;
4467 break;
4468 case ACB_NORMAL:
4469 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4470 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4471 DOMAIN_RID_USERS, info->info5.primary_gid);
4472 ret = false;
4474 break;
4478 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4479 domain_sid, acct_flags, name.string, which_ops,
4480 machine_credentials)) {
4481 ret = false;
4484 if (!policy_handle_empty(&user_handle)) {
4485 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
4487 d.in.user_handle = &user_handle;
4488 d.out.user_handle = &user_handle;
4490 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4491 if (!NT_STATUS_IS_OK(status)) {
4492 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4493 ret = false;
4497 talloc_free(user_ctx);
4500 return ret;
4503 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4504 struct torture_context *tctx,
4505 struct policy_handle *handle)
4507 NTSTATUS status;
4508 struct samr_QueryAliasInfo r;
4509 union samr_AliasInfo *info;
4510 uint16_t levels[] = {1, 2, 3};
4511 int i;
4512 bool ret = true;
4514 for (i=0;i<ARRAY_SIZE(levels);i++) {
4515 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
4517 r.in.alias_handle = handle;
4518 r.in.level = levels[i];
4519 r.out.info = &info;
4521 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4522 if (!NT_STATUS_IS_OK(status)) {
4523 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
4524 levels[i], nt_errstr(status));
4525 ret = false;
4529 return ret;
4532 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4533 struct torture_context *tctx,
4534 struct policy_handle *handle)
4536 NTSTATUS status;
4537 struct samr_QueryGroupInfo r;
4538 union samr_GroupInfo *info;
4539 uint16_t levels[] = {1, 2, 3, 4, 5};
4540 int i;
4541 bool ret = true;
4543 for (i=0;i<ARRAY_SIZE(levels);i++) {
4544 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4546 r.in.group_handle = handle;
4547 r.in.level = levels[i];
4548 r.out.info = &info;
4550 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4551 if (!NT_STATUS_IS_OK(status)) {
4552 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4553 levels[i], nt_errstr(status));
4554 ret = false;
4558 return ret;
4561 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4562 struct torture_context *tctx,
4563 struct policy_handle *handle)
4565 NTSTATUS status;
4566 struct samr_QueryGroupMember r;
4567 struct samr_RidTypeArray *rids = NULL;
4568 bool ret = true;
4570 torture_comment(tctx, "Testing QueryGroupMember\n");
4572 r.in.group_handle = handle;
4573 r.out.rids = &rids;
4575 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4576 if (!NT_STATUS_IS_OK(status)) {
4577 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(status));
4578 ret = false;
4581 return ret;
4585 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4586 struct torture_context *tctx,
4587 struct policy_handle *handle)
4589 NTSTATUS status;
4590 struct samr_QueryGroupInfo r;
4591 union samr_GroupInfo *info;
4592 struct samr_SetGroupInfo s;
4593 uint16_t levels[] = {1, 2, 3, 4};
4594 uint16_t set_ok[] = {0, 1, 1, 1};
4595 int i;
4596 bool ret = true;
4598 for (i=0;i<ARRAY_SIZE(levels);i++) {
4599 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4601 r.in.group_handle = handle;
4602 r.in.level = levels[i];
4603 r.out.info = &info;
4605 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4608 levels[i], nt_errstr(status));
4609 ret = false;
4612 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
4614 s.in.group_handle = handle;
4615 s.in.level = levels[i];
4616 s.in.info = *r.out.info;
4618 #if 0
4619 /* disabled this, as it changes the name only from the point of view of samr,
4620 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4621 the name is still reserved, so creating the old name fails, but deleting by the old name
4622 also fails */
4623 if (s.in.level == 2) {
4624 init_lsa_String(&s.in.info->string, "NewName");
4626 #endif
4628 if (s.in.level == 4) {
4629 init_lsa_String(&s.in.info->description, "test description");
4632 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4633 if (set_ok[i]) {
4634 if (!NT_STATUS_IS_OK(status)) {
4635 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
4636 r.in.level, nt_errstr(status));
4637 ret = false;
4638 continue;
4640 } else {
4641 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4642 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4643 r.in.level, nt_errstr(status));
4644 ret = false;
4645 continue;
4650 return ret;
4653 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4654 struct torture_context *tctx,
4655 struct policy_handle *handle)
4657 NTSTATUS status;
4658 struct samr_QueryUserInfo r;
4659 union samr_UserInfo *info;
4660 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4661 11, 12, 13, 14, 16, 17, 20, 21};
4662 int i;
4663 bool ret = true;
4665 for (i=0;i<ARRAY_SIZE(levels);i++) {
4666 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
4668 r.in.user_handle = handle;
4669 r.in.level = levels[i];
4670 r.out.info = &info;
4672 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4673 if (!NT_STATUS_IS_OK(status)) {
4674 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4675 levels[i], nt_errstr(status));
4676 ret = false;
4680 return ret;
4683 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4684 struct torture_context *tctx,
4685 struct policy_handle *handle)
4687 NTSTATUS status;
4688 struct samr_QueryUserInfo2 r;
4689 union samr_UserInfo *info;
4690 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4691 11, 12, 13, 14, 16, 17, 20, 21};
4692 int i;
4693 bool ret = true;
4695 for (i=0;i<ARRAY_SIZE(levels);i++) {
4696 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
4698 r.in.user_handle = handle;
4699 r.in.level = levels[i];
4700 r.out.info = &info;
4702 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4703 if (!NT_STATUS_IS_OK(status)) {
4704 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
4705 levels[i], nt_errstr(status));
4706 ret = false;
4710 return ret;
4713 static bool test_OpenUser(struct dcerpc_pipe *p,
4714 struct torture_context *tctx,
4715 struct policy_handle *handle, uint32_t rid)
4717 NTSTATUS status;
4718 struct samr_OpenUser r;
4719 struct policy_handle user_handle;
4720 bool ret = true;
4722 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4724 r.in.domain_handle = handle;
4725 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4726 r.in.rid = rid;
4727 r.out.user_handle = &user_handle;
4729 status = dcerpc_samr_OpenUser(p, tctx, &r);
4730 if (!NT_STATUS_IS_OK(status)) {
4731 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4732 return false;
4735 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4736 ret = false;
4739 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4740 ret = false;
4743 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4744 ret = false;
4747 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4748 ret = false;
4751 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4752 ret = false;
4755 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4756 ret = false;
4759 return ret;
4762 static bool test_OpenGroup(struct dcerpc_pipe *p,
4763 struct torture_context *tctx,
4764 struct policy_handle *handle, uint32_t rid)
4766 NTSTATUS status;
4767 struct samr_OpenGroup r;
4768 struct policy_handle group_handle;
4769 bool ret = true;
4771 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
4773 r.in.domain_handle = handle;
4774 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4775 r.in.rid = rid;
4776 r.out.group_handle = &group_handle;
4778 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4779 if (!NT_STATUS_IS_OK(status)) {
4780 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4781 return false;
4784 if (!torture_setting_bool(tctx, "samba3", false)) {
4785 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4786 ret = false;
4790 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4791 ret = false;
4794 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4795 ret = false;
4798 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4799 ret = false;
4802 return ret;
4805 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4806 struct policy_handle *handle, uint32_t rid)
4808 NTSTATUS status;
4809 struct samr_OpenAlias r;
4810 struct policy_handle alias_handle;
4811 bool ret = true;
4813 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4815 r.in.domain_handle = handle;
4816 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4817 r.in.rid = rid;
4818 r.out.alias_handle = &alias_handle;
4820 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4821 if (!NT_STATUS_IS_OK(status)) {
4822 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4823 return false;
4826 if (!torture_setting_bool(tctx, "samba3", false)) {
4827 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4828 ret = false;
4832 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4833 ret = false;
4836 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4837 ret = false;
4840 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4841 ret = false;
4844 return ret;
4847 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4848 struct policy_handle *handle, uint32_t rid,
4849 uint32_t acct_flag_mask)
4851 NTSTATUS status;
4852 struct samr_OpenUser r;
4853 struct samr_QueryUserInfo q;
4854 union samr_UserInfo *info;
4855 struct policy_handle user_handle;
4856 bool ret = true;
4858 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4860 r.in.domain_handle = handle;
4861 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4862 r.in.rid = rid;
4863 r.out.user_handle = &user_handle;
4865 status = dcerpc_samr_OpenUser(p, tctx, &r);
4866 if (!NT_STATUS_IS_OK(status)) {
4867 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4868 return false;
4871 q.in.user_handle = &user_handle;
4872 q.in.level = 16;
4873 q.out.info = &info;
4875 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4876 if (!NT_STATUS_IS_OK(status)) {
4877 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
4878 nt_errstr(status));
4879 ret = false;
4880 } else {
4881 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4882 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4883 acct_flag_mask, info->info16.acct_flags, rid);
4884 ret = false;
4888 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4889 ret = false;
4892 return ret;
4895 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4896 struct torture_context *tctx,
4897 struct policy_handle *handle)
4899 NTSTATUS status = STATUS_MORE_ENTRIES;
4900 struct samr_EnumDomainUsers r;
4901 uint32_t mask, resume_handle=0;
4902 int i, mask_idx;
4903 bool ret = true;
4904 struct samr_LookupNames n;
4905 struct samr_LookupRids lr ;
4906 struct lsa_Strings names;
4907 struct samr_Ids rids, types;
4908 struct samr_SamArray *sam = NULL;
4909 uint32_t num_entries = 0;
4911 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4912 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4913 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4914 ACB_PWNOEXP, 0};
4916 torture_comment(tctx, "Testing EnumDomainUsers\n");
4918 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4919 r.in.domain_handle = handle;
4920 r.in.resume_handle = &resume_handle;
4921 r.in.acct_flags = mask = masks[mask_idx];
4922 r.in.max_size = (uint32_t)-1;
4923 r.out.resume_handle = &resume_handle;
4924 r.out.num_entries = &num_entries;
4925 r.out.sam = &sam;
4927 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4928 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4929 !NT_STATUS_IS_OK(status)) {
4930 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(status));
4931 return false;
4934 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4936 if (sam->count == 0) {
4937 continue;
4940 for (i=0;i<sam->count;i++) {
4941 if (mask) {
4942 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4943 ret = false;
4945 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4946 ret = false;
4951 torture_comment(tctx, "Testing LookupNames\n");
4952 n.in.domain_handle = handle;
4953 n.in.num_names = sam->count;
4954 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4955 n.out.rids = &rids;
4956 n.out.types = &types;
4957 for (i=0;i<sam->count;i++) {
4958 n.in.names[i].string = sam->entries[i].name.string;
4960 status = dcerpc_samr_LookupNames(p, tctx, &n);
4961 if (!NT_STATUS_IS_OK(status)) {
4962 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4963 ret = false;
4967 torture_comment(tctx, "Testing LookupRids\n");
4968 lr.in.domain_handle = handle;
4969 lr.in.num_rids = sam->count;
4970 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4971 lr.out.names = &names;
4972 lr.out.types = &types;
4973 for (i=0;i<sam->count;i++) {
4974 lr.in.rids[i] = sam->entries[i].idx;
4976 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4977 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4979 return ret;
4983 try blasting the server with a bunch of sync requests
4985 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4986 struct policy_handle *handle)
4988 NTSTATUS status;
4989 struct samr_EnumDomainUsers r;
4990 uint32_t resume_handle=0;
4991 int i;
4992 #define ASYNC_COUNT 100
4993 struct rpc_request *req[ASYNC_COUNT];
4995 if (!torture_setting_bool(tctx, "dangerous", false)) {
4996 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4999 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5001 r.in.domain_handle = handle;
5002 r.in.resume_handle = &resume_handle;
5003 r.in.acct_flags = 0;
5004 r.in.max_size = (uint32_t)-1;
5005 r.out.resume_handle = &resume_handle;
5007 for (i=0;i<ASYNC_COUNT;i++) {
5008 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5011 for (i=0;i<ASYNC_COUNT;i++) {
5012 status = dcerpc_ndr_request_recv(req[i]);
5013 if (!NT_STATUS_IS_OK(status)) {
5014 torture_warning(tctx, "EnumDomainUsers[%d] failed - %s\n",
5015 i, nt_errstr(status));
5016 return false;
5020 torture_comment(tctx, "%d async requests OK\n", i);
5022 return true;
5025 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5026 struct torture_context *tctx,
5027 struct policy_handle *handle)
5029 NTSTATUS status;
5030 struct samr_EnumDomainGroups r;
5031 uint32_t resume_handle=0;
5032 struct samr_SamArray *sam = NULL;
5033 uint32_t num_entries = 0;
5034 int i;
5035 bool ret = true;
5037 torture_comment(tctx, "Testing EnumDomainGroups\n");
5039 r.in.domain_handle = handle;
5040 r.in.resume_handle = &resume_handle;
5041 r.in.max_size = (uint32_t)-1;
5042 r.out.resume_handle = &resume_handle;
5043 r.out.num_entries = &num_entries;
5044 r.out.sam = &sam;
5046 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5047 if (!NT_STATUS_IS_OK(status)) {
5048 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(status));
5049 return false;
5052 if (!sam) {
5053 return false;
5056 for (i=0;i<sam->count;i++) {
5057 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5058 ret = false;
5062 return ret;
5065 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5066 struct torture_context *tctx,
5067 struct policy_handle *handle)
5069 NTSTATUS status;
5070 struct samr_EnumDomainAliases r;
5071 uint32_t resume_handle=0;
5072 struct samr_SamArray *sam = NULL;
5073 uint32_t num_entries = 0;
5074 int i;
5075 bool ret = true;
5077 torture_comment(tctx, "Testing EnumDomainAliases\n");
5079 r.in.domain_handle = handle;
5080 r.in.resume_handle = &resume_handle;
5081 r.in.max_size = (uint32_t)-1;
5082 r.out.sam = &sam;
5083 r.out.num_entries = &num_entries;
5084 r.out.resume_handle = &resume_handle;
5086 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5087 if (!NT_STATUS_IS_OK(status)) {
5088 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(status));
5089 return false;
5092 if (!sam) {
5093 return false;
5096 for (i=0;i<sam->count;i++) {
5097 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5098 ret = false;
5102 return ret;
5105 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5106 struct torture_context *tctx,
5107 struct policy_handle *handle)
5109 NTSTATUS status;
5110 struct samr_GetDisplayEnumerationIndex r;
5111 bool ret = true;
5112 uint16_t levels[] = {1, 2, 3, 4, 5};
5113 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5114 struct lsa_String name;
5115 uint32_t idx = 0;
5116 int i;
5118 for (i=0;i<ARRAY_SIZE(levels);i++) {
5119 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5121 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5123 r.in.domain_handle = handle;
5124 r.in.level = levels[i];
5125 r.in.name = &name;
5126 r.out.idx = &idx;
5128 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5130 if (ok_lvl[i] &&
5131 !NT_STATUS_IS_OK(status) &&
5132 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5133 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5134 levels[i], nt_errstr(status));
5135 ret = false;
5138 init_lsa_String(&name, "zzzzzzzz");
5140 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5142 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5143 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5144 levels[i], nt_errstr(status));
5145 ret = false;
5149 return ret;
5152 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5153 struct torture_context *tctx,
5154 struct policy_handle *handle)
5156 NTSTATUS status;
5157 struct samr_GetDisplayEnumerationIndex2 r;
5158 bool ret = true;
5159 uint16_t levels[] = {1, 2, 3, 4, 5};
5160 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5161 struct lsa_String name;
5162 uint32_t idx = 0;
5163 int i;
5165 for (i=0;i<ARRAY_SIZE(levels);i++) {
5166 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5168 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5170 r.in.domain_handle = handle;
5171 r.in.level = levels[i];
5172 r.in.name = &name;
5173 r.out.idx = &idx;
5175 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5176 if (ok_lvl[i] &&
5177 !NT_STATUS_IS_OK(status) &&
5178 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5179 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5180 levels[i], nt_errstr(status));
5181 ret = false;
5184 init_lsa_String(&name, "zzzzzzzz");
5186 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5187 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5188 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5189 levels[i], nt_errstr(status));
5190 ret = false;
5194 return ret;
5197 #define STRING_EQUAL_QUERY(s1, s2, user) \
5198 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5199 /* odd, but valid */ \
5200 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5201 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
5202 #s1, user.string, s1.string, s2.string, __location__); \
5203 ret = false; \
5205 #define INT_EQUAL_QUERY(s1, s2, user) \
5206 if (s1 != s2) { \
5207 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5208 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5209 ret = false; \
5212 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5213 struct torture_context *tctx,
5214 struct samr_QueryDisplayInfo *querydisplayinfo,
5215 bool *seen_testuser)
5217 struct samr_OpenUser r;
5218 struct samr_QueryUserInfo q;
5219 union samr_UserInfo *info;
5220 struct policy_handle user_handle;
5221 int i, ret = true;
5222 NTSTATUS status;
5223 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5224 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5225 for (i = 0; ; i++) {
5226 switch (querydisplayinfo->in.level) {
5227 case 1:
5228 if (i >= querydisplayinfo->out.info->info1.count) {
5229 return ret;
5231 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5232 break;
5233 case 2:
5234 if (i >= querydisplayinfo->out.info->info2.count) {
5235 return ret;
5237 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5238 break;
5239 case 3:
5240 /* Groups */
5241 case 4:
5242 case 5:
5243 /* Not interested in validating just the account name */
5244 return true;
5247 r.out.user_handle = &user_handle;
5249 switch (querydisplayinfo->in.level) {
5250 case 1:
5251 case 2:
5252 status = dcerpc_samr_OpenUser(p, tctx, &r);
5253 if (!NT_STATUS_IS_OK(status)) {
5254 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5255 return false;
5259 q.in.user_handle = &user_handle;
5260 q.in.level = 21;
5261 q.out.info = &info;
5262 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5263 if (!NT_STATUS_IS_OK(status)) {
5264 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5265 return false;
5268 switch (querydisplayinfo->in.level) {
5269 case 1:
5270 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5271 *seen_testuser = true;
5273 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5274 info->info21.full_name, info->info21.account_name);
5275 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5276 info->info21.account_name, info->info21.account_name);
5277 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5278 info->info21.description, info->info21.account_name);
5279 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5280 info->info21.rid, info->info21.account_name);
5281 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5282 info->info21.acct_flags, info->info21.account_name);
5284 break;
5285 case 2:
5286 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5287 info->info21.account_name, info->info21.account_name);
5288 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5289 info->info21.description, info->info21.account_name);
5290 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5291 info->info21.rid, info->info21.account_name);
5292 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5293 info->info21.acct_flags, info->info21.account_name);
5295 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5296 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5297 info->info21.account_name.string);
5300 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5301 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5302 info->info21.account_name.string,
5303 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5304 info->info21.acct_flags);
5305 return false;
5308 break;
5311 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5312 return false;
5315 return ret;
5318 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5319 struct torture_context *tctx,
5320 struct policy_handle *handle)
5322 NTSTATUS status;
5323 struct samr_QueryDisplayInfo r;
5324 struct samr_QueryDomainInfo dom_info;
5325 union samr_DomainInfo *info = NULL;
5326 bool ret = true;
5327 uint16_t levels[] = {1, 2, 3, 4, 5};
5328 int i;
5329 bool seen_testuser = false;
5330 uint32_t total_size;
5331 uint32_t returned_size;
5332 union samr_DispInfo disp_info;
5335 for (i=0;i<ARRAY_SIZE(levels);i++) {
5336 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
5338 r.in.start_idx = 0;
5339 status = STATUS_MORE_ENTRIES;
5340 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5341 r.in.domain_handle = handle;
5342 r.in.level = levels[i];
5343 r.in.max_entries = 2;
5344 r.in.buf_size = (uint32_t)-1;
5345 r.out.total_size = &total_size;
5346 r.out.returned_size = &returned_size;
5347 r.out.info = &disp_info;
5349 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5350 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5351 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5352 levels[i], nt_errstr(status));
5353 ret = false;
5355 switch (r.in.level) {
5356 case 1:
5357 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5358 ret = false;
5360 r.in.start_idx += r.out.info->info1.count;
5361 break;
5362 case 2:
5363 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5364 ret = false;
5366 r.in.start_idx += r.out.info->info2.count;
5367 break;
5368 case 3:
5369 r.in.start_idx += r.out.info->info3.count;
5370 break;
5371 case 4:
5372 r.in.start_idx += r.out.info->info4.count;
5373 break;
5374 case 5:
5375 r.in.start_idx += r.out.info->info5.count;
5376 break;
5379 dom_info.in.domain_handle = handle;
5380 dom_info.in.level = 2;
5381 dom_info.out.info = &info;
5383 /* Check number of users returned is correct */
5384 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5385 if (!NT_STATUS_IS_OK(status)) {
5386 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5387 r.in.level, nt_errstr(status));
5388 ret = false;
5389 break;
5391 switch (r.in.level) {
5392 case 1:
5393 case 4:
5394 if (info->general.num_users < r.in.start_idx) {
5395 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5396 r.in.start_idx, info->general.num_groups,
5397 info->general.domain_name.string);
5398 ret = false;
5400 if (!seen_testuser) {
5401 struct policy_handle user_handle;
5402 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5403 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5404 info->general.domain_name.string);
5405 ret = false;
5406 test_samr_handle_Close(p, tctx, &user_handle);
5409 break;
5410 case 3:
5411 case 5:
5412 if (info->general.num_groups != r.in.start_idx) {
5413 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5414 r.in.start_idx, info->general.num_groups,
5415 info->general.domain_name.string);
5416 ret = false;
5419 break;
5424 return ret;
5427 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5428 struct torture_context *tctx,
5429 struct policy_handle *handle)
5431 NTSTATUS status;
5432 struct samr_QueryDisplayInfo2 r;
5433 bool ret = true;
5434 uint16_t levels[] = {1, 2, 3, 4, 5};
5435 int i;
5436 uint32_t total_size;
5437 uint32_t returned_size;
5438 union samr_DispInfo info;
5440 for (i=0;i<ARRAY_SIZE(levels);i++) {
5441 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
5443 r.in.domain_handle = handle;
5444 r.in.level = levels[i];
5445 r.in.start_idx = 0;
5446 r.in.max_entries = 1000;
5447 r.in.buf_size = (uint32_t)-1;
5448 r.out.total_size = &total_size;
5449 r.out.returned_size = &returned_size;
5450 r.out.info = &info;
5452 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5453 if (!NT_STATUS_IS_OK(status)) {
5454 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
5455 levels[i], nt_errstr(status));
5456 ret = false;
5460 return ret;
5463 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5464 struct policy_handle *handle)
5466 NTSTATUS status;
5467 struct samr_QueryDisplayInfo3 r;
5468 bool ret = true;
5469 uint16_t levels[] = {1, 2, 3, 4, 5};
5470 int i;
5471 uint32_t total_size;
5472 uint32_t returned_size;
5473 union samr_DispInfo info;
5475 for (i=0;i<ARRAY_SIZE(levels);i++) {
5476 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5478 r.in.domain_handle = handle;
5479 r.in.level = levels[i];
5480 r.in.start_idx = 0;
5481 r.in.max_entries = 1000;
5482 r.in.buf_size = (uint32_t)-1;
5483 r.out.total_size = &total_size;
5484 r.out.returned_size = &returned_size;
5485 r.out.info = &info;
5487 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5488 if (!NT_STATUS_IS_OK(status)) {
5489 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
5490 levels[i], nt_errstr(status));
5491 ret = false;
5495 return ret;
5499 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5500 struct torture_context *tctx,
5501 struct policy_handle *handle)
5503 NTSTATUS status;
5504 struct samr_QueryDisplayInfo r;
5505 bool ret = true;
5506 uint32_t total_size;
5507 uint32_t returned_size;
5508 union samr_DispInfo info;
5510 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
5512 r.in.domain_handle = handle;
5513 r.in.level = 1;
5514 r.in.start_idx = 0;
5515 r.in.max_entries = 1;
5516 r.in.buf_size = (uint32_t)-1;
5517 r.out.total_size = &total_size;
5518 r.out.returned_size = &returned_size;
5519 r.out.info = &info;
5521 do {
5522 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5523 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5524 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5525 torture_warning(tctx, "expected idx %d but got %d\n",
5526 r.in.start_idx + 1,
5527 r.out.info->info1.entries[0].idx);
5528 break;
5531 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5532 !NT_STATUS_IS_OK(status)) {
5533 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5534 r.in.level, nt_errstr(status));
5535 ret = false;
5536 break;
5538 r.in.start_idx++;
5539 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5540 NT_STATUS_IS_OK(status)) &&
5541 *r.out.returned_size != 0);
5543 return ret;
5546 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5547 struct policy_handle *handle)
5549 NTSTATUS status;
5550 struct samr_QueryDomainInfo r;
5551 union samr_DomainInfo *info = NULL;
5552 struct samr_SetDomainInfo s;
5553 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5554 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5555 int i;
5556 bool ret = true;
5557 const char *domain_comment = talloc_asprintf(tctx,
5558 "Tortured by Samba4 RPC-SAMR: %s",
5559 timestring(tctx, time(NULL)));
5561 s.in.domain_handle = handle;
5562 s.in.level = 4;
5563 s.in.info = talloc(tctx, union samr_DomainInfo);
5565 s.in.info->oem.oem_information.string = domain_comment;
5566 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5567 if (!NT_STATUS_IS_OK(status)) {
5568 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
5569 s.in.level, nt_errstr(status));
5570 return false;
5573 for (i=0;i<ARRAY_SIZE(levels);i++) {
5574 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5576 r.in.domain_handle = handle;
5577 r.in.level = levels[i];
5578 r.out.info = &info;
5580 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5581 if (!NT_STATUS_IS_OK(status)) {
5582 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5583 r.in.level, nt_errstr(status));
5584 ret = false;
5585 continue;
5588 switch (levels[i]) {
5589 case 2:
5590 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5591 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5592 levels[i], info->general.oem_information.string, domain_comment);
5593 if (!torture_setting_bool(tctx, "samba3", false)) {
5594 ret = false;
5597 if (!info->general.primary.string) {
5598 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5599 levels[i]);
5600 ret = false;
5601 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5602 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5603 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5604 levels[i], info->general.primary.string, dcerpc_server_name(p));
5607 break;
5608 case 4:
5609 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5610 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5611 levels[i], info->oem.oem_information.string, domain_comment);
5612 if (!torture_setting_bool(tctx, "samba3", false)) {
5613 ret = false;
5616 break;
5617 case 6:
5618 if (!info->info6.primary.string) {
5619 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5620 levels[i]);
5621 ret = false;
5623 break;
5624 case 11:
5625 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5626 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5627 levels[i], info->general2.general.oem_information.string, domain_comment);
5628 if (!torture_setting_bool(tctx, "samba3", false)) {
5629 ret = false;
5632 break;
5635 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5637 s.in.domain_handle = handle;
5638 s.in.level = levels[i];
5639 s.in.info = info;
5641 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5642 if (set_ok[i]) {
5643 if (!NT_STATUS_IS_OK(status)) {
5644 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
5645 r.in.level, nt_errstr(status));
5646 ret = false;
5647 continue;
5649 } else {
5650 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5651 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5652 r.in.level, nt_errstr(status));
5653 ret = false;
5654 continue;
5658 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5659 if (!NT_STATUS_IS_OK(status)) {
5660 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5661 r.in.level, nt_errstr(status));
5662 ret = false;
5663 continue;
5667 return ret;
5671 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5672 struct policy_handle *handle)
5674 NTSTATUS status;
5675 struct samr_QueryDomainInfo2 r;
5676 union samr_DomainInfo *info = NULL;
5677 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5678 int i;
5679 bool ret = true;
5681 for (i=0;i<ARRAY_SIZE(levels);i++) {
5682 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
5684 r.in.domain_handle = handle;
5685 r.in.level = levels[i];
5686 r.out.info = &info;
5688 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5689 if (!NT_STATUS_IS_OK(status)) {
5690 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
5691 r.in.level, nt_errstr(status));
5692 ret = false;
5693 continue;
5697 return true;
5700 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5701 set of group names. */
5702 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5703 struct policy_handle *handle)
5705 struct samr_EnumDomainGroups q1;
5706 struct samr_QueryDisplayInfo q2;
5707 NTSTATUS status;
5708 uint32_t resume_handle=0;
5709 struct samr_SamArray *sam = NULL;
5710 uint32_t num_entries = 0;
5711 int i;
5712 bool ret = true;
5713 uint32_t total_size;
5714 uint32_t returned_size;
5715 union samr_DispInfo info;
5717 int num_names = 0;
5718 const char **names = NULL;
5720 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5722 q1.in.domain_handle = handle;
5723 q1.in.resume_handle = &resume_handle;
5724 q1.in.max_size = 5;
5725 q1.out.resume_handle = &resume_handle;
5726 q1.out.num_entries = &num_entries;
5727 q1.out.sam = &sam;
5729 status = STATUS_MORE_ENTRIES;
5730 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5731 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5733 if (!NT_STATUS_IS_OK(status) &&
5734 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5735 break;
5737 for (i=0; i<*q1.out.num_entries; i++) {
5738 add_string_to_array(tctx,
5739 sam->entries[i].name.string,
5740 &names, &num_names);
5744 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5746 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5748 q2.in.domain_handle = handle;
5749 q2.in.level = 5;
5750 q2.in.start_idx = 0;
5751 q2.in.max_entries = 5;
5752 q2.in.buf_size = (uint32_t)-1;
5753 q2.out.total_size = &total_size;
5754 q2.out.returned_size = &returned_size;
5755 q2.out.info = &info;
5757 status = STATUS_MORE_ENTRIES;
5758 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5759 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5761 if (!NT_STATUS_IS_OK(status) &&
5762 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5763 break;
5765 for (i=0; i<q2.out.info->info5.count; i++) {
5766 int j;
5767 const char *name = q2.out.info->info5.entries[i].account_name.string;
5768 bool found = false;
5769 for (j=0; j<num_names; j++) {
5770 if (names[j] == NULL)
5771 continue;
5772 if (strequal(names[j], name)) {
5773 names[j] = NULL;
5774 found = true;
5775 break;
5779 if (!found) {
5780 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5781 name);
5782 ret = false;
5785 q2.in.start_idx += q2.out.info->info5.count;
5788 if (!NT_STATUS_IS_OK(status)) {
5789 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
5790 nt_errstr(status));
5791 ret = false;
5794 for (i=0; i<num_names; i++) {
5795 if (names[i] != NULL) {
5796 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5797 names[i]);
5798 ret = false;
5802 return ret;
5805 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5806 struct policy_handle *group_handle)
5808 struct samr_DeleteDomainGroup d;
5809 NTSTATUS status;
5811 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5813 d.in.group_handle = group_handle;
5814 d.out.group_handle = group_handle;
5816 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5817 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5819 return true;
5822 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5823 struct policy_handle *domain_handle)
5825 struct samr_TestPrivateFunctionsDomain r;
5826 NTSTATUS status;
5827 bool ret = true;
5829 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5831 r.in.domain_handle = domain_handle;
5833 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5834 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5836 return ret;
5839 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5840 struct dom_sid *domain_sid,
5841 struct policy_handle *domain_handle)
5843 struct samr_RidToSid r;
5844 NTSTATUS status;
5845 bool ret = true;
5846 struct dom_sid *calc_sid, *out_sid;
5847 int rids[] = { 0, 42, 512, 10200 };
5848 int i;
5850 for (i=0;i<ARRAY_SIZE(rids);i++) {
5851 torture_comment(tctx, "Testing RidToSid\n");
5853 calc_sid = dom_sid_dup(tctx, domain_sid);
5854 r.in.domain_handle = domain_handle;
5855 r.in.rid = rids[i];
5856 r.out.sid = &out_sid;
5858 status = dcerpc_samr_RidToSid(p, tctx, &r);
5859 if (!NT_STATUS_IS_OK(status)) {
5860 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5861 ret = false;
5862 } else {
5863 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5865 if (!dom_sid_equal(calc_sid, out_sid)) {
5866 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
5867 dom_sid_string(tctx, out_sid),
5868 dom_sid_string(tctx, calc_sid));
5869 ret = false;
5874 return ret;
5877 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5878 struct policy_handle *domain_handle)
5880 struct samr_GetBootKeyInformation r;
5881 NTSTATUS status;
5882 bool ret = true;
5883 uint32_t unknown = 0;
5885 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5887 r.in.domain_handle = domain_handle;
5888 r.out.unknown = &unknown;
5890 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5891 if (!NT_STATUS_IS_OK(status)) {
5892 /* w2k3 seems to fail this sometimes and pass it sometimes */
5893 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5896 return ret;
5899 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5900 struct policy_handle *domain_handle,
5901 struct policy_handle *group_handle)
5903 NTSTATUS status;
5904 struct samr_AddGroupMember r;
5905 struct samr_DeleteGroupMember d;
5906 struct samr_QueryGroupMember q;
5907 struct samr_RidTypeArray *rids = NULL;
5908 struct samr_SetMemberAttributesOfGroup s;
5909 uint32_t rid;
5910 bool found_member = false;
5911 int i;
5913 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5914 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5916 r.in.group_handle = group_handle;
5917 r.in.rid = rid;
5918 r.in.flags = 0; /* ??? */
5920 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
5922 d.in.group_handle = group_handle;
5923 d.in.rid = rid;
5925 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5926 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5928 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5929 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5931 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5932 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5934 if (torture_setting_bool(tctx, "samba4", false) ||
5935 torture_setting_bool(tctx, "samba3", false)) {
5936 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
5937 } else {
5938 /* this one is quite strange. I am using random inputs in the
5939 hope of triggering an error that might give us a clue */
5941 s.in.group_handle = group_handle;
5942 s.in.unknown1 = random();
5943 s.in.unknown2 = random();
5945 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5946 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5949 q.in.group_handle = group_handle;
5950 q.out.rids = &rids;
5952 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5953 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5954 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5956 for (i=0; i < rids->count; i++) {
5957 if (rids->rids[i] == rid) {
5958 found_member = true;
5962 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
5964 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5965 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5967 rids = NULL;
5968 found_member = false;
5970 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5971 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5972 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5974 for (i=0; i < rids->count; i++) {
5975 if (rids->rids[i] == rid) {
5976 found_member = true;
5980 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
5982 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5983 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5985 return true;
5989 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5990 struct torture_context *tctx,
5991 struct policy_handle *domain_handle,
5992 const char *group_name,
5993 struct policy_handle *group_handle,
5994 struct dom_sid *domain_sid,
5995 bool test_group)
5997 NTSTATUS status;
5998 struct samr_CreateDomainGroup r;
5999 uint32_t rid;
6000 struct lsa_String name;
6001 bool ret = true;
6003 init_lsa_String(&name, group_name);
6005 r.in.domain_handle = domain_handle;
6006 r.in.name = &name;
6007 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6008 r.out.group_handle = group_handle;
6009 r.out.rid = &rid;
6011 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
6013 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6015 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6016 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6017 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6018 return true;
6019 } else {
6020 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6021 nt_errstr(status));
6022 return false;
6026 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6027 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6028 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6029 nt_errstr(status));
6030 return false;
6032 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6034 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6035 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6037 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6038 nt_errstr(status));
6039 return false;
6041 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6043 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6045 if (!test_group) {
6046 return ret;
6049 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6050 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(status));
6051 ret = false;
6054 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6055 ret = false;
6058 return ret;
6063 its not totally clear what this does. It seems to accept any sid you like.
6065 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6066 struct torture_context *tctx,
6067 struct policy_handle *domain_handle)
6069 NTSTATUS status;
6070 struct samr_RemoveMemberFromForeignDomain r;
6072 r.in.domain_handle = domain_handle;
6073 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6075 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6076 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6078 return true;
6081 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6082 struct torture_context *tctx,
6083 struct policy_handle *domain_handle,
6084 uint32_t *total_num_entries_p)
6086 NTSTATUS status;
6087 struct samr_EnumDomainUsers r;
6088 uint32_t resume_handle = 0;
6089 uint32_t num_entries = 0;
6090 uint32_t total_num_entries = 0;
6091 struct samr_SamArray *sam;
6093 r.in.domain_handle = domain_handle;
6094 r.in.acct_flags = 0;
6095 r.in.max_size = (uint32_t)-1;
6096 r.in.resume_handle = &resume_handle;
6098 r.out.sam = &sam;
6099 r.out.num_entries = &num_entries;
6100 r.out.resume_handle = &resume_handle;
6102 torture_comment(tctx, "Testing EnumDomainUsers\n");
6104 do {
6105 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6106 if (NT_STATUS_IS_ERR(status)) {
6107 torture_assert_ntstatus_ok(tctx, status,
6108 "failed to enumerate users");
6111 total_num_entries += num_entries;
6112 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6114 if (total_num_entries_p) {
6115 *total_num_entries_p = total_num_entries;
6118 return true;
6121 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6122 struct torture_context *tctx,
6123 struct policy_handle *domain_handle,
6124 uint32_t *total_num_entries_p)
6126 NTSTATUS status;
6127 struct samr_EnumDomainGroups r;
6128 uint32_t resume_handle = 0;
6129 uint32_t num_entries = 0;
6130 uint32_t total_num_entries = 0;
6131 struct samr_SamArray *sam;
6133 r.in.domain_handle = domain_handle;
6134 r.in.max_size = (uint32_t)-1;
6135 r.in.resume_handle = &resume_handle;
6137 r.out.sam = &sam;
6138 r.out.num_entries = &num_entries;
6139 r.out.resume_handle = &resume_handle;
6141 torture_comment(tctx, "Testing EnumDomainGroups\n");
6143 do {
6144 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6145 if (NT_STATUS_IS_ERR(status)) {
6146 torture_assert_ntstatus_ok(tctx, status,
6147 "failed to enumerate groups");
6150 total_num_entries += num_entries;
6151 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6153 if (total_num_entries_p) {
6154 *total_num_entries_p = total_num_entries;
6157 return true;
6160 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6161 struct torture_context *tctx,
6162 struct policy_handle *domain_handle,
6163 uint32_t *total_num_entries_p)
6165 NTSTATUS status;
6166 struct samr_EnumDomainAliases r;
6167 uint32_t resume_handle = 0;
6168 uint32_t num_entries = 0;
6169 uint32_t total_num_entries = 0;
6170 struct samr_SamArray *sam;
6172 r.in.domain_handle = domain_handle;
6173 r.in.max_size = (uint32_t)-1;
6174 r.in.resume_handle = &resume_handle;
6176 r.out.sam = &sam;
6177 r.out.num_entries = &num_entries;
6178 r.out.resume_handle = &resume_handle;
6180 torture_comment(tctx, "Testing EnumDomainAliases\n");
6182 do {
6183 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6184 if (NT_STATUS_IS_ERR(status)) {
6185 torture_assert_ntstatus_ok(tctx, status,
6186 "failed to enumerate aliases");
6189 total_num_entries += num_entries;
6190 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6192 if (total_num_entries_p) {
6193 *total_num_entries_p = total_num_entries;
6196 return true;
6199 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
6200 struct torture_context *tctx,
6201 struct policy_handle *handle,
6202 uint16_t level,
6203 uint32_t *total_num_entries_p)
6205 NTSTATUS status;
6206 struct samr_QueryDisplayInfo r;
6207 uint32_t total_num_entries = 0;
6209 r.in.domain_handle = handle;
6210 r.in.level = level;
6211 r.in.start_idx = 0;
6212 r.in.max_entries = (uint32_t)-1;
6213 r.in.buf_size = (uint32_t)-1;
6215 torture_comment(tctx, "Testing QueryDisplayInfo\n");
6217 do {
6218 uint32_t total_size;
6219 uint32_t returned_size;
6220 union samr_DispInfo info;
6222 r.out.total_size = &total_size;
6223 r.out.returned_size = &returned_size;
6224 r.out.info = &info;
6226 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6227 if (NT_STATUS_IS_ERR(status)) {
6228 torture_assert_ntstatus_ok(tctx, status,
6229 "failed to query displayinfo");
6232 if (*r.out.returned_size == 0) {
6233 break;
6236 switch (r.in.level) {
6237 case 1:
6238 total_num_entries += info.info1.count;
6239 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
6240 break;
6241 case 2:
6242 total_num_entries += info.info2.count;
6243 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
6244 break;
6245 case 3:
6246 total_num_entries += info.info3.count;
6247 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
6248 break;
6249 case 4:
6250 total_num_entries += info.info4.count;
6251 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
6252 break;
6253 case 5:
6254 total_num_entries += info.info5.count;
6255 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
6256 break;
6257 default:
6258 return false;
6261 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6263 if (total_num_entries_p) {
6264 *total_num_entries_p = total_num_entries;
6267 return true;
6270 static bool test_ManyObjects(struct dcerpc_pipe *p,
6271 struct torture_context *tctx,
6272 struct policy_handle *domain_handle,
6273 struct dom_sid *domain_sid,
6274 enum torture_samr_choice which_ops)
6276 uint32_t num_total = 1500;
6277 uint32_t num_enum = 0;
6278 uint32_t num_disp = 0;
6279 uint32_t num_created = 0;
6280 uint32_t num_anounced = 0;
6281 bool ret = true;
6282 NTSTATUS status;
6283 uint32_t i;
6285 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
6287 /* query */
6290 struct samr_QueryDomainInfo2 r;
6291 union samr_DomainInfo *info;
6292 r.in.domain_handle = domain_handle;
6293 r.in.level = 2;
6294 r.out.info = &info;
6296 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6297 torture_assert_ntstatus_ok(tctx, status,
6298 "failed to query domain info");
6300 switch (which_ops) {
6301 case TORTURE_SAMR_MANY_ACCOUNTS:
6302 num_anounced = info->general.num_users;
6303 break;
6304 case TORTURE_SAMR_MANY_GROUPS:
6305 num_anounced = info->general.num_groups;
6306 break;
6307 case TORTURE_SAMR_MANY_ALIASES:
6308 num_anounced = info->general.num_aliases;
6309 break;
6310 default:
6311 return false;
6315 /* create */
6317 for (i=0; i < num_total; i++) {
6319 const char *name = NULL;
6321 switch (which_ops) {
6322 case TORTURE_SAMR_MANY_ACCOUNTS:
6323 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6324 ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
6325 break;
6326 case TORTURE_SAMR_MANY_GROUPS:
6327 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6328 ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6329 break;
6330 case TORTURE_SAMR_MANY_ALIASES:
6331 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6332 ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6333 break;
6334 default:
6335 return false;
6337 if (!policy_handle_empty(&handles[i])) {
6338 num_created++;
6342 /* enum */
6344 switch (which_ops) {
6345 case TORTURE_SAMR_MANY_ACCOUNTS:
6346 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6347 break;
6348 case TORTURE_SAMR_MANY_GROUPS:
6349 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6350 break;
6351 case TORTURE_SAMR_MANY_ALIASES:
6352 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6353 break;
6354 default:
6355 return false;
6358 /* dispinfo */
6360 switch (which_ops) {
6361 case TORTURE_SAMR_MANY_ACCOUNTS:
6362 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
6363 break;
6364 case TORTURE_SAMR_MANY_GROUPS:
6365 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
6366 break;
6367 case TORTURE_SAMR_MANY_ALIASES:
6368 /* no aliases in dispinfo */
6369 break;
6370 default:
6371 return false;
6374 /* close or delete */
6376 for (i=0; i < num_total; i++) {
6378 if (policy_handle_empty(&handles[i])) {
6379 continue;
6382 if (torture_setting_bool(tctx, "samba3", false)) {
6383 ret &= test_samr_handle_Close(p, tctx, &handles[i]);
6384 } else {
6385 switch (which_ops) {
6386 case TORTURE_SAMR_MANY_ACCOUNTS:
6387 ret &= test_DeleteUser(p, tctx, &handles[i]);
6388 break;
6389 case TORTURE_SAMR_MANY_GROUPS:
6390 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
6391 break;
6392 case TORTURE_SAMR_MANY_ALIASES:
6393 ret &= test_DeleteAlias(p, tctx, &handles[i]);
6394 break;
6395 default:
6396 return false;
6401 talloc_free(handles);
6403 if (which_ops == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
6404 torture_comment(tctx,
6405 "unexpected number of results (%u) returned in enum call, expected %u\n",
6406 num_enum, num_anounced + num_created);
6408 torture_comment(tctx,
6409 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6410 num_disp, num_anounced + num_created);
6412 return ret;
6415 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6416 struct policy_handle *handle);
6418 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6419 struct policy_handle *handle, struct dom_sid *sid,
6420 enum torture_samr_choice which_ops,
6421 struct cli_credentials *machine_credentials)
6423 NTSTATUS status;
6424 struct samr_OpenDomain r;
6425 struct policy_handle domain_handle;
6426 struct policy_handle alias_handle;
6427 struct policy_handle user_handle;
6428 struct policy_handle group_handle;
6429 bool ret = true;
6431 ZERO_STRUCT(alias_handle);
6432 ZERO_STRUCT(user_handle);
6433 ZERO_STRUCT(group_handle);
6434 ZERO_STRUCT(domain_handle);
6436 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6438 r.in.connect_handle = handle;
6439 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6440 r.in.sid = sid;
6441 r.out.domain_handle = &domain_handle;
6443 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6444 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6446 /* run the domain tests with the main handle closed - this tests
6447 the servers reference counting */
6448 torture_assert(tctx, test_samr_handle_Close(p, tctx, handle), "Failed to close SAMR handle");
6450 switch (which_ops) {
6451 case TORTURE_SAMR_PASSWORDS:
6452 case TORTURE_SAMR_USER_PRIVILEGES:
6453 if (!torture_setting_bool(tctx, "samba3", false)) {
6454 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6456 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6457 if (!ret) {
6458 torture_warning(tctx, "Testing PASSWORDS or PRIVILAGES on domain %s failed!\n", dom_sid_string(tctx, sid));
6460 break;
6461 case TORTURE_SAMR_USER_ATTRIBUTES:
6462 if (!torture_setting_bool(tctx, "samba3", false)) {
6463 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6465 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6466 /* This test needs 'complex' users to validate */
6467 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6468 if (!ret) {
6469 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6471 break;
6472 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6473 if (!torture_setting_bool(tctx, "samba3", false)) {
6474 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6476 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6477 if (!ret) {
6478 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6480 break;
6481 case TORTURE_SAMR_MANY_ACCOUNTS:
6482 case TORTURE_SAMR_MANY_GROUPS:
6483 case TORTURE_SAMR_MANY_ALIASES:
6484 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6485 if (!ret) {
6486 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
6488 break;
6489 case TORTURE_SAMR_OTHER:
6490 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6491 if (!ret) {
6492 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6494 if (!torture_setting_bool(tctx, "samba3", false)) {
6495 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6497 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6498 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6499 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6500 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6501 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6502 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6503 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6504 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6505 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6506 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6507 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6508 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6510 if (torture_setting_bool(tctx, "samba4", false)) {
6511 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6512 } else {
6513 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6514 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6516 ret &= test_GroupList(p, tctx, &domain_handle);
6517 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6518 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6519 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6520 if (!ret) {
6521 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6523 break;
6526 if (!policy_handle_empty(&user_handle) &&
6527 !test_DeleteUser(p, tctx, &user_handle)) {
6528 ret = false;
6531 if (!policy_handle_empty(&alias_handle) &&
6532 !test_DeleteAlias(p, tctx, &alias_handle)) {
6533 ret = false;
6536 if (!policy_handle_empty(&group_handle) &&
6537 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6538 ret = false;
6541 torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
6543 torture_assert(tctx, test_Connect(p, tctx, handle), "Faile to re-connect SAMR handle");
6544 /* reconnect the main handle */
6546 if (!ret) {
6547 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6550 return ret;
6553 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6554 struct policy_handle *handle, const char *domain,
6555 enum torture_samr_choice which_ops,
6556 struct cli_credentials *machine_credentials)
6558 NTSTATUS status;
6559 struct samr_LookupDomain r;
6560 struct dom_sid2 *sid = NULL;
6561 struct lsa_String n1;
6562 struct lsa_String n2;
6563 bool ret = true;
6565 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6567 /* check for correct error codes */
6568 r.in.connect_handle = handle;
6569 r.in.domain_name = &n2;
6570 r.out.sid = &sid;
6571 n2.string = NULL;
6573 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6574 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6576 init_lsa_String(&n2, "xxNODOMAINxx");
6578 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6579 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6581 r.in.connect_handle = handle;
6583 init_lsa_String(&n1, domain);
6584 r.in.domain_name = &n1;
6586 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6587 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6589 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6590 ret = false;
6593 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6594 machine_credentials)) {
6595 ret = false;
6598 return ret;
6602 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6603 struct policy_handle *handle, enum torture_samr_choice which_ops,
6604 struct cli_credentials *machine_credentials)
6606 NTSTATUS status;
6607 struct samr_EnumDomains r;
6608 uint32_t resume_handle = 0;
6609 uint32_t num_entries = 0;
6610 struct samr_SamArray *sam = NULL;
6611 int i;
6612 bool ret = true;
6614 r.in.connect_handle = handle;
6615 r.in.resume_handle = &resume_handle;
6616 r.in.buf_size = (uint32_t)-1;
6617 r.out.resume_handle = &resume_handle;
6618 r.out.num_entries = &num_entries;
6619 r.out.sam = &sam;
6621 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6622 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6624 if (!*r.out.sam) {
6625 return false;
6628 for (i=0;i<sam->count;i++) {
6629 if (!test_LookupDomain(p, tctx, handle,
6630 sam->entries[i].name.string, which_ops,
6631 machine_credentials)) {
6632 ret = false;
6636 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6637 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6639 return ret;
6643 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6644 struct policy_handle *handle)
6646 NTSTATUS status;
6647 struct samr_Connect r;
6648 struct samr_Connect2 r2;
6649 struct samr_Connect3 r3;
6650 struct samr_Connect4 r4;
6651 struct samr_Connect5 r5;
6652 union samr_ConnectInfo info;
6653 struct policy_handle h;
6654 uint32_t level_out = 0;
6655 bool ret = true, got_handle = false;
6657 torture_comment(tctx, "testing samr_Connect\n");
6659 r.in.system_name = 0;
6660 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6661 r.out.connect_handle = &h;
6663 status = dcerpc_samr_Connect(p, tctx, &r);
6664 if (!NT_STATUS_IS_OK(status)) {
6665 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6666 ret = false;
6667 } else {
6668 got_handle = true;
6669 *handle = h;
6672 torture_comment(tctx, "testing samr_Connect2\n");
6674 r2.in.system_name = NULL;
6675 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6676 r2.out.connect_handle = &h;
6678 status = dcerpc_samr_Connect2(p, tctx, &r2);
6679 if (!NT_STATUS_IS_OK(status)) {
6680 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6681 ret = false;
6682 } else {
6683 if (got_handle) {
6684 test_samr_handle_Close(p, tctx, handle);
6686 got_handle = true;
6687 *handle = h;
6690 torture_comment(tctx, "testing samr_Connect3\n");
6692 r3.in.system_name = NULL;
6693 r3.in.unknown = 0;
6694 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6695 r3.out.connect_handle = &h;
6697 status = dcerpc_samr_Connect3(p, tctx, &r3);
6698 if (!NT_STATUS_IS_OK(status)) {
6699 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(status));
6700 ret = false;
6701 } else {
6702 if (got_handle) {
6703 test_samr_handle_Close(p, tctx, handle);
6705 got_handle = true;
6706 *handle = h;
6709 torture_comment(tctx, "testing samr_Connect4\n");
6711 r4.in.system_name = "";
6712 r4.in.client_version = 0;
6713 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6714 r4.out.connect_handle = &h;
6716 status = dcerpc_samr_Connect4(p, tctx, &r4);
6717 if (!NT_STATUS_IS_OK(status)) {
6718 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(status));
6719 ret = false;
6720 } else {
6721 if (got_handle) {
6722 test_samr_handle_Close(p, tctx, handle);
6724 got_handle = true;
6725 *handle = h;
6728 torture_comment(tctx, "testing samr_Connect5\n");
6730 info.info1.client_version = 0;
6731 info.info1.unknown2 = 0;
6733 r5.in.system_name = "";
6734 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6735 r5.in.level_in = 1;
6736 r5.out.level_out = &level_out;
6737 r5.in.info_in = &info;
6738 r5.out.info_out = &info;
6739 r5.out.connect_handle = &h;
6741 status = dcerpc_samr_Connect5(p, tctx, &r5);
6742 if (!NT_STATUS_IS_OK(status)) {
6743 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(status));
6744 ret = false;
6745 } else {
6746 if (got_handle) {
6747 test_samr_handle_Close(p, tctx, handle);
6749 got_handle = true;
6750 *handle = h;
6753 return ret;
6757 bool torture_rpc_samr(struct torture_context *torture)
6759 NTSTATUS status;
6760 struct dcerpc_pipe *p;
6761 bool ret = true;
6762 struct policy_handle handle;
6764 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6765 if (!NT_STATUS_IS_OK(status)) {
6766 return false;
6769 ret &= test_Connect(p, torture, &handle);
6771 if (!torture_setting_bool(torture, "samba3", false)) {
6772 ret &= test_QuerySecurity(p, torture, &handle);
6775 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6777 ret &= test_SetDsrmPassword(p, torture, &handle);
6779 ret &= test_Shutdown(p, torture, &handle);
6781 ret &= test_samr_handle_Close(p, torture, &handle);
6783 return ret;
6787 bool torture_rpc_samr_users(struct torture_context *torture)
6789 NTSTATUS status;
6790 struct dcerpc_pipe *p;
6791 bool ret = true;
6792 struct policy_handle handle;
6794 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6795 if (!NT_STATUS_IS_OK(status)) {
6796 return false;
6799 ret &= test_Connect(p, torture, &handle);
6801 if (!torture_setting_bool(torture, "samba3", false)) {
6802 ret &= test_QuerySecurity(p, torture, &handle);
6805 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6807 ret &= test_SetDsrmPassword(p, torture, &handle);
6809 ret &= test_Shutdown(p, torture, &handle);
6811 ret &= test_samr_handle_Close(p, torture, &handle);
6813 return ret;
6817 bool torture_rpc_samr_passwords(struct torture_context *torture)
6819 NTSTATUS status;
6820 struct dcerpc_pipe *p;
6821 bool ret = true;
6822 struct policy_handle handle;
6824 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6825 if (!NT_STATUS_IS_OK(status)) {
6826 return false;
6829 ret &= test_Connect(p, torture, &handle);
6831 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6833 ret &= test_samr_handle_Close(p, torture, &handle);
6835 return ret;
6838 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6839 struct dcerpc_pipe *p2,
6840 struct cli_credentials *machine_credentials)
6842 NTSTATUS status;
6843 struct dcerpc_pipe *p;
6844 bool ret = true;
6845 struct policy_handle handle;
6847 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6848 if (!NT_STATUS_IS_OK(status)) {
6849 return false;
6852 ret &= test_Connect(p, torture, &handle);
6854 ret &= test_EnumDomains(p, torture, &handle,
6855 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6856 machine_credentials);
6858 ret &= test_samr_handle_Close(p, torture, &handle);
6860 return ret;
6863 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6865 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6866 struct torture_rpc_tcase *tcase;
6868 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6869 &ndr_table_samr,
6870 TEST_ACCOUNT_NAME_PWD);
6872 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6873 torture_rpc_samr_pwdlastset);
6875 return suite;
6878 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6879 struct dcerpc_pipe *p2,
6880 struct cli_credentials *machine_credentials)
6882 NTSTATUS status;
6883 struct dcerpc_pipe *p;
6884 bool ret = true;
6885 struct policy_handle handle;
6887 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6888 if (!NT_STATUS_IS_OK(status)) {
6889 return false;
6892 ret &= test_Connect(p, torture, &handle);
6894 ret &= test_EnumDomains(p, torture, &handle,
6895 TORTURE_SAMR_USER_PRIVILEGES,
6896 machine_credentials);
6898 ret &= test_samr_handle_Close(p, torture, &handle);
6900 return ret;
6903 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6905 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6906 struct torture_rpc_tcase *tcase;
6908 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6909 &ndr_table_samr,
6910 TEST_ACCOUNT_NAME_PWD);
6912 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6913 torture_rpc_samr_users_privileges_delete_user);
6915 return suite;
6918 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6919 struct dcerpc_pipe *p2,
6920 struct cli_credentials *machine_credentials)
6922 NTSTATUS status;
6923 struct dcerpc_pipe *p;
6924 bool ret = true;
6925 struct policy_handle handle;
6927 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6928 if (!NT_STATUS_IS_OK(status)) {
6929 return false;
6932 ret &= test_Connect(p, torture, &handle);
6934 ret &= test_EnumDomains(p, torture, &handle,
6935 TORTURE_SAMR_MANY_ACCOUNTS,
6936 machine_credentials);
6938 ret &= test_samr_handle_Close(p, torture, &handle);
6940 return ret;
6943 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
6944 struct dcerpc_pipe *p2,
6945 struct cli_credentials *machine_credentials)
6947 NTSTATUS status;
6948 struct dcerpc_pipe *p;
6949 bool ret = true;
6950 struct policy_handle handle;
6952 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6953 if (!NT_STATUS_IS_OK(status)) {
6954 return false;
6957 ret &= test_Connect(p, torture, &handle);
6959 ret &= test_EnumDomains(p, torture, &handle,
6960 TORTURE_SAMR_MANY_GROUPS,
6961 machine_credentials);
6963 ret &= test_samr_handle_Close(p, torture, &handle);
6965 return ret;
6968 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
6969 struct dcerpc_pipe *p2,
6970 struct cli_credentials *machine_credentials)
6972 NTSTATUS status;
6973 struct dcerpc_pipe *p;
6974 bool ret = true;
6975 struct policy_handle handle;
6977 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6978 if (!NT_STATUS_IS_OK(status)) {
6979 return false;
6982 ret &= test_Connect(p, torture, &handle);
6984 ret &= test_EnumDomains(p, torture, &handle,
6985 TORTURE_SAMR_MANY_ALIASES,
6986 machine_credentials);
6988 ret &= test_samr_handle_Close(p, torture, &handle);
6990 return ret;
6993 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
6995 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
6996 struct torture_rpc_tcase *tcase;
6998 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6999 &ndr_table_samr,
7000 TEST_ACCOUNT_NAME);
7002 torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
7003 torture_rpc_samr_many_aliases);
7004 torture_rpc_tcase_add_test_creds(tcase, "many_groups",
7005 torture_rpc_samr_many_groups);
7006 torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
7007 torture_rpc_samr_many_accounts);
7009 return suite;