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/>.
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"
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,
54 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
55 struct torture_context *tctx,
56 struct policy_handle *handle);
58 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
59 struct torture_context *tctx,
60 struct policy_handle *handle);
62 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
63 struct torture_context *tctx,
64 struct policy_handle *handle);
66 static bool test_ChangePassword(struct dcerpc_pipe *p,
67 struct torture_context *tctx,
68 const char *acct_name,
69 struct policy_handle *domain_handle, char **password);
71 static void init_lsa_String(struct lsa_String *string, const char *s)
76 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
81 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
83 string->length = length;
84 string->size = length;
85 string->array = (uint16_t *)discard_const(s);
88 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
89 struct policy_handle *handle)
95 r.out.handle = handle;
97 status = dcerpc_samr_Close(p, tctx, &r);
98 torture_assert_ntstatus_ok(tctx, status, "Close");
103 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
104 struct policy_handle *handle)
107 struct samr_Shutdown r;
109 if (!torture_setting_bool(tctx, "dangerous", false)) {
110 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
114 r.in.connect_handle = handle;
116 torture_comment(tctx, "testing samr_Shutdown\n");
118 status = dcerpc_samr_Shutdown(p, tctx, &r);
119 torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
124 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
125 struct policy_handle *handle)
128 struct samr_SetDsrmPassword r;
129 struct lsa_String string;
130 struct samr_Password hash;
132 if (!torture_setting_bool(tctx, "dangerous", false)) {
133 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
136 E_md4hash("TeSTDSRM123", hash.hash);
138 init_lsa_String(&string, "Administrator");
144 torture_comment(tctx, "testing samr_SetDsrmPassword\n");
146 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
147 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
153 static bool test_QuerySecurity(struct dcerpc_pipe *p,
154 struct torture_context *tctx,
155 struct policy_handle *handle)
158 struct samr_QuerySecurity r;
159 struct samr_SetSecurity s;
160 struct sec_desc_buf *sdbuf = NULL;
162 r.in.handle = handle;
164 r.out.sdbuf = &sdbuf;
166 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
167 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
169 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
171 s.in.handle = handle;
175 if (torture_setting_bool(tctx, "samba4", false)) {
176 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
179 status = dcerpc_samr_SetSecurity(p, tctx, &s);
180 torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
182 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
183 torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
189 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
190 struct policy_handle *handle, uint32_t base_acct_flags,
191 const char *base_account_name)
194 struct samr_SetUserInfo s;
195 struct samr_SetUserInfo2 s2;
196 struct samr_QueryUserInfo q;
197 struct samr_QueryUserInfo q0;
198 union samr_UserInfo u;
199 union samr_UserInfo *info;
201 const char *test_account_name;
203 uint32_t user_extra_flags = 0;
205 if (!torture_setting_bool(tctx, "samba3", false)) {
206 if (base_acct_flags == ACB_NORMAL) {
207 /* When created, accounts are expired by default */
208 user_extra_flags = ACB_PW_EXPIRED;
212 s.in.user_handle = handle;
215 s2.in.user_handle = handle;
218 q.in.user_handle = handle;
222 #define TESTCALL(call, r) \
223 status = dcerpc_samr_ ##call(p, tctx, &r); \
224 if (!NT_STATUS_IS_OK(status)) { \
225 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
226 r.in.level, nt_errstr(status), __location__); \
231 #define STRING_EQUAL(s1, s2, field) \
232 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
233 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
234 #field, s2, __location__); \
239 #define MEM_EQUAL(s1, s2, length, field) \
240 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
241 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
242 #field, (const char *)s2, __location__); \
247 #define INT_EQUAL(i1, i2, field) \
249 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
250 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
255 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
256 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
258 TESTCALL(QueryUserInfo, q) \
260 s2.in.level = lvl1; \
263 ZERO_STRUCT(u.info21); \
264 u.info21.fields_present = fpval; \
266 init_lsa_String(&u.info ## lvl1.field1, value); \
267 TESTCALL(SetUserInfo, s) \
268 TESTCALL(SetUserInfo2, s2) \
269 init_lsa_String(&u.info ## lvl1.field1, ""); \
270 TESTCALL(QueryUserInfo, q); \
272 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
274 TESTCALL(QueryUserInfo, q) \
276 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
279 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
280 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
282 TESTCALL(QueryUserInfo, q) \
284 s2.in.level = lvl1; \
287 ZERO_STRUCT(u.info21); \
288 u.info21.fields_present = fpval; \
290 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
291 TESTCALL(SetUserInfo, s) \
292 TESTCALL(SetUserInfo2, s2) \
293 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
294 TESTCALL(QueryUserInfo, q); \
296 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
298 TESTCALL(QueryUserInfo, q) \
300 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
303 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
304 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
306 TESTCALL(QueryUserInfo, q) \
308 s2.in.level = lvl1; \
311 uint8_t *bits = u.info21.logon_hours.bits; \
312 ZERO_STRUCT(u.info21); \
313 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
314 u.info21.logon_hours.units_per_week = 168; \
315 u.info21.logon_hours.bits = bits; \
317 u.info21.fields_present = fpval; \
319 u.info ## lvl1.field1 = value; \
320 TESTCALL(SetUserInfo, s) \
321 TESTCALL(SetUserInfo2, s2) \
322 u.info ## lvl1.field1 = 0; \
323 TESTCALL(QueryUserInfo, q); \
325 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
327 TESTCALL(QueryUserInfo, q) \
329 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
332 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
333 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
337 do { TESTCALL(QueryUserInfo, q0) } while (0);
339 /* Samba 3 cannot store comment fields atm. - gd */
340 if (!torture_setting_bool(tctx, "samba3", false)) {
341 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
342 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
343 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 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);
467 /* Samba 3 can only store seconds / time_t in passdb - gd */
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),
513 /* Removing the 'disabled' flag doesn't stick - check this */
514 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
516 (base_acct_flags | ACB_DISABLED | user_extra_flags),
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);
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);
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);
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);
579 generate a random password for password change tests
581 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
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;
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);
606 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
607 struct policy_handle *handle, char **password)
610 struct samr_SetUserInfo s;
611 union samr_UserInfo u;
613 DATA_BLOB session_key;
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;
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 printf("SetUserInfo level %u - no session key - %s\n",
637 s.in.level, nt_errstr(status));
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 printf("SetUserInfo level %u failed - %s\n",
648 s.in.level, nt_errstr(status));
658 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
659 struct policy_handle *handle, uint32_t fields_present,
663 struct samr_SetUserInfo s;
664 union samr_UserInfo u;
666 DATA_BLOB session_key;
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;
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 printf("SetUserInfo level %u - no session key - %s\n",
693 s.in.level, nt_errstr(status));
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 printf("SetUserInfo level %u failed - %s\n",
704 s.in.level, nt_errstr(status));
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 printf("SetUserInfo level %u - no session key - %s\n",
715 s.in.level, nt_errstr(status));
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 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
728 s.in.level, nt_errstr(status));
736 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
737 struct policy_handle *handle, bool makeshort,
741 struct samr_SetUserInfo s;
742 union samr_UserInfo u;
744 DATA_BLOB session_key;
745 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
746 uint8_t confounder[16];
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);
762 newpass = samr_rand_pass(tctx, policy_min_pw_len);
765 s.in.user_handle = handle;
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 printf("SetUserInfo level %u - no session key - %s\n",
775 s.in.level, nt_errstr(status));
779 generate_random_buffer((uint8_t *)confounder, 16);
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 printf("SetUserInfo level %u failed - %s\n",
794 s.in.level, nt_errstr(status));
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 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
811 s.in.level, nt_errstr(status));
820 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
821 struct policy_handle *handle, uint32_t fields_present,
825 struct samr_SetUserInfo s;
826 union samr_UserInfo u;
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];
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;
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 printf("SetUserInfo level %u - no session key - %s\n",
858 s.in.level, nt_errstr(status));
862 generate_random_buffer((uint8_t *)confounder, 16);
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 printf("SetUserInfo level %u failed - %s\n",
877 s.in.level, nt_errstr(status));
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 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
894 s.in.level, nt_errstr(status));
901 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
902 struct policy_handle *handle, char **password)
905 struct samr_SetUserInfo s;
906 union samr_UserInfo u;
908 DATA_BLOB session_key;
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;
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 printf("SetUserInfo level %u - no session key - %s\n",
939 s.in.level, nt_errstr(status));
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);
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 printf("SetUserInfo level %u failed - %s\n",
963 s.in.level, nt_errstr(status));
972 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
973 struct policy_handle *handle, uint32_t fields_present,
977 struct samr_SetUserInfo s;
978 union samr_UserInfo u;
980 DATA_BLOB session_key;
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;
1000 E_md4hash(newpass, nt_hash);
1001 E_deshash(newpass, lm_hash);
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 printf("SetUserInfo level %u - no session key - %s\n",
1024 s.in.level, nt_errstr(status));
1028 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
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) {
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 printf("SetUserInfo level %u failed - %s\n",
1051 s.in.level, nt_errstr(status));
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 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1066 s.in.level, nt_errstr(status));
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 printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1079 s.in.level, nt_errstr(status));
1087 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1088 struct torture_context *tctx,
1089 struct policy_handle *handle,
1091 uint32_t fields_present,
1092 char **password, uint8_t password_expired,
1094 bool *matched_expected_error)
1097 NTSTATUS expected_error = NT_STATUS_OK;
1098 struct samr_SetUserInfo s;
1099 struct samr_SetUserInfo2 s2;
1100 union samr_UserInfo u;
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];
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);
1123 s2.in.user_handle = handle;
1125 s2.in.level = level;
1127 s.in.user_handle = handle;
1132 if (fields_present & SAMR_FIELD_COMMENT) {
1133 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
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);
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;
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);
1183 u.info24.password_expired = password_expired;
1185 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
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);
1197 u.info26.password_expired = password_expired;
1199 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1204 status = dcerpc_fetch_session_key(p, &session_key);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 printf("SetUserInfo level %u - no session key - %s\n",
1207 s.in.level, nt_errstr(status));
1211 generate_random_buffer((uint8_t *)confounder, 16);
1214 MD5Update(&ctx, confounder, 16);
1215 MD5Update(&ctx, session_key.data, session_key.length);
1216 MD5Final(confounded_session_key.data, &ctx);
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);
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);
1237 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
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) {
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;
1255 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1258 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1261 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1262 memcpy(&u.info25.password.data[516], confounder, 16);
1265 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1266 memcpy(&u.info26.password.data[516], confounder, 16);
1271 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
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)) {
1287 torture_assert_ntstatus_equal(tctx,
1289 expected_error, "SetUserInfo2 failed");
1291 torture_assert_ntstatus_equal(tctx,
1293 expected_error, "SetUserInfo failed");
1295 *matched_expected_error = true;
1299 if (!NT_STATUS_IS_OK(status)) {
1300 printf("SetUserInfo%s level %u failed - %s\n",
1301 use_setinfo2 ? "2":"", level, nt_errstr(status));
1304 *password = newpass;
1310 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1311 struct policy_handle *handle)
1314 struct samr_SetAliasInfo r;
1315 struct samr_QueryAliasInfo q;
1316 union samr_AliasInfo *info;
1317 uint16_t levels[] = {2, 3};
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: printf("ALIASINFOALL ignored\n"); break;
1338 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 printf("SetAliasInfo level %u failed - %s\n",
1341 levels[i], nt_errstr(status));
1345 q.in.alias_handle = handle;
1346 q.in.level = levels[i];
1349 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 printf("QueryAliasInfo level %u failed - %s\n",
1352 levels[i], nt_errstr(status));
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;
1367 torture_comment(tctx, "testing GetGroupsForUser\n");
1369 r.in.user_handle = user_handle;
1372 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1373 torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1379 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1380 struct lsa_String *domain_name)
1383 struct samr_GetDomPwInfo r;
1384 struct samr_PwInfo info;
1386 r.in.domain_name = domain_name;
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");
1415 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1416 struct policy_handle *handle)
1419 struct samr_GetUserPwInfo r;
1420 struct samr_PwInfo info;
1422 torture_comment(tctx, "Testing GetUserPwInfo\n");
1424 r.in.user_handle = handle;
1427 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1428 torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1433 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1434 struct policy_handle *domain_handle, const char *name,
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;
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];
1456 init_lsa_String(&sname[1], "xxNONAMExx");
1458 status = dcerpc_samr_LookupNames(p, tctx, &n);
1459 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1460 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1461 if (NT_STATUS_IS_OK(status)) {
1462 return NT_STATUS_UNSUCCESSFUL;
1468 status = dcerpc_samr_LookupNames(p, tctx, &n);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1474 init_lsa_String(&sname[0], "xxNONAMExx");
1476 status = dcerpc_samr_LookupNames(p, tctx, &n);
1477 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1478 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1479 if (NT_STATUS_IS_OK(status)) {
1480 return NT_STATUS_UNSUCCESSFUL;
1485 init_lsa_String(&sname[0], "xxNONAMExx");
1486 init_lsa_String(&sname[1], "xxNONAME2xx");
1488 status = dcerpc_samr_LookupNames(p, tctx, &n);
1489 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1490 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1491 if (NT_STATUS_IS_OK(status)) {
1492 return NT_STATUS_UNSUCCESSFUL;
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)
1506 struct samr_OpenUser r;
1509 status = test_LookupName(p, tctx, domain_handle, name, &rid);
1510 if (!NT_STATUS_IS_OK(status)) {
1514 r.in.domain_handle = domain_handle;
1515 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1517 r.out.user_handle = user_handle;
1518 status = dcerpc_samr_OpenUser(p, tctx, &r);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1527 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1528 struct torture_context *tctx,
1529 struct policy_handle *handle)
1532 struct samr_ChangePasswordUser r;
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)) {
1546 printf("Testing ChangePasswordUser for user 'testuser'\n");
1548 printf("old password: %s\n", oldpass);
1549 printf("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 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1581 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
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)
1594 struct samr_ChangePasswordUser r;
1596 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1597 struct policy_handle user_handle;
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;
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)) {
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 */
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 */
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 */
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 */
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 */
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 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1702 /* Unbreak the LM cross */
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 */
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 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1725 /* Unbreak the NT cross */
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)) {
1752 *password = newpass;
1753 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1754 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
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)) {
1790 *password = newpass;
1791 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1792 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
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 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1828 } else if (!NT_STATUS_IS_OK(status)) {
1829 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
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;
1849 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1850 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1851 printf("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 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1859 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
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)
1872 struct samr_OemChangePasswordUser2 r;
1874 struct samr_Password lm_verifier;
1875 struct samr_CryptPassword lm_pass;
1876 struct lsa_AsciiString server, account, account_bad;
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 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1932 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1933 /* Break the old password */
1935 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1936 /* unbreak it for the next operation */
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 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
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;
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 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
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 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
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 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
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 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
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 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2026 } else if (!NT_STATUS_IS_OK(status)) {
2027 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2030 *password = newpass;
2037 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2038 const char *acct_name,
2040 char *newpass, bool allow_password_restriction)
2043 struct samr_ChangePasswordUser2 r;
2045 struct lsa_String server, account;
2046 struct samr_CryptPassword nt_pass, lm_pass;
2047 struct samr_Password nt_verifier, lm_verifier;
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;
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;
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 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2105 } else if (!NT_STATUS_IS_OK(status)) {
2106 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2109 *password = newpass;
2116 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2117 const char *account_string,
2118 int policy_min_pw_len,
2120 const char *newpass,
2121 NTTIME last_password_change,
2122 bool handle_reject_reason)
2125 struct samr_ChangePasswordUser3 r;
2127 struct lsa_String server, account, account_bad;
2128 struct samr_CryptPassword nt_pass, lm_pass;
2129 struct samr_Password nt_verifier, lm_verifier;
2131 uint8_t old_nt_hash[16], new_nt_hash[16];
2132 uint8_t old_lm_hash[16], new_lm_hash[16];
2134 struct samr_DomInfo1 *dominfo = NULL;
2135 struct samr_ChangeReject *reject = NULL;
2137 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2139 if (newpass == NULL) {
2141 if (policy_min_pw_len == 0) {
2142 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2144 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2146 } while (check_password_quality(newpass) == false);
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;
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 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
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 */
2201 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2202 /* Unbreak it again */
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;
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 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
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 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
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;
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)
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 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2274 SAMR_REJECT_OTHER, reject->reason);
2279 /* We tested the order of precendence which is as follows:
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 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2293 SAMR_REJECT_OTHER, reject->reason);
2297 } else if ((dominfo->min_password_length > 0) &&
2298 (strlen(newpass) < dominfo->min_password_length)) {
2300 if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2301 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2302 SAMR_REJECT_TOO_SHORT, reject->reason);
2306 } else if ((dominfo->password_history_length > 0) &&
2307 strequal(oldpass, newpass)) {
2309 if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2310 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2311 SAMR_REJECT_IN_HISTORY, reject->reason);
2314 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2316 if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2317 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2318 SAMR_REJECT_COMPLEXITY, reject->reason);
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 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2335 SAMR_REJECT_OTHER, reject->reason);
2338 /* Perhaps the server has a 'min password age' set? */
2341 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2342 *password = talloc_strdup(tctx, newpass);
2348 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2349 const char *account_string,
2350 struct policy_handle *handle,
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;
2363 struct lsa_String server, account;
2364 struct samr_CryptPassword nt_pass;
2365 struct samr_Password nt_verifier;
2366 DATA_BLOB new_random_pass;
2369 uint8_t old_nt_hash[16], new_nt_hash[16];
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;
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 printf("SetUserInfo level %u - no session key - %s\n",
2396 s.in.level, nt_errstr(status));
2400 generate_random_buffer((uint8_t *)confounder, 16);
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 printf("SetUserInfo level %u failed - %s\n",
2415 s.in.level, nt_errstr(status));
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;
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 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2449 SAMR_REJECT_OTHER, reject->reason);
2452 /* Perhaps the server has a 'min password age' set? */
2454 } else if (!NT_STATUS_IS_OK(status)) {
2455 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
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;
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 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2487 SAMR_REJECT_OTHER, reject->reason);
2490 /* Perhaps the server has a 'min password age' set? */
2493 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2494 *password = talloc_strdup(tctx, newpass);
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;
2508 torture_comment(tctx, "Testing GetMembersInAlias\n");
2510 r.in.alias_handle = alias_handle;
2513 status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2514 torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
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;
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;
2534 status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2535 torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2537 d.in.alias_handle = alias_handle;
2540 status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2541 torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
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;
2552 struct lsa_SidArray sids;
2554 torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2555 a.in.alias_handle = alias_handle;
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;
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");
2589 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2590 struct policy_handle *user_handle)
2592 struct samr_TestPrivateFunctionsUser r;
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");
2605 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2606 struct torture_context *tctx,
2607 struct policy_handle *handle,
2612 uint16_t levels[] = { /* 3, */ 5, 21 };
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;
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);
2634 r.in.user_handle = handle;
2635 r.in.level = levels[i];
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 printf("QueryUserInfo%s level %u failed - %s\n",
2643 use_info2 ? "2":"", levels[i], nt_errstr(status));
2647 switch (levels[i]) {
2649 pwdlastset3 = info->info3.last_password_change;
2652 pwdlastset5 = info->info5.last_password_change;
2655 pwdlastset21 = info->info21.last_password_change;
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);
2673 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2674 struct cli_credentials *machine_credentials,
2675 struct cli_credentials *test_credentials,
2676 struct netlogon_creds_CredentialState *creds,
2677 NTSTATUS expected_result)
2680 struct netr_LogonSamLogon r;
2681 struct netr_Authenticator auth, auth2;
2682 union netr_LogonLevel logon;
2683 union netr_Validation validation;
2684 uint8_t authoritative;
2685 struct netr_NetworkInfo ninfo;
2686 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2687 int flags = CLI_CRED_NTLM_AUTH;
2689 if (lp_client_lanman_auth(tctx->lp_ctx)) {
2690 flags |= CLI_CRED_LANMAN_AUTH;
2693 if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2694 flags |= CLI_CRED_NTLMv2_AUTH;
2697 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2698 &ninfo.identity_info.account_name.string,
2699 &ninfo.identity_info.domain_name.string);
2701 generate_random_buffer(ninfo.challenge,
2702 sizeof(ninfo.challenge));
2703 chal = data_blob_const(ninfo.challenge,
2704 sizeof(ninfo.challenge));
2706 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2707 cli_credentials_get_domain(machine_credentials));
2709 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2715 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2717 ninfo.lm.data = lm_resp.data;
2718 ninfo.lm.length = lm_resp.length;
2720 ninfo.nt.data = nt_resp.data;
2721 ninfo.nt.length = nt_resp.length;
2723 ninfo.identity_info.parameter_control =
2724 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2725 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2726 ninfo.identity_info.logon_id_low = 0;
2727 ninfo.identity_info.logon_id_high = 0;
2728 ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2730 logon.network = &ninfo;
2732 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2733 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2734 r.in.credential = &auth;
2735 r.in.return_authenticator = &auth2;
2736 r.in.logon_level = 2;
2737 r.in.logon = &logon;
2738 r.out.validation = &validation;
2739 r.out.authoritative = &authoritative;
2741 d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2744 netlogon_creds_client_authenticator(creds, &auth);
2746 r.in.validation_level = 2;
2748 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2749 if (!NT_STATUS_IS_OK(status)) {
2750 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2753 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2756 torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2757 "Credential chaining failed");
2762 static bool test_SamLogon(struct torture_context *tctx,
2763 struct dcerpc_pipe *p,
2764 struct cli_credentials *machine_credentials,
2765 struct cli_credentials *test_credentials,
2766 NTSTATUS expected_result)
2768 struct netlogon_creds_CredentialState *creds;
2770 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2774 return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2775 creds, expected_result);
2778 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2779 struct dcerpc_pipe *p,
2780 struct cli_credentials *machine_creds,
2781 const char *acct_name,
2783 NTSTATUS expected_samlogon_result)
2786 struct cli_credentials *test_credentials;
2788 test_credentials = cli_credentials_init(tctx);
2790 cli_credentials_set_workstation(test_credentials,
2791 TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2792 cli_credentials_set_domain(test_credentials,
2793 lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2794 cli_credentials_set_username(test_credentials,
2795 acct_name, CRED_SPECIFIED);
2796 cli_credentials_set_password(test_credentials,
2797 password, CRED_SPECIFIED);
2798 cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2800 printf("testing samlogon as %s@%s password: %s\n",
2801 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2803 if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2804 expected_samlogon_result)) {
2805 torture_warning(tctx, "new password did not work\n");
2812 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2813 struct dcerpc_pipe *np,
2814 struct torture_context *tctx,
2815 struct policy_handle *handle,
2817 uint32_t fields_present,
2818 uint8_t password_expired,
2819 bool *matched_expected_error,
2821 const char *acct_name,
2823 struct cli_credentials *machine_creds,
2824 bool use_queryinfo2,
2826 NTSTATUS expected_samlogon_result)
2828 const char *fields = NULL;
2835 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2842 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2843 "(password_expired: %d) %s\n",
2844 use_setinfo2 ? "2":"", level, password_expired,
2845 fields ? fields : "");
2847 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2852 matched_expected_error)) {
2856 if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2862 if (*matched_expected_error == true) {
2866 if (!test_SamLogon_with_creds(tctx, np,
2870 expected_samlogon_result)) {
2877 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2878 struct torture_context *tctx,
2879 uint32_t acct_flags,
2880 const char *acct_name,
2881 struct policy_handle *handle,
2883 struct cli_credentials *machine_credentials)
2885 int s = 0, q = 0, f = 0, l = 0, z = 0;
2888 bool set_levels[] = { false, true };
2889 bool query_levels[] = { false, true };
2890 uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2891 uint32_t nonzeros[] = { 1, 24 };
2892 uint32_t fields_present[] = {
2894 SAMR_FIELD_EXPIRED_FLAG,
2895 SAMR_FIELD_LAST_PWD_CHANGE,
2896 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2898 SAMR_FIELD_NT_PASSWORD_PRESENT,
2899 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2900 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2901 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2902 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2903 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2904 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2907 struct dcerpc_pipe *np = NULL;
2909 if (torture_setting_bool(tctx, "samba3", false)) {
2911 printf("Samba3 has second granularity, setting delay to: %d\n",
2915 status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2916 if (!NT_STATUS_IS_OK(status)) {
2920 /* set to 1 to enable testing for all possible opcode
2921 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2924 #define TEST_SET_LEVELS 1
2925 #define TEST_QUERY_LEVELS 1
2927 for (l=0; l<ARRAY_SIZE(levels); l++) {
2928 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2929 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2930 #ifdef TEST_SET_LEVELS
2931 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2933 #ifdef TEST_QUERY_LEVELS
2934 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2936 NTTIME pwdlastset_old = 0;
2937 NTTIME pwdlastset_new = 0;
2938 bool matched_expected_error = false;
2939 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2941 torture_comment(tctx, "------------------------------\n"
2942 "Testing pwdLastSet attribute for flags: 0x%08x "
2943 "(s: %d (l: %d), q: %d)\n",
2944 acct_flags, s, levels[l], q);
2946 switch (levels[l]) {
2950 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2951 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2952 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2960 /* set a password and force password change (pwdlastset 0) by
2961 * setting the password expired flag to a non-0 value */
2963 if (!test_SetPassword_level(p, np, tctx, handle,
2967 &matched_expected_error,
2971 machine_credentials,
2974 expected_samlogon_result)) {
2978 if (matched_expected_error == true) {
2979 /* skipping on expected failure */
2983 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2984 * set without the SAMR_FIELD_EXPIRED_FLAG */
2986 switch (levels[l]) {
2990 if ((pwdlastset_new != 0) &&
2991 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2992 torture_comment(tctx, "not considering a non-0 "
2993 "pwdLastSet as a an error as the "
2994 "SAMR_FIELD_EXPIRED_FLAG has not "
2999 if (pwdlastset_new != 0) {
3000 torture_warning(tctx, "pwdLastSet test failed: "
3001 "expected pwdLastSet 0 but got %lld\n",
3008 switch (levels[l]) {
3012 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3013 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3014 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3015 (pwdlastset_old >= pwdlastset_new)) {
3016 torture_warning(tctx, "pwdlastset not increasing\n");
3021 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3022 (pwdlastset_old >= pwdlastset_new)) {
3023 torture_warning(tctx, "pwdlastset not increasing\n");
3033 /* set a password, pwdlastset needs to get updated (increased
3034 * value), password_expired value used here is 0 */
3036 if (!test_SetPassword_level(p, np, tctx, handle,
3040 &matched_expected_error,
3044 machine_credentials,
3047 expected_samlogon_result)) {
3051 /* when a password has been changed, pwdlastset must not be 0 afterwards
3052 * and must be larger then the old value */
3054 switch (levels[l]) {
3059 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3060 * password has been changed, old and new pwdlastset
3061 * need to be the same value */
3063 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3064 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3065 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3067 torture_assert_int_equal(tctx, pwdlastset_old,
3068 pwdlastset_new, "pwdlastset must be equal");
3072 if (pwdlastset_old >= pwdlastset_new) {
3073 torture_warning(tctx, "pwdLastSet test failed: "
3074 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3075 pwdlastset_old, pwdlastset_new);
3078 if (pwdlastset_new == 0) {
3079 torture_warning(tctx, "pwdLastSet test failed: "
3080 "expected non-0 pwdlastset, got: %lld\n",
3086 switch (levels[l]) {
3090 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3091 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3092 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3093 (pwdlastset_old >= pwdlastset_new)) {
3094 torture_warning(tctx, "pwdlastset not increasing\n");
3099 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3100 (pwdlastset_old >= pwdlastset_new)) {
3101 torture_warning(tctx, "pwdlastset not increasing\n");
3107 pwdlastset_old = pwdlastset_new;
3113 /* set a password, pwdlastset needs to get updated (increased
3114 * value), password_expired value used here is 0 */
3116 if (!test_SetPassword_level(p, np, tctx, handle,
3120 &matched_expected_error,
3124 machine_credentials,
3127 expected_samlogon_result)) {
3131 /* when a password has been changed, pwdlastset must not be 0 afterwards
3132 * and must be larger then the old value */
3134 switch (levels[l]) {
3139 /* if no password has been changed, old and new pwdlastset
3140 * need to be the same value */
3142 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3143 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3145 torture_assert_int_equal(tctx, pwdlastset_old,
3146 pwdlastset_new, "pwdlastset must be equal");
3150 if (pwdlastset_old >= pwdlastset_new) {
3151 torture_warning(tctx, "pwdLastSet test failed: "
3152 "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3153 pwdlastset_old, pwdlastset_new);
3156 if (pwdlastset_new == 0) {
3157 torture_warning(tctx, "pwdLastSet test failed: "
3158 "expected non-0 pwdlastset, got: %lld\n",
3166 /* set a password and force password change (pwdlastset 0) by
3167 * setting the password expired flag to a non-0 value */
3169 if (!test_SetPassword_level(p, np, tctx, handle,
3173 &matched_expected_error,
3177 machine_credentials,
3180 expected_samlogon_result)) {
3184 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3185 * set without the SAMR_FIELD_EXPIRED_FLAG */
3187 switch (levels[l]) {
3191 if ((pwdlastset_new != 0) &&
3192 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3193 torture_comment(tctx, "not considering a non-0 "
3194 "pwdLastSet as a an error as the "
3195 "SAMR_FIELD_EXPIRED_FLAG has not "
3200 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3201 * password has been changed, old and new pwdlastset
3202 * need to be the same value */
3204 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3205 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3206 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3208 torture_assert_int_equal(tctx, pwdlastset_old,
3209 pwdlastset_new, "pwdlastset must be equal");
3214 if (pwdlastset_old == pwdlastset_new) {
3215 torture_warning(tctx, "pwdLastSet test failed: "
3216 "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3217 pwdlastset_old, pwdlastset_new);
3221 if (pwdlastset_new != 0) {
3222 torture_warning(tctx, "pwdLastSet test failed: "
3223 "expected pwdLastSet 0, got %lld\n",
3230 switch (levels[l]) {
3234 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3235 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3236 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3237 (pwdlastset_old >= pwdlastset_new)) {
3238 torture_warning(tctx, "pwdlastset not increasing\n");
3243 if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3244 (pwdlastset_old >= pwdlastset_new)) {
3245 torture_warning(tctx, "pwdlastset not increasing\n");
3251 /* if the level we are testing does not have a fields_present
3252 * field, skip all fields present tests by setting f to to
3254 switch (levels[l]) {
3258 f = ARRAY_SIZE(fields_present);
3262 #ifdef TEST_QUERY_LEVELS
3265 #ifdef TEST_SET_LEVELS
3268 } /* fields present */
3272 #undef TEST_SET_LEVELS
3273 #undef TEST_QUERY_LEVELS
3278 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3279 struct dcerpc_pipe *lp,
3280 struct torture_context *tctx,
3281 struct policy_handle *domain_handle,
3282 struct policy_handle *lsa_handle,
3283 struct policy_handle *user_handle,
3284 const struct dom_sid *domain_sid,
3286 struct cli_credentials *machine_credentials)
3291 struct policy_handle lsa_acct_handle;
3292 struct dom_sid *user_sid;
3294 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3297 struct lsa_EnumAccountRights r;
3298 struct lsa_RightSet rights;
3300 printf("Testing LSA EnumAccountRights\n");
3302 r.in.handle = lsa_handle;
3303 r.in.sid = user_sid;
3304 r.out.rights = &rights;
3306 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3307 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3308 "Expected enum rights for account to fail");
3312 struct lsa_RightSet rights;
3313 struct lsa_StringLarge names[2];
3314 struct lsa_AddAccountRights r;
3316 printf("Testing LSA AddAccountRights\n");
3318 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3319 init_lsa_StringLarge(&names[1], NULL);
3322 rights.names = names;
3324 r.in.handle = lsa_handle;
3325 r.in.sid = user_sid;
3326 r.in.rights = &rights;
3328 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3329 torture_assert_ntstatus_ok(tctx, status,
3330 "Failed to add privileges");
3334 struct lsa_EnumAccounts r;
3335 uint32_t resume_handle = 0;
3336 struct lsa_SidArray lsa_sid_array;
3338 bool found_sid = false;
3340 printf("Testing LSA EnumAccounts\n");
3342 r.in.handle = lsa_handle;
3343 r.in.num_entries = 0x1000;
3344 r.in.resume_handle = &resume_handle;
3345 r.out.sids = &lsa_sid_array;
3346 r.out.resume_handle = &resume_handle;
3348 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3349 torture_assert_ntstatus_ok(tctx, status,
3350 "Failed to enum accounts");
3352 for (i=0; i < lsa_sid_array.num_sids; i++) {
3353 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3358 torture_assert(tctx, found_sid,
3359 "failed to list privileged account");
3363 struct lsa_EnumAccountRights r;
3364 struct lsa_RightSet user_rights;
3366 printf("Testing LSA EnumAccountRights\n");
3368 r.in.handle = lsa_handle;
3369 r.in.sid = user_sid;
3370 r.out.rights = &user_rights;
3372 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3373 torture_assert_ntstatus_ok(tctx, status,
3374 "Failed to enum rights for account");
3376 if (user_rights.count < 1) {
3377 torture_warning(tctx, "failed to find newly added rights");
3383 struct lsa_OpenAccount r;
3385 printf("Testing LSA OpenAccount\n");
3387 r.in.handle = lsa_handle;
3388 r.in.sid = user_sid;
3389 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3390 r.out.acct_handle = &lsa_acct_handle;
3392 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3393 torture_assert_ntstatus_ok(tctx, status,
3394 "Failed to open lsa account");
3398 struct lsa_GetSystemAccessAccount r;
3399 uint32_t access_mask;
3401 printf("Testing LSA GetSystemAccessAccount\n");
3403 r.in.handle = &lsa_acct_handle;
3404 r.out.access_mask = &access_mask;
3406 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3407 torture_assert_ntstatus_ok(tctx, status,
3408 "Failed to get lsa system access account");
3414 printf("Testing LSA Close\n");
3416 r.in.handle = &lsa_acct_handle;
3417 r.out.handle = &lsa_acct_handle;
3419 status = dcerpc_lsa_Close(lp, tctx, &r);
3420 torture_assert_ntstatus_ok(tctx, status,
3421 "Failed to close lsa");
3425 struct samr_DeleteUser r;
3427 printf("Testing SAMR DeleteUser\n");
3429 r.in.user_handle = user_handle;
3430 r.out.user_handle = user_handle;
3432 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3433 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3437 struct lsa_EnumAccounts r;
3438 uint32_t resume_handle = 0;
3439 struct lsa_SidArray lsa_sid_array;
3441 bool found_sid = false;
3443 printf("Testing LSA EnumAccounts\n");
3445 r.in.handle = lsa_handle;
3446 r.in.num_entries = 0x1000;
3447 r.in.resume_handle = &resume_handle;
3448 r.out.sids = &lsa_sid_array;
3449 r.out.resume_handle = &resume_handle;
3451 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3452 torture_assert_ntstatus_ok(tctx, status,
3453 "Failed to enum accounts");
3455 for (i=0; i < lsa_sid_array.num_sids; i++) {
3456 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3461 torture_assert(tctx, found_sid,
3462 "failed to list privileged account");
3466 struct lsa_EnumAccountRights r;
3467 struct lsa_RightSet user_rights;
3469 printf("Testing LSA EnumAccountRights\n");
3471 r.in.handle = lsa_handle;
3472 r.in.sid = user_sid;
3473 r.out.rights = &user_rights;
3475 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3476 torture_assert_ntstatus_ok(tctx, status,
3477 "Failed to enum rights for account");
3479 if (user_rights.count < 1) {
3480 torture_warning(tctx, "failed to find newly added rights");
3486 struct lsa_OpenAccount r;
3488 printf("Testing LSA OpenAccount\n");
3490 r.in.handle = lsa_handle;
3491 r.in.sid = user_sid;
3492 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3493 r.out.acct_handle = &lsa_acct_handle;
3495 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3496 torture_assert_ntstatus_ok(tctx, status,
3497 "Failed to open lsa account");
3501 struct lsa_GetSystemAccessAccount r;
3502 uint32_t access_mask;
3504 printf("Testing LSA GetSystemAccessAccount\n");
3506 r.in.handle = &lsa_acct_handle;
3507 r.out.access_mask = &access_mask;
3509 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3510 torture_assert_ntstatus_ok(tctx, status,
3511 "Failed to get lsa system access account");
3515 struct lsa_DeleteObject r;
3517 printf("Testing LSA DeleteObject\n");
3519 r.in.handle = &lsa_acct_handle;
3520 r.out.handle = &lsa_acct_handle;
3522 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3523 torture_assert_ntstatus_ok(tctx, status,
3524 "Failed to delete object");
3528 struct lsa_EnumAccounts r;
3529 uint32_t resume_handle = 0;
3530 struct lsa_SidArray lsa_sid_array;
3532 bool found_sid = false;
3534 printf("Testing LSA EnumAccounts\n");
3536 r.in.handle = lsa_handle;
3537 r.in.num_entries = 0x1000;
3538 r.in.resume_handle = &resume_handle;
3539 r.out.sids = &lsa_sid_array;
3540 r.out.resume_handle = &resume_handle;
3542 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3543 torture_assert_ntstatus_ok(tctx, status,
3544 "Failed to enum accounts");
3546 for (i=0; i < lsa_sid_array.num_sids; i++) {
3547 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3552 torture_assert(tctx, !found_sid,
3553 "should not have listed privileged account");
3557 struct lsa_EnumAccountRights r;
3558 struct lsa_RightSet user_rights;
3560 printf("Testing LSA EnumAccountRights\n");
3562 r.in.handle = lsa_handle;
3563 r.in.sid = user_sid;
3564 r.out.rights = &user_rights;
3566 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3567 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3568 "Failed to enum rights for account");
3574 static bool test_user_ops(struct dcerpc_pipe *p,
3575 struct torture_context *tctx,
3576 struct policy_handle *user_handle,
3577 struct policy_handle *domain_handle,
3578 const struct dom_sid *domain_sid,
3579 uint32_t base_acct_flags,
3580 const char *base_acct_name, enum torture_samr_choice which_ops,
3581 struct cli_credentials *machine_credentials)
3583 char *password = NULL;
3584 struct samr_QueryUserInfo q;
3585 union samr_UserInfo *info;
3591 const uint32_t password_fields[] = {
3592 SAMR_FIELD_NT_PASSWORD_PRESENT,
3593 SAMR_FIELD_LM_PASSWORD_PRESENT,
3594 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3598 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3599 if (!NT_STATUS_IS_OK(status)) {
3603 switch (which_ops) {
3604 case TORTURE_SAMR_USER_ATTRIBUTES:
3605 if (!test_QuerySecurity(p, tctx, user_handle)) {
3609 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3613 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3617 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3622 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3626 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3630 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3634 case TORTURE_SAMR_PASSWORDS:
3635 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3636 char simple_pass[9];
3637 char *v = generate_random_str(tctx, 1);
3639 ZERO_STRUCT(simple_pass);
3640 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3642 printf("Testing machine account password policy rules\n");
3644 /* Workstation trust accounts don't seem to need to honour password quality policy */
3645 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3649 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3653 /* reset again, to allow another 'user' password change */
3654 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3658 /* Try a 'short' password */
3659 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3663 /* Try a compleatly random password */
3664 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3669 for (i = 0; password_fields[i]; i++) {
3670 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3674 /* check it was set right */
3675 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3680 for (i = 0; password_fields[i]; i++) {
3681 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3685 /* check it was set right */
3686 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3691 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3695 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3699 if (torture_setting_bool(tctx, "samba4", false)) {
3700 printf("skipping Set Password level 18 and 21 against Samba4\n");
3703 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3707 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3711 for (i = 0; password_fields[i]; i++) {
3713 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3714 /* we need to skip as that would break
3715 * the ChangePasswordUser3 verify */
3719 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3723 /* check it was set right */
3724 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3730 q.in.user_handle = user_handle;
3734 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3735 if (!NT_STATUS_IS_OK(status)) {
3736 printf("QueryUserInfo level %u failed - %s\n",
3737 q.in.level, nt_errstr(status));
3740 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3741 if ((info->info5.acct_flags) != expected_flags) {
3742 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3743 info->info5.acct_flags,
3746 if (!torture_setting_bool(tctx, "samba3", false)) {
3750 if (info->info5.rid != rid) {
3751 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3752 info->info5.rid, rid);
3759 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3761 /* test last password change timestamp behaviour */
3762 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3764 user_handle, &password,
3765 machine_credentials)) {
3770 torture_comment(tctx, "pwdLastSet test succeeded\n");
3772 torture_warning(tctx, "pwdLastSet test failed\n");
3777 case TORTURE_SAMR_USER_PRIVILEGES: {
3779 struct dcerpc_pipe *lp;
3780 struct policy_handle *lsa_handle;
3782 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3783 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3785 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3789 if (!test_DeleteUser_with_privs(p, lp, tctx,
3790 domain_handle, lsa_handle, user_handle,
3792 machine_credentials)) {
3796 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3801 torture_warning(tctx, "privileged user delete test failed\n");
3806 case TORTURE_SAMR_OTHER:
3807 /* We just need the account to exist */
3813 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3814 struct policy_handle *alias_handle,
3815 const struct dom_sid *domain_sid)
3819 if (!torture_setting_bool(tctx, "samba3", false)) {
3820 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3825 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3829 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3833 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3837 if (torture_setting_bool(tctx, "samba4", false)) {
3838 printf("skipping MultipleMembers Alias tests against Samba4\n");
3842 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3850 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3851 struct policy_handle *user_handle)
3853 struct samr_DeleteUser d;
3855 torture_comment(tctx, "Testing DeleteUser\n");
3857 d.in.user_handle = user_handle;
3858 d.out.user_handle = user_handle;
3860 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3861 torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3866 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3867 struct torture_context *tctx,
3868 struct policy_handle *handle, const char *name)
3871 struct samr_DeleteUser d;
3872 struct policy_handle user_handle;
3875 status = test_LookupName(p, tctx, handle, name, &rid);
3876 if (!NT_STATUS_IS_OK(status)) {
3880 status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3881 if (!NT_STATUS_IS_OK(status)) {
3885 d.in.user_handle = &user_handle;
3886 d.out.user_handle = &user_handle;
3887 status = dcerpc_samr_DeleteUser(p, tctx, &d);
3888 if (!NT_STATUS_IS_OK(status)) {
3895 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3900 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3901 struct torture_context *tctx,
3902 struct policy_handle *handle, const char *name)
3905 struct samr_OpenGroup r;
3906 struct samr_DeleteDomainGroup d;
3907 struct policy_handle group_handle;
3910 status = test_LookupName(p, tctx, handle, name, &rid);
3911 if (!NT_STATUS_IS_OK(status)) {
3915 r.in.domain_handle = handle;
3916 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3918 r.out.group_handle = &group_handle;
3919 status = dcerpc_samr_OpenGroup(p, tctx, &r);
3920 if (!NT_STATUS_IS_OK(status)) {
3924 d.in.group_handle = &group_handle;
3925 d.out.group_handle = &group_handle;
3926 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3927 if (!NT_STATUS_IS_OK(status)) {
3934 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3939 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3940 struct torture_context *tctx,
3941 struct policy_handle *domain_handle,
3945 struct samr_OpenAlias r;
3946 struct samr_DeleteDomAlias d;
3947 struct policy_handle alias_handle;
3950 printf("testing DeleteAlias_byname\n");
3952 status = test_LookupName(p, tctx, domain_handle, name, &rid);
3953 if (!NT_STATUS_IS_OK(status)) {
3957 r.in.domain_handle = domain_handle;
3958 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3960 r.out.alias_handle = &alias_handle;
3961 status = dcerpc_samr_OpenAlias(p, tctx, &r);
3962 if (!NT_STATUS_IS_OK(status)) {
3966 d.in.alias_handle = &alias_handle;
3967 d.out.alias_handle = &alias_handle;
3968 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3969 if (!NT_STATUS_IS_OK(status)) {
3976 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3980 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3981 struct torture_context *tctx,
3982 struct policy_handle *alias_handle)
3984 struct samr_DeleteDomAlias d;
3987 printf("Testing DeleteAlias\n");
3989 d.in.alias_handle = alias_handle;
3990 d.out.alias_handle = alias_handle;
3992 status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3993 if (!NT_STATUS_IS_OK(status)) {
3994 printf("DeleteAlias failed - %s\n", nt_errstr(status));
4001 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4002 struct policy_handle *domain_handle,
4003 const char *alias_name,
4004 struct policy_handle *alias_handle,
4005 const struct dom_sid *domain_sid,
4009 struct samr_CreateDomAlias r;
4010 struct lsa_String name;
4014 init_lsa_String(&name, alias_name);
4015 r.in.domain_handle = domain_handle;
4016 r.in.alias_name = &name;
4017 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4018 r.out.alias_handle = alias_handle;
4021 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
4023 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4025 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4026 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4027 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
4030 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4036 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4037 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4040 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4043 if (!NT_STATUS_IS_OK(status)) {
4044 printf("CreateAlias failed - %s\n", nt_errstr(status));
4052 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4059 static bool test_ChangePassword(struct dcerpc_pipe *p,
4060 struct torture_context *tctx,
4061 const char *acct_name,
4062 struct policy_handle *domain_handle, char **password)
4070 if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4074 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4078 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4082 /* test what happens when setting the old password again */
4083 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4088 char simple_pass[9];
4089 char *v = generate_random_str(tctx, 1);
4091 ZERO_STRUCT(simple_pass);
4092 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4094 /* test what happens when picking a simple password */
4095 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4100 /* set samr_SetDomainInfo level 1 with min_length 5 */
4102 struct samr_QueryDomainInfo r;
4103 union samr_DomainInfo *info = NULL;
4104 struct samr_SetDomainInfo s;
4105 uint16_t len_old, len;
4106 uint32_t pwd_prop_old;
4107 int64_t min_pwd_age_old;
4112 r.in.domain_handle = domain_handle;
4116 printf("testing samr_QueryDomainInfo level 1\n");
4117 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4118 if (!NT_STATUS_IS_OK(status)) {
4122 s.in.domain_handle = domain_handle;
4126 /* remember the old min length, so we can reset it */
4127 len_old = s.in.info->info1.min_password_length;
4128 s.in.info->info1.min_password_length = len;
4129 pwd_prop_old = s.in.info->info1.password_properties;
4130 /* turn off password complexity checks for this test */
4131 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4133 min_pwd_age_old = s.in.info->info1.min_password_age;
4134 s.in.info->info1.min_password_age = 0;
4136 printf("testing samr_SetDomainInfo level 1\n");
4137 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4138 if (!NT_STATUS_IS_OK(status)) {
4142 printf("calling test_ChangePasswordUser3 with too short password\n");
4144 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4148 s.in.info->info1.min_password_length = len_old;
4149 s.in.info->info1.password_properties = pwd_prop_old;
4150 s.in.info->info1.min_password_age = min_pwd_age_old;
4152 printf("testing samr_SetDomainInfo level 1\n");
4153 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4154 if (!NT_STATUS_IS_OK(status)) {
4162 struct samr_OpenUser r;
4163 struct samr_QueryUserInfo q;
4164 union samr_UserInfo *info;
4165 struct samr_LookupNames n;
4166 struct policy_handle user_handle;
4167 struct samr_Ids rids, types;
4169 n.in.domain_handle = domain_handle;
4171 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4172 n.in.names[0].string = acct_name;
4174 n.out.types = &types;
4176 status = dcerpc_samr_LookupNames(p, tctx, &n);
4177 if (!NT_STATUS_IS_OK(status)) {
4178 printf("LookupNames failed - %s\n", nt_errstr(status));
4182 r.in.domain_handle = domain_handle;
4183 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4184 r.in.rid = n.out.rids->ids[0];
4185 r.out.user_handle = &user_handle;
4187 status = dcerpc_samr_OpenUser(p, tctx, &r);
4188 if (!NT_STATUS_IS_OK(status)) {
4189 printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4193 q.in.user_handle = &user_handle;
4197 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4198 if (!NT_STATUS_IS_OK(status)) {
4199 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
4203 printf("calling test_ChangePasswordUser3 with too early password change\n");
4205 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4206 info->info5.last_password_change, true)) {
4211 /* we change passwords twice - this has the effect of verifying
4212 they were changed correctly for the final call */
4213 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4217 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4224 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4225 struct policy_handle *domain_handle,
4226 const char *user_name,
4227 struct policy_handle *user_handle_out,
4228 struct dom_sid *domain_sid,
4229 enum torture_samr_choice which_ops,
4230 struct cli_credentials *machine_credentials,
4234 TALLOC_CTX *user_ctx;
4237 struct samr_CreateUser r;
4238 struct samr_QueryUserInfo q;
4239 union samr_UserInfo *info;
4240 struct samr_DeleteUser d;
4243 /* This call creates a 'normal' account - check that it really does */
4244 const uint32_t acct_flags = ACB_NORMAL;
4245 struct lsa_String name;
4248 struct policy_handle user_handle;
4249 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4250 init_lsa_String(&name, user_name);
4252 r.in.domain_handle = domain_handle;
4253 r.in.account_name = &name;
4254 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4255 r.out.user_handle = &user_handle;
4258 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
4260 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4262 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4263 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4264 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4267 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4273 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4274 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4275 talloc_free(user_ctx);
4278 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4281 if (!NT_STATUS_IS_OK(status)) {
4282 talloc_free(user_ctx);
4283 printf("CreateUser failed - %s\n", nt_errstr(status));
4288 if (user_handle_out) {
4289 *user_handle_out = user_handle;
4295 q.in.user_handle = &user_handle;
4299 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4300 if (!NT_STATUS_IS_OK(status)) {
4301 printf("QueryUserInfo level %u failed - %s\n",
4302 q.in.level, nt_errstr(status));
4305 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4306 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4307 info->info16.acct_flags,
4313 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4314 domain_sid, acct_flags, name.string, which_ops,
4315 machine_credentials)) {
4319 if (user_handle_out) {
4320 *user_handle_out = user_handle;
4322 printf("Testing DeleteUser (createuser test)\n");
4324 d.in.user_handle = &user_handle;
4325 d.out.user_handle = &user_handle;
4327 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4328 if (!NT_STATUS_IS_OK(status)) {
4329 printf("DeleteUser failed - %s\n", nt_errstr(status));
4336 talloc_free(user_ctx);
4342 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4343 struct policy_handle *domain_handle,
4344 struct dom_sid *domain_sid,
4345 enum torture_samr_choice which_ops,
4346 struct cli_credentials *machine_credentials)
4349 struct samr_CreateUser2 r;
4350 struct samr_QueryUserInfo q;
4351 union samr_UserInfo *info;
4352 struct samr_DeleteUser d;
4353 struct policy_handle user_handle;
4355 struct lsa_String name;
4360 uint32_t acct_flags;
4361 const char *account_name;
4363 } account_types[] = {
4364 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4365 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4366 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4367 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4368 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4369 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4370 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4371 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4372 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4373 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4374 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4375 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4376 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4377 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4378 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4381 for (i = 0; account_types[i].account_name; i++) {
4382 TALLOC_CTX *user_ctx;
4383 uint32_t acct_flags = account_types[i].acct_flags;
4384 uint32_t access_granted;
4385 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4386 init_lsa_String(&name, account_types[i].account_name);
4388 r.in.domain_handle = domain_handle;
4389 r.in.account_name = &name;
4390 r.in.acct_flags = acct_flags;
4391 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4392 r.out.user_handle = &user_handle;
4393 r.out.access_granted = &access_granted;
4396 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4398 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4400 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4401 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4402 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4405 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4412 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4413 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4414 talloc_free(user_ctx);
4418 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4421 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4422 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4423 nt_errstr(status), nt_errstr(account_types[i].nt_status));
4427 if (NT_STATUS_IS_OK(status)) {
4428 q.in.user_handle = &user_handle;
4432 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4433 if (!NT_STATUS_IS_OK(status)) {
4434 printf("QueryUserInfo level %u failed - %s\n",
4435 q.in.level, nt_errstr(status));
4438 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4439 if (acct_flags == ACB_NORMAL) {
4440 expected_flags |= ACB_PW_EXPIRED;
4442 if ((info->info5.acct_flags) != expected_flags) {
4443 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4444 info->info5.acct_flags,
4448 switch (acct_flags) {
4450 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4451 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4452 DOMAIN_RID_DCS, info->info5.primary_gid);
4457 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4458 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4459 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4464 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4465 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4466 DOMAIN_RID_USERS, info->info5.primary_gid);
4473 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4474 domain_sid, acct_flags, name.string, which_ops,
4475 machine_credentials)) {
4479 if (!policy_handle_empty(&user_handle)) {
4480 printf("Testing DeleteUser (createuser2 test)\n");
4482 d.in.user_handle = &user_handle;
4483 d.out.user_handle = &user_handle;
4485 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4486 if (!NT_STATUS_IS_OK(status)) {
4487 printf("DeleteUser failed - %s\n", nt_errstr(status));
4492 talloc_free(user_ctx);
4498 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4499 struct torture_context *tctx,
4500 struct policy_handle *handle)
4503 struct samr_QueryAliasInfo r;
4504 union samr_AliasInfo *info;
4505 uint16_t levels[] = {1, 2, 3};
4509 for (i=0;i<ARRAY_SIZE(levels);i++) {
4510 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4512 r.in.alias_handle = handle;
4513 r.in.level = levels[i];
4516 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4517 if (!NT_STATUS_IS_OK(status)) {
4518 printf("QueryAliasInfo level %u failed - %s\n",
4519 levels[i], nt_errstr(status));
4527 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4528 struct torture_context *tctx,
4529 struct policy_handle *handle)
4532 struct samr_QueryGroupInfo r;
4533 union samr_GroupInfo *info;
4534 uint16_t levels[] = {1, 2, 3, 4, 5};
4538 for (i=0;i<ARRAY_SIZE(levels);i++) {
4539 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4541 r.in.group_handle = handle;
4542 r.in.level = levels[i];
4545 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4546 if (!NT_STATUS_IS_OK(status)) {
4547 printf("QueryGroupInfo level %u failed - %s\n",
4548 levels[i], nt_errstr(status));
4556 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4557 struct torture_context *tctx,
4558 struct policy_handle *handle)
4561 struct samr_QueryGroupMember r;
4562 struct samr_RidTypeArray *rids = NULL;
4565 printf("Testing QueryGroupMember\n");
4567 r.in.group_handle = handle;
4570 status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4571 if (!NT_STATUS_IS_OK(status)) {
4572 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4580 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4581 struct torture_context *tctx,
4582 struct policy_handle *handle)
4585 struct samr_QueryGroupInfo r;
4586 union samr_GroupInfo *info;
4587 struct samr_SetGroupInfo s;
4588 uint16_t levels[] = {1, 2, 3, 4};
4589 uint16_t set_ok[] = {0, 1, 1, 1};
4593 for (i=0;i<ARRAY_SIZE(levels);i++) {
4594 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4596 r.in.group_handle = handle;
4597 r.in.level = levels[i];
4600 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4601 if (!NT_STATUS_IS_OK(status)) {
4602 printf("QueryGroupInfo level %u failed - %s\n",
4603 levels[i], nt_errstr(status));
4607 printf("Testing SetGroupInfo level %u\n", levels[i]);
4609 s.in.group_handle = handle;
4610 s.in.level = levels[i];
4611 s.in.info = *r.out.info;
4614 /* disabled this, as it changes the name only from the point of view of samr,
4615 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4616 the name is still reserved, so creating the old name fails, but deleting by the old name
4618 if (s.in.level == 2) {
4619 init_lsa_String(&s.in.info->string, "NewName");
4623 if (s.in.level == 4) {
4624 init_lsa_String(&s.in.info->description, "test description");
4627 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4629 if (!NT_STATUS_IS_OK(status)) {
4630 printf("SetGroupInfo level %u failed - %s\n",
4631 r.in.level, nt_errstr(status));
4636 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4637 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4638 r.in.level, nt_errstr(status));
4648 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4649 struct torture_context *tctx,
4650 struct policy_handle *handle)
4653 struct samr_QueryUserInfo r;
4654 union samr_UserInfo *info;
4655 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4656 11, 12, 13, 14, 16, 17, 20, 21};
4660 for (i=0;i<ARRAY_SIZE(levels);i++) {
4661 printf("Testing QueryUserInfo level %u\n", levels[i]);
4663 r.in.user_handle = handle;
4664 r.in.level = levels[i];
4667 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4668 if (!NT_STATUS_IS_OK(status)) {
4669 printf("QueryUserInfo level %u failed - %s\n",
4670 levels[i], nt_errstr(status));
4678 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4679 struct torture_context *tctx,
4680 struct policy_handle *handle)
4683 struct samr_QueryUserInfo2 r;
4684 union samr_UserInfo *info;
4685 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4686 11, 12, 13, 14, 16, 17, 20, 21};
4690 for (i=0;i<ARRAY_SIZE(levels);i++) {
4691 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4693 r.in.user_handle = handle;
4694 r.in.level = levels[i];
4697 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4698 if (!NT_STATUS_IS_OK(status)) {
4699 printf("QueryUserInfo2 level %u failed - %s\n",
4700 levels[i], nt_errstr(status));
4708 static bool test_OpenUser(struct dcerpc_pipe *p,
4709 struct torture_context *tctx,
4710 struct policy_handle *handle, uint32_t rid)
4713 struct samr_OpenUser r;
4714 struct policy_handle user_handle;
4717 printf("Testing OpenUser(%u)\n", rid);
4719 r.in.domain_handle = handle;
4720 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4722 r.out.user_handle = &user_handle;
4724 status = dcerpc_samr_OpenUser(p, tctx, &r);
4725 if (!NT_STATUS_IS_OK(status)) {
4726 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4730 if (!test_QuerySecurity(p, tctx, &user_handle)) {
4734 if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4738 if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4742 if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4746 if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4750 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4757 static bool test_OpenGroup(struct dcerpc_pipe *p,
4758 struct torture_context *tctx,
4759 struct policy_handle *handle, uint32_t rid)
4762 struct samr_OpenGroup r;
4763 struct policy_handle group_handle;
4766 printf("Testing OpenGroup(%u)\n", rid);
4768 r.in.domain_handle = handle;
4769 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4771 r.out.group_handle = &group_handle;
4773 status = dcerpc_samr_OpenGroup(p, tctx, &r);
4774 if (!NT_STATUS_IS_OK(status)) {
4775 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4779 if (!torture_setting_bool(tctx, "samba3", false)) {
4780 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4785 if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4789 if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4793 if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4800 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4801 struct policy_handle *handle, uint32_t rid)
4804 struct samr_OpenAlias r;
4805 struct policy_handle alias_handle;
4808 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4810 r.in.domain_handle = handle;
4811 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4813 r.out.alias_handle = &alias_handle;
4815 status = dcerpc_samr_OpenAlias(p, tctx, &r);
4816 if (!NT_STATUS_IS_OK(status)) {
4817 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4821 if (!torture_setting_bool(tctx, "samba3", false)) {
4822 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4827 if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4831 if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4835 if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4842 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4843 struct policy_handle *handle, uint32_t rid,
4844 uint32_t acct_flag_mask)
4847 struct samr_OpenUser r;
4848 struct samr_QueryUserInfo q;
4849 union samr_UserInfo *info;
4850 struct policy_handle user_handle;
4853 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4855 r.in.domain_handle = handle;
4856 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4858 r.out.user_handle = &user_handle;
4860 status = dcerpc_samr_OpenUser(p, tctx, &r);
4861 if (!NT_STATUS_IS_OK(status)) {
4862 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4866 q.in.user_handle = &user_handle;
4870 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4871 if (!NT_STATUS_IS_OK(status)) {
4872 printf("QueryUserInfo level 16 failed - %s\n",
4876 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4877 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4878 acct_flag_mask, info->info16.acct_flags, rid);
4883 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4890 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4891 struct torture_context *tctx,
4892 struct policy_handle *handle)
4894 NTSTATUS status = STATUS_MORE_ENTRIES;
4895 struct samr_EnumDomainUsers r;
4896 uint32_t mask, resume_handle=0;
4899 struct samr_LookupNames n;
4900 struct samr_LookupRids lr ;
4901 struct lsa_Strings names;
4902 struct samr_Ids rids, types;
4903 struct samr_SamArray *sam = NULL;
4904 uint32_t num_entries = 0;
4906 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4907 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4908 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4911 printf("Testing EnumDomainUsers\n");
4913 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4914 r.in.domain_handle = handle;
4915 r.in.resume_handle = &resume_handle;
4916 r.in.acct_flags = mask = masks[mask_idx];
4917 r.in.max_size = (uint32_t)-1;
4918 r.out.resume_handle = &resume_handle;
4919 r.out.num_entries = &num_entries;
4922 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4923 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4924 !NT_STATUS_IS_OK(status)) {
4925 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4929 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4931 if (sam->count == 0) {
4935 for (i=0;i<sam->count;i++) {
4937 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4940 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4946 printf("Testing LookupNames\n");
4947 n.in.domain_handle = handle;
4948 n.in.num_names = sam->count;
4949 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4951 n.out.types = &types;
4952 for (i=0;i<sam->count;i++) {
4953 n.in.names[i].string = sam->entries[i].name.string;
4955 status = dcerpc_samr_LookupNames(p, tctx, &n);
4956 if (!NT_STATUS_IS_OK(status)) {
4957 printf("LookupNames failed - %s\n", nt_errstr(status));
4962 printf("Testing LookupRids\n");
4963 lr.in.domain_handle = handle;
4964 lr.in.num_rids = sam->count;
4965 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4966 lr.out.names = &names;
4967 lr.out.types = &types;
4968 for (i=0;i<sam->count;i++) {
4969 lr.in.rids[i] = sam->entries[i].idx;
4971 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4972 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4978 try blasting the server with a bunch of sync requests
4980 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4981 struct policy_handle *handle)
4984 struct samr_EnumDomainUsers r;
4985 uint32_t resume_handle=0;
4987 #define ASYNC_COUNT 100
4988 struct rpc_request *req[ASYNC_COUNT];
4990 if (!torture_setting_bool(tctx, "dangerous", false)) {
4991 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4994 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4996 r.in.domain_handle = handle;
4997 r.in.resume_handle = &resume_handle;
4998 r.in.acct_flags = 0;
4999 r.in.max_size = (uint32_t)-1;
5000 r.out.resume_handle = &resume_handle;
5002 for (i=0;i<ASYNC_COUNT;i++) {
5003 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5006 for (i=0;i<ASYNC_COUNT;i++) {
5007 status = dcerpc_ndr_request_recv(req[i]);
5008 if (!NT_STATUS_IS_OK(status)) {
5009 printf("EnumDomainUsers[%d] failed - %s\n",
5010 i, nt_errstr(status));
5015 torture_comment(tctx, "%d async requests OK\n", i);
5020 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5021 struct torture_context *tctx,
5022 struct policy_handle *handle)
5025 struct samr_EnumDomainGroups r;
5026 uint32_t resume_handle=0;
5027 struct samr_SamArray *sam = NULL;
5028 uint32_t num_entries = 0;
5032 printf("Testing EnumDomainGroups\n");
5034 r.in.domain_handle = handle;
5035 r.in.resume_handle = &resume_handle;
5036 r.in.max_size = (uint32_t)-1;
5037 r.out.resume_handle = &resume_handle;
5038 r.out.num_entries = &num_entries;
5041 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5042 if (!NT_STATUS_IS_OK(status)) {
5043 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5051 for (i=0;i<sam->count;i++) {
5052 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5060 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5061 struct torture_context *tctx,
5062 struct policy_handle *handle)
5065 struct samr_EnumDomainAliases r;
5066 uint32_t resume_handle=0;
5067 struct samr_SamArray *sam = NULL;
5068 uint32_t num_entries = 0;
5072 printf("Testing EnumDomainAliases\n");
5074 r.in.domain_handle = handle;
5075 r.in.resume_handle = &resume_handle;
5076 r.in.max_size = (uint32_t)-1;
5078 r.out.num_entries = &num_entries;
5079 r.out.resume_handle = &resume_handle;
5081 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5082 if (!NT_STATUS_IS_OK(status)) {
5083 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5091 for (i=0;i<sam->count;i++) {
5092 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5100 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5101 struct torture_context *tctx,
5102 struct policy_handle *handle)
5105 struct samr_GetDisplayEnumerationIndex r;
5107 uint16_t levels[] = {1, 2, 3, 4, 5};
5108 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5109 struct lsa_String name;
5113 for (i=0;i<ARRAY_SIZE(levels);i++) {
5114 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5116 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5118 r.in.domain_handle = handle;
5119 r.in.level = levels[i];
5123 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5126 !NT_STATUS_IS_OK(status) &&
5127 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5128 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5129 levels[i], nt_errstr(status));
5133 init_lsa_String(&name, "zzzzzzzz");
5135 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5137 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5138 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5139 levels[i], nt_errstr(status));
5147 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5148 struct torture_context *tctx,
5149 struct policy_handle *handle)
5152 struct samr_GetDisplayEnumerationIndex2 r;
5154 uint16_t levels[] = {1, 2, 3, 4, 5};
5155 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5156 struct lsa_String name;
5160 for (i=0;i<ARRAY_SIZE(levels);i++) {
5161 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5163 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5165 r.in.domain_handle = handle;
5166 r.in.level = levels[i];
5170 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5172 !NT_STATUS_IS_OK(status) &&
5173 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5174 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5175 levels[i], nt_errstr(status));
5179 init_lsa_String(&name, "zzzzzzzz");
5181 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5182 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5183 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5184 levels[i], nt_errstr(status));
5192 #define STRING_EQUAL_QUERY(s1, s2, user) \
5193 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5194 /* odd, but valid */ \
5195 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5196 printf("%s mismatch for %s: %s != %s (%s)\n", \
5197 #s1, user.string, s1.string, s2.string, __location__); \
5200 #define INT_EQUAL_QUERY(s1, s2, user) \
5202 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5203 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5207 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5208 struct torture_context *tctx,
5209 struct samr_QueryDisplayInfo *querydisplayinfo,
5210 bool *seen_testuser)
5212 struct samr_OpenUser r;
5213 struct samr_QueryUserInfo q;
5214 union samr_UserInfo *info;
5215 struct policy_handle user_handle;
5218 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5219 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5220 for (i = 0; ; i++) {
5221 switch (querydisplayinfo->in.level) {
5223 if (i >= querydisplayinfo->out.info->info1.count) {
5226 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5229 if (i >= querydisplayinfo->out.info->info2.count) {
5232 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5238 /* Not interested in validating just the account name */
5242 r.out.user_handle = &user_handle;
5244 switch (querydisplayinfo->in.level) {
5247 status = dcerpc_samr_OpenUser(p, tctx, &r);
5248 if (!NT_STATUS_IS_OK(status)) {
5249 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5254 q.in.user_handle = &user_handle;
5257 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5258 if (!NT_STATUS_IS_OK(status)) {
5259 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5263 switch (querydisplayinfo->in.level) {
5265 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5266 *seen_testuser = true;
5268 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5269 info->info21.full_name, info->info21.account_name);
5270 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5271 info->info21.account_name, info->info21.account_name);
5272 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5273 info->info21.description, info->info21.account_name);
5274 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5275 info->info21.rid, info->info21.account_name);
5276 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5277 info->info21.acct_flags, info->info21.account_name);
5281 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5282 info->info21.account_name, info->info21.account_name);
5283 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5284 info->info21.description, info->info21.account_name);
5285 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5286 info->info21.rid, info->info21.account_name);
5287 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5288 info->info21.acct_flags, info->info21.account_name);
5290 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5291 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5292 info->info21.account_name.string);
5295 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5296 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5297 info->info21.account_name.string,
5298 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5299 info->info21.acct_flags);
5306 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5313 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5314 struct torture_context *tctx,
5315 struct policy_handle *handle)
5318 struct samr_QueryDisplayInfo r;
5319 struct samr_QueryDomainInfo dom_info;
5320 union samr_DomainInfo *info = NULL;
5322 uint16_t levels[] = {1, 2, 3, 4, 5};
5324 bool seen_testuser = false;
5325 uint32_t total_size;
5326 uint32_t returned_size;
5327 union samr_DispInfo disp_info;
5330 for (i=0;i<ARRAY_SIZE(levels);i++) {
5331 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5334 status = STATUS_MORE_ENTRIES;
5335 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5336 r.in.domain_handle = handle;
5337 r.in.level = levels[i];
5338 r.in.max_entries = 2;
5339 r.in.buf_size = (uint32_t)-1;
5340 r.out.total_size = &total_size;
5341 r.out.returned_size = &returned_size;
5342 r.out.info = &disp_info;
5344 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5345 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5346 printf("QueryDisplayInfo level %u failed - %s\n",
5347 levels[i], nt_errstr(status));
5350 switch (r.in.level) {
5352 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5355 r.in.start_idx += r.out.info->info1.count;
5358 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5361 r.in.start_idx += r.out.info->info2.count;
5364 r.in.start_idx += r.out.info->info3.count;
5367 r.in.start_idx += r.out.info->info4.count;
5370 r.in.start_idx += r.out.info->info5.count;
5374 dom_info.in.domain_handle = handle;
5375 dom_info.in.level = 2;
5376 dom_info.out.info = &info;
5378 /* Check number of users returned is correct */
5379 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5380 if (!NT_STATUS_IS_OK(status)) {
5381 printf("QueryDomainInfo level %u failed - %s\n",
5382 r.in.level, nt_errstr(status));
5386 switch (r.in.level) {
5389 if (info->general.num_users < r.in.start_idx) {
5390 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5391 r.in.start_idx, info->general.num_groups,
5392 info->general.domain_name.string);
5395 if (!seen_testuser) {
5396 struct policy_handle user_handle;
5397 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5398 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5399 info->general.domain_name.string);
5401 test_samr_handle_Close(p, tctx, &user_handle);
5407 if (info->general.num_groups != r.in.start_idx) {
5408 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5409 r.in.start_idx, info->general.num_groups,
5410 info->general.domain_name.string);
5422 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5423 struct torture_context *tctx,
5424 struct policy_handle *handle)
5427 struct samr_QueryDisplayInfo2 r;
5429 uint16_t levels[] = {1, 2, 3, 4, 5};
5431 uint32_t total_size;
5432 uint32_t returned_size;
5433 union samr_DispInfo info;
5435 for (i=0;i<ARRAY_SIZE(levels);i++) {
5436 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5438 r.in.domain_handle = handle;
5439 r.in.level = levels[i];
5441 r.in.max_entries = 1000;
5442 r.in.buf_size = (uint32_t)-1;
5443 r.out.total_size = &total_size;
5444 r.out.returned_size = &returned_size;
5447 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5448 if (!NT_STATUS_IS_OK(status)) {
5449 printf("QueryDisplayInfo2 level %u failed - %s\n",
5450 levels[i], nt_errstr(status));
5458 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5459 struct policy_handle *handle)
5462 struct samr_QueryDisplayInfo3 r;
5464 uint16_t levels[] = {1, 2, 3, 4, 5};
5466 uint32_t total_size;
5467 uint32_t returned_size;
5468 union samr_DispInfo info;
5470 for (i=0;i<ARRAY_SIZE(levels);i++) {
5471 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5473 r.in.domain_handle = handle;
5474 r.in.level = levels[i];
5476 r.in.max_entries = 1000;
5477 r.in.buf_size = (uint32_t)-1;
5478 r.out.total_size = &total_size;
5479 r.out.returned_size = &returned_size;
5482 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5483 if (!NT_STATUS_IS_OK(status)) {
5484 printf("QueryDisplayInfo3 level %u failed - %s\n",
5485 levels[i], nt_errstr(status));
5494 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5495 struct torture_context *tctx,
5496 struct policy_handle *handle)
5499 struct samr_QueryDisplayInfo r;
5501 uint32_t total_size;
5502 uint32_t returned_size;
5503 union samr_DispInfo info;
5505 printf("Testing QueryDisplayInfo continuation\n");
5507 r.in.domain_handle = handle;
5510 r.in.max_entries = 1;
5511 r.in.buf_size = (uint32_t)-1;
5512 r.out.total_size = &total_size;
5513 r.out.returned_size = &returned_size;
5517 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5518 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5519 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5520 printf("expected idx %d but got %d\n",
5522 r.out.info->info1.entries[0].idx);
5526 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5527 !NT_STATUS_IS_OK(status)) {
5528 printf("QueryDisplayInfo level %u failed - %s\n",
5529 r.in.level, nt_errstr(status));
5534 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5535 NT_STATUS_IS_OK(status)) &&
5536 *r.out.returned_size != 0);
5541 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5542 struct policy_handle *handle)
5545 struct samr_QueryDomainInfo r;
5546 union samr_DomainInfo *info = NULL;
5547 struct samr_SetDomainInfo s;
5548 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5549 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5552 const char *domain_comment = talloc_asprintf(tctx,
5553 "Tortured by Samba4 RPC-SAMR: %s",
5554 timestring(tctx, time(NULL)));
5556 s.in.domain_handle = handle;
5558 s.in.info = talloc(tctx, union samr_DomainInfo);
5560 s.in.info->oem.oem_information.string = domain_comment;
5561 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5562 if (!NT_STATUS_IS_OK(status)) {
5563 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5564 s.in.level, nt_errstr(status));
5568 for (i=0;i<ARRAY_SIZE(levels);i++) {
5569 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5571 r.in.domain_handle = handle;
5572 r.in.level = levels[i];
5575 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5576 if (!NT_STATUS_IS_OK(status)) {
5577 printf("QueryDomainInfo level %u failed - %s\n",
5578 r.in.level, nt_errstr(status));
5583 switch (levels[i]) {
5585 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5586 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5587 levels[i], info->general.oem_information.string, domain_comment);
5590 if (!info->general.primary.string) {
5591 printf("QueryDomainInfo level %u returned no PDC name\n",
5594 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5595 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5596 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5597 levels[i], info->general.primary.string, dcerpc_server_name(p));
5602 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5603 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5604 levels[i], info->oem.oem_information.string, domain_comment);
5609 if (!info->info6.primary.string) {
5610 printf("QueryDomainInfo level %u returned no PDC name\n",
5616 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5617 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5618 levels[i], info->general2.general.oem_information.string, domain_comment);
5624 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5626 s.in.domain_handle = handle;
5627 s.in.level = levels[i];
5630 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5632 if (!NT_STATUS_IS_OK(status)) {
5633 printf("SetDomainInfo level %u failed - %s\n",
5634 r.in.level, nt_errstr(status));
5639 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5640 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5641 r.in.level, nt_errstr(status));
5647 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5648 if (!NT_STATUS_IS_OK(status)) {
5649 printf("QueryDomainInfo level %u failed - %s\n",
5650 r.in.level, nt_errstr(status));
5660 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5661 struct policy_handle *handle)
5664 struct samr_QueryDomainInfo2 r;
5665 union samr_DomainInfo *info = NULL;
5666 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5670 for (i=0;i<ARRAY_SIZE(levels);i++) {
5671 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5673 r.in.domain_handle = handle;
5674 r.in.level = levels[i];
5677 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5678 if (!NT_STATUS_IS_OK(status)) {
5679 printf("QueryDomainInfo2 level %u failed - %s\n",
5680 r.in.level, nt_errstr(status));
5689 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5690 set of group names. */
5691 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5692 struct policy_handle *handle)
5694 struct samr_EnumDomainGroups q1;
5695 struct samr_QueryDisplayInfo q2;
5697 uint32_t resume_handle=0;
5698 struct samr_SamArray *sam = NULL;
5699 uint32_t num_entries = 0;
5702 uint32_t total_size;
5703 uint32_t returned_size;
5704 union samr_DispInfo info;
5707 const char **names = NULL;
5709 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5711 q1.in.domain_handle = handle;
5712 q1.in.resume_handle = &resume_handle;
5714 q1.out.resume_handle = &resume_handle;
5715 q1.out.num_entries = &num_entries;
5718 status = STATUS_MORE_ENTRIES;
5719 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5720 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5722 if (!NT_STATUS_IS_OK(status) &&
5723 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5726 for (i=0; i<*q1.out.num_entries; i++) {
5727 add_string_to_array(tctx,
5728 sam->entries[i].name.string,
5729 &names, &num_names);
5733 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5735 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5737 q2.in.domain_handle = handle;
5739 q2.in.start_idx = 0;
5740 q2.in.max_entries = 5;
5741 q2.in.buf_size = (uint32_t)-1;
5742 q2.out.total_size = &total_size;
5743 q2.out.returned_size = &returned_size;
5744 q2.out.info = &info;
5746 status = STATUS_MORE_ENTRIES;
5747 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5748 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5750 if (!NT_STATUS_IS_OK(status) &&
5751 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5754 for (i=0; i<q2.out.info->info5.count; i++) {
5756 const char *name = q2.out.info->info5.entries[i].account_name.string;
5758 for (j=0; j<num_names; j++) {
5759 if (names[j] == NULL)
5761 if (strequal(names[j], name)) {
5769 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5774 q2.in.start_idx += q2.out.info->info5.count;
5777 if (!NT_STATUS_IS_OK(status)) {
5778 printf("QueryDisplayInfo level 5 failed - %s\n",
5783 for (i=0; i<num_names; i++) {
5784 if (names[i] != NULL) {
5785 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5794 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5795 struct policy_handle *group_handle)
5797 struct samr_DeleteDomainGroup d;
5800 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5802 d.in.group_handle = group_handle;
5803 d.out.group_handle = group_handle;
5805 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5806 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5811 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5812 struct policy_handle *domain_handle)
5814 struct samr_TestPrivateFunctionsDomain r;
5818 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5820 r.in.domain_handle = domain_handle;
5822 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5823 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5828 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5829 struct dom_sid *domain_sid,
5830 struct policy_handle *domain_handle)
5832 struct samr_RidToSid r;
5835 struct dom_sid *calc_sid, *out_sid;
5836 int rids[] = { 0, 42, 512, 10200 };
5839 for (i=0;i<ARRAY_SIZE(rids);i++) {
5840 torture_comment(tctx, "Testing RidToSid\n");
5842 calc_sid = dom_sid_dup(tctx, domain_sid);
5843 r.in.domain_handle = domain_handle;
5845 r.out.sid = &out_sid;
5847 status = dcerpc_samr_RidToSid(p, tctx, &r);
5848 if (!NT_STATUS_IS_OK(status)) {
5849 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5852 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5854 if (!dom_sid_equal(calc_sid, out_sid)) {
5855 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5856 dom_sid_string(tctx, out_sid),
5857 dom_sid_string(tctx, calc_sid));
5866 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5867 struct policy_handle *domain_handle)
5869 struct samr_GetBootKeyInformation r;
5872 uint32_t unknown = 0;
5874 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5876 r.in.domain_handle = domain_handle;
5877 r.out.unknown = &unknown;
5879 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5880 if (!NT_STATUS_IS_OK(status)) {
5881 /* w2k3 seems to fail this sometimes and pass it sometimes */
5882 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5888 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5889 struct policy_handle *domain_handle,
5890 struct policy_handle *group_handle)
5893 struct samr_AddGroupMember r;
5894 struct samr_DeleteGroupMember d;
5895 struct samr_QueryGroupMember q;
5896 struct samr_RidTypeArray *rids = NULL;
5897 struct samr_SetMemberAttributesOfGroup s;
5900 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5901 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5903 r.in.group_handle = group_handle;
5905 r.in.flags = 0; /* ??? */
5907 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5909 d.in.group_handle = group_handle;
5912 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5913 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5915 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5916 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5918 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5919 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5921 if (torture_setting_bool(tctx, "samba4", false) ||
5922 torture_setting_bool(tctx, "samba3", false)) {
5923 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5925 /* this one is quite strange. I am using random inputs in the
5926 hope of triggering an error that might give us a clue */
5928 s.in.group_handle = group_handle;
5929 s.in.unknown1 = random();
5930 s.in.unknown2 = random();
5932 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5933 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5936 q.in.group_handle = group_handle;
5939 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5940 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5942 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5943 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5945 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5946 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5952 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5953 struct torture_context *tctx,
5954 struct policy_handle *domain_handle,
5955 const char *group_name,
5956 struct policy_handle *group_handle,
5957 struct dom_sid *domain_sid,
5961 struct samr_CreateDomainGroup r;
5963 struct lsa_String name;
5966 init_lsa_String(&name, group_name);
5968 r.in.domain_handle = domain_handle;
5970 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5971 r.out.group_handle = group_handle;
5974 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5976 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5978 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5979 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5980 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5983 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5989 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5990 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5991 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5995 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5997 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5998 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6000 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6004 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6006 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6012 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6013 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
6017 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6026 its not totally clear what this does. It seems to accept any sid you like.
6028 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6029 struct torture_context *tctx,
6030 struct policy_handle *domain_handle)
6033 struct samr_RemoveMemberFromForeignDomain r;
6035 r.in.domain_handle = domain_handle;
6036 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6038 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6039 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6046 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6047 struct policy_handle *handle);
6049 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6050 struct policy_handle *handle, struct dom_sid *sid,
6051 enum torture_samr_choice which_ops,
6052 struct cli_credentials *machine_credentials)
6055 struct samr_OpenDomain r;
6056 struct policy_handle domain_handle;
6057 struct policy_handle alias_handle;
6058 struct policy_handle user_handle;
6059 struct policy_handle group_handle;
6062 ZERO_STRUCT(alias_handle);
6063 ZERO_STRUCT(user_handle);
6064 ZERO_STRUCT(group_handle);
6065 ZERO_STRUCT(domain_handle);
6067 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6069 r.in.connect_handle = handle;
6070 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6072 r.out.domain_handle = &domain_handle;
6074 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6075 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6077 /* run the domain tests with the main handle closed - this tests
6078 the servers reference counting */
6079 ret &= test_samr_handle_Close(p, tctx, handle);
6081 switch (which_ops) {
6082 case TORTURE_SAMR_USER_ATTRIBUTES:
6083 case TORTURE_SAMR_USER_PRIVILEGES:
6084 case TORTURE_SAMR_PASSWORDS:
6085 if (!torture_setting_bool(tctx, "samba3", false)) {
6086 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6088 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6089 /* This test needs 'complex' users to validate */
6090 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6092 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6095 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6096 if (!torture_setting_bool(tctx, "samba3", false)) {
6097 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6099 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6101 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6104 case TORTURE_SAMR_OTHER:
6105 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6107 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6109 if (!torture_setting_bool(tctx, "samba3", false)) {
6110 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6112 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6113 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6114 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6115 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6116 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6117 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6118 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6119 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6120 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6121 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6122 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6123 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6125 if (torture_setting_bool(tctx, "samba4", false)) {
6126 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6128 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6129 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6131 ret &= test_GroupList(p, tctx, &domain_handle);
6132 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6133 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6134 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6136 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6141 if (!policy_handle_empty(&user_handle) &&
6142 !test_DeleteUser(p, tctx, &user_handle)) {
6146 if (!policy_handle_empty(&alias_handle) &&
6147 !test_DeleteAlias(p, tctx, &alias_handle)) {
6151 if (!policy_handle_empty(&group_handle) &&
6152 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6156 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
6158 /* reconnect the main handle */
6159 ret &= test_Connect(p, tctx, handle);
6162 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6168 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6169 struct policy_handle *handle, const char *domain,
6170 enum torture_samr_choice which_ops,
6171 struct cli_credentials *machine_credentials)
6174 struct samr_LookupDomain r;
6175 struct dom_sid2 *sid = NULL;
6176 struct lsa_String n1;
6177 struct lsa_String n2;
6180 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6182 /* check for correct error codes */
6183 r.in.connect_handle = handle;
6184 r.in.domain_name = &n2;
6188 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6189 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6191 init_lsa_String(&n2, "xxNODOMAINxx");
6193 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6194 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6196 r.in.connect_handle = handle;
6198 init_lsa_String(&n1, domain);
6199 r.in.domain_name = &n1;
6201 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6202 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6204 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6208 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6209 machine_credentials)) {
6217 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6218 struct policy_handle *handle, enum torture_samr_choice which_ops,
6219 struct cli_credentials *machine_credentials)
6222 struct samr_EnumDomains r;
6223 uint32_t resume_handle = 0;
6224 uint32_t num_entries = 0;
6225 struct samr_SamArray *sam = NULL;
6229 r.in.connect_handle = handle;
6230 r.in.resume_handle = &resume_handle;
6231 r.in.buf_size = (uint32_t)-1;
6232 r.out.resume_handle = &resume_handle;
6233 r.out.num_entries = &num_entries;
6236 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6237 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6243 for (i=0;i<sam->count;i++) {
6244 if (!test_LookupDomain(p, tctx, handle,
6245 sam->entries[i].name.string, which_ops,
6246 machine_credentials)) {
6251 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6252 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6258 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6259 struct policy_handle *handle)
6262 struct samr_Connect r;
6263 struct samr_Connect2 r2;
6264 struct samr_Connect3 r3;
6265 struct samr_Connect4 r4;
6266 struct samr_Connect5 r5;
6267 union samr_ConnectInfo info;
6268 struct policy_handle h;
6269 uint32_t level_out = 0;
6270 bool ret = true, got_handle = false;
6272 torture_comment(tctx, "testing samr_Connect\n");
6274 r.in.system_name = 0;
6275 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6276 r.out.connect_handle = &h;
6278 status = dcerpc_samr_Connect(p, tctx, &r);
6279 if (!NT_STATUS_IS_OK(status)) {
6280 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6287 torture_comment(tctx, "testing samr_Connect2\n");
6289 r2.in.system_name = NULL;
6290 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6291 r2.out.connect_handle = &h;
6293 status = dcerpc_samr_Connect2(p, tctx, &r2);
6294 if (!NT_STATUS_IS_OK(status)) {
6295 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6299 test_samr_handle_Close(p, tctx, handle);
6305 torture_comment(tctx, "testing samr_Connect3\n");
6307 r3.in.system_name = NULL;
6309 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6310 r3.out.connect_handle = &h;
6312 status = dcerpc_samr_Connect3(p, tctx, &r3);
6313 if (!NT_STATUS_IS_OK(status)) {
6314 printf("Connect3 failed - %s\n", nt_errstr(status));
6318 test_samr_handle_Close(p, tctx, handle);
6324 torture_comment(tctx, "testing samr_Connect4\n");
6326 r4.in.system_name = "";
6327 r4.in.client_version = 0;
6328 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6329 r4.out.connect_handle = &h;
6331 status = dcerpc_samr_Connect4(p, tctx, &r4);
6332 if (!NT_STATUS_IS_OK(status)) {
6333 printf("Connect4 failed - %s\n", nt_errstr(status));
6337 test_samr_handle_Close(p, tctx, handle);
6343 torture_comment(tctx, "testing samr_Connect5\n");
6345 info.info1.client_version = 0;
6346 info.info1.unknown2 = 0;
6348 r5.in.system_name = "";
6349 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6351 r5.out.level_out = &level_out;
6352 r5.in.info_in = &info;
6353 r5.out.info_out = &info;
6354 r5.out.connect_handle = &h;
6356 status = dcerpc_samr_Connect5(p, tctx, &r5);
6357 if (!NT_STATUS_IS_OK(status)) {
6358 printf("Connect5 failed - %s\n", nt_errstr(status));
6362 test_samr_handle_Close(p, tctx, handle);
6372 bool torture_rpc_samr(struct torture_context *torture)
6375 struct dcerpc_pipe *p;
6377 struct policy_handle handle;
6379 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6380 if (!NT_STATUS_IS_OK(status)) {
6384 ret &= test_Connect(p, torture, &handle);
6386 if (!torture_setting_bool(torture, "samba3", false)) {
6387 ret &= test_QuerySecurity(p, torture, &handle);
6390 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6392 ret &= test_SetDsrmPassword(p, torture, &handle);
6394 ret &= test_Shutdown(p, torture, &handle);
6396 ret &= test_samr_handle_Close(p, torture, &handle);
6402 bool torture_rpc_samr_users(struct torture_context *torture)
6405 struct dcerpc_pipe *p;
6407 struct policy_handle handle;
6409 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6410 if (!NT_STATUS_IS_OK(status)) {
6414 ret &= test_Connect(p, torture, &handle);
6416 if (!torture_setting_bool(torture, "samba3", false)) {
6417 ret &= test_QuerySecurity(p, torture, &handle);
6420 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6422 ret &= test_SetDsrmPassword(p, torture, &handle);
6424 ret &= test_Shutdown(p, torture, &handle);
6426 ret &= test_samr_handle_Close(p, torture, &handle);
6432 bool torture_rpc_samr_passwords(struct torture_context *torture)
6435 struct dcerpc_pipe *p;
6437 struct policy_handle handle;
6439 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6440 if (!NT_STATUS_IS_OK(status)) {
6444 ret &= test_Connect(p, torture, &handle);
6446 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6448 ret &= test_samr_handle_Close(p, torture, &handle);
6453 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6454 struct dcerpc_pipe *p2,
6455 struct cli_credentials *machine_credentials)
6458 struct dcerpc_pipe *p;
6460 struct policy_handle handle;
6462 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6463 if (!NT_STATUS_IS_OK(status)) {
6467 ret &= test_Connect(p, torture, &handle);
6469 ret &= test_EnumDomains(p, torture, &handle,
6470 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6471 machine_credentials);
6473 ret &= test_samr_handle_Close(p, torture, &handle);
6478 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6480 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6481 struct torture_rpc_tcase *tcase;
6483 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6485 TEST_ACCOUNT_NAME_PWD);
6487 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6488 torture_rpc_samr_pwdlastset);
6493 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6494 struct dcerpc_pipe *p2,
6495 struct cli_credentials *machine_credentials)
6498 struct dcerpc_pipe *p;
6500 struct policy_handle handle;
6502 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6503 if (!NT_STATUS_IS_OK(status)) {
6507 ret &= test_Connect(p, torture, &handle);
6509 ret &= test_EnumDomains(p, torture, &handle,
6510 TORTURE_SAMR_USER_PRIVILEGES,
6511 machine_credentials);
6513 ret &= test_samr_handle_Close(p, torture, &handle);
6518 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6520 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6521 struct torture_rpc_tcase *tcase;
6523 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6525 TEST_ACCOUNT_NAME_PWD);
6527 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6528 torture_rpc_samr_users_privileges_delete_user);