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(struct dcerpc_pipe *p, struct torture_context *tctx,
4891 struct policy_handle *handle)
4893 NTSTATUS status = STATUS_MORE_ENTRIES;
4894 struct samr_EnumDomainUsers r;
4895 uint32_t mask, resume_handle=0;
4898 struct samr_LookupNames n;
4899 struct samr_LookupRids lr ;
4900 struct lsa_Strings names;
4901 struct samr_Ids rids, types;
4902 struct samr_SamArray *sam = NULL;
4903 uint32_t num_entries = 0;
4905 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4906 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4907 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4910 printf("Testing EnumDomainUsers\n");
4912 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4913 r.in.domain_handle = handle;
4914 r.in.resume_handle = &resume_handle;
4915 r.in.acct_flags = mask = masks[mask_idx];
4916 r.in.max_size = (uint32_t)-1;
4917 r.out.resume_handle = &resume_handle;
4918 r.out.num_entries = &num_entries;
4921 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4922 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4923 !NT_STATUS_IS_OK(status)) {
4924 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4928 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4930 if (sam->count == 0) {
4934 for (i=0;i<sam->count;i++) {
4936 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4939 } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4945 printf("Testing LookupNames\n");
4946 n.in.domain_handle = handle;
4947 n.in.num_names = sam->count;
4948 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4950 n.out.types = &types;
4951 for (i=0;i<sam->count;i++) {
4952 n.in.names[i].string = sam->entries[i].name.string;
4954 status = dcerpc_samr_LookupNames(p, tctx, &n);
4955 if (!NT_STATUS_IS_OK(status)) {
4956 printf("LookupNames failed - %s\n", nt_errstr(status));
4961 printf("Testing LookupRids\n");
4962 lr.in.domain_handle = handle;
4963 lr.in.num_rids = sam->count;
4964 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4965 lr.out.names = &names;
4966 lr.out.types = &types;
4967 for (i=0;i<sam->count;i++) {
4968 lr.in.rids[i] = sam->entries[i].idx;
4970 status = dcerpc_samr_LookupRids(p, tctx, &lr);
4971 torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4977 try blasting the server with a bunch of sync requests
4979 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4980 struct policy_handle *handle)
4983 struct samr_EnumDomainUsers r;
4984 uint32_t resume_handle=0;
4986 #define ASYNC_COUNT 100
4987 struct rpc_request *req[ASYNC_COUNT];
4989 if (!torture_setting_bool(tctx, "dangerous", false)) {
4990 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4993 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4995 r.in.domain_handle = handle;
4996 r.in.resume_handle = &resume_handle;
4997 r.in.acct_flags = 0;
4998 r.in.max_size = (uint32_t)-1;
4999 r.out.resume_handle = &resume_handle;
5001 for (i=0;i<ASYNC_COUNT;i++) {
5002 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5005 for (i=0;i<ASYNC_COUNT;i++) {
5006 status = dcerpc_ndr_request_recv(req[i]);
5007 if (!NT_STATUS_IS_OK(status)) {
5008 printf("EnumDomainUsers[%d] failed - %s\n",
5009 i, nt_errstr(status));
5014 torture_comment(tctx, "%d async requests OK\n", i);
5019 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
5020 struct torture_context *tctx,
5021 struct policy_handle *handle)
5024 struct samr_EnumDomainGroups r;
5025 uint32_t resume_handle=0;
5026 struct samr_SamArray *sam = NULL;
5027 uint32_t num_entries = 0;
5031 printf("Testing EnumDomainGroups\n");
5033 r.in.domain_handle = handle;
5034 r.in.resume_handle = &resume_handle;
5035 r.in.max_size = (uint32_t)-1;
5036 r.out.resume_handle = &resume_handle;
5037 r.out.num_entries = &num_entries;
5040 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5041 if (!NT_STATUS_IS_OK(status)) {
5042 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5050 for (i=0;i<sam->count;i++) {
5051 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5059 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
5060 struct torture_context *tctx,
5061 struct policy_handle *handle)
5064 struct samr_EnumDomainAliases r;
5065 uint32_t resume_handle=0;
5066 struct samr_SamArray *sam = NULL;
5067 uint32_t num_entries = 0;
5071 printf("Testing EnumDomainAliases\n");
5073 r.in.domain_handle = handle;
5074 r.in.resume_handle = &resume_handle;
5075 r.in.max_size = (uint32_t)-1;
5077 r.out.num_entries = &num_entries;
5078 r.out.resume_handle = &resume_handle;
5080 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5081 if (!NT_STATUS_IS_OK(status)) {
5082 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5090 for (i=0;i<sam->count;i++) {
5091 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5099 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5100 struct torture_context *tctx,
5101 struct policy_handle *handle)
5104 struct samr_GetDisplayEnumerationIndex r;
5106 uint16_t levels[] = {1, 2, 3, 4, 5};
5107 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5108 struct lsa_String name;
5112 for (i=0;i<ARRAY_SIZE(levels);i++) {
5113 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5115 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5117 r.in.domain_handle = handle;
5118 r.in.level = levels[i];
5122 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5125 !NT_STATUS_IS_OK(status) &&
5126 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5127 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5128 levels[i], nt_errstr(status));
5132 init_lsa_String(&name, "zzzzzzzz");
5134 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5136 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5137 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5138 levels[i], nt_errstr(status));
5146 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5147 struct torture_context *tctx,
5148 struct policy_handle *handle)
5151 struct samr_GetDisplayEnumerationIndex2 r;
5153 uint16_t levels[] = {1, 2, 3, 4, 5};
5154 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5155 struct lsa_String name;
5159 for (i=0;i<ARRAY_SIZE(levels);i++) {
5160 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5162 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5164 r.in.domain_handle = handle;
5165 r.in.level = levels[i];
5169 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5171 !NT_STATUS_IS_OK(status) &&
5172 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5173 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5174 levels[i], nt_errstr(status));
5178 init_lsa_String(&name, "zzzzzzzz");
5180 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5181 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5182 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5183 levels[i], nt_errstr(status));
5191 #define STRING_EQUAL_QUERY(s1, s2, user) \
5192 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5193 /* odd, but valid */ \
5194 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5195 printf("%s mismatch for %s: %s != %s (%s)\n", \
5196 #s1, user.string, s1.string, s2.string, __location__); \
5199 #define INT_EQUAL_QUERY(s1, s2, user) \
5201 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5202 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5206 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5207 struct torture_context *tctx,
5208 struct samr_QueryDisplayInfo *querydisplayinfo,
5209 bool *seen_testuser)
5211 struct samr_OpenUser r;
5212 struct samr_QueryUserInfo q;
5213 union samr_UserInfo *info;
5214 struct policy_handle user_handle;
5217 r.in.domain_handle = querydisplayinfo->in.domain_handle;
5218 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5219 for (i = 0; ; i++) {
5220 switch (querydisplayinfo->in.level) {
5222 if (i >= querydisplayinfo->out.info->info1.count) {
5225 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5228 if (i >= querydisplayinfo->out.info->info2.count) {
5231 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5237 /* Not interested in validating just the account name */
5241 r.out.user_handle = &user_handle;
5243 switch (querydisplayinfo->in.level) {
5246 status = dcerpc_samr_OpenUser(p, tctx, &r);
5247 if (!NT_STATUS_IS_OK(status)) {
5248 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5253 q.in.user_handle = &user_handle;
5256 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5257 if (!NT_STATUS_IS_OK(status)) {
5258 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5262 switch (querydisplayinfo->in.level) {
5264 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5265 *seen_testuser = true;
5267 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5268 info->info21.full_name, info->info21.account_name);
5269 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5270 info->info21.account_name, info->info21.account_name);
5271 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5272 info->info21.description, info->info21.account_name);
5273 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5274 info->info21.rid, info->info21.account_name);
5275 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5276 info->info21.acct_flags, info->info21.account_name);
5280 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5281 info->info21.account_name, info->info21.account_name);
5282 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5283 info->info21.description, info->info21.account_name);
5284 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5285 info->info21.rid, info->info21.account_name);
5286 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5287 info->info21.acct_flags, info->info21.account_name);
5289 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5290 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5291 info->info21.account_name.string);
5294 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5295 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5296 info->info21.account_name.string,
5297 querydisplayinfo->out.info->info2.entries[i].acct_flags,
5298 info->info21.acct_flags);
5305 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5312 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5313 struct torture_context *tctx,
5314 struct policy_handle *handle)
5317 struct samr_QueryDisplayInfo r;
5318 struct samr_QueryDomainInfo dom_info;
5319 union samr_DomainInfo *info = NULL;
5321 uint16_t levels[] = {1, 2, 3, 4, 5};
5323 bool seen_testuser = false;
5324 uint32_t total_size;
5325 uint32_t returned_size;
5326 union samr_DispInfo disp_info;
5329 for (i=0;i<ARRAY_SIZE(levels);i++) {
5330 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5333 status = STATUS_MORE_ENTRIES;
5334 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5335 r.in.domain_handle = handle;
5336 r.in.level = levels[i];
5337 r.in.max_entries = 2;
5338 r.in.buf_size = (uint32_t)-1;
5339 r.out.total_size = &total_size;
5340 r.out.returned_size = &returned_size;
5341 r.out.info = &disp_info;
5343 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5344 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5345 printf("QueryDisplayInfo level %u failed - %s\n",
5346 levels[i], nt_errstr(status));
5349 switch (r.in.level) {
5351 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5354 r.in.start_idx += r.out.info->info1.count;
5357 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5360 r.in.start_idx += r.out.info->info2.count;
5363 r.in.start_idx += r.out.info->info3.count;
5366 r.in.start_idx += r.out.info->info4.count;
5369 r.in.start_idx += r.out.info->info5.count;
5373 dom_info.in.domain_handle = handle;
5374 dom_info.in.level = 2;
5375 dom_info.out.info = &info;
5377 /* Check number of users returned is correct */
5378 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5379 if (!NT_STATUS_IS_OK(status)) {
5380 printf("QueryDomainInfo level %u failed - %s\n",
5381 r.in.level, nt_errstr(status));
5385 switch (r.in.level) {
5388 if (info->general.num_users < r.in.start_idx) {
5389 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5390 r.in.start_idx, info->general.num_groups,
5391 info->general.domain_name.string);
5394 if (!seen_testuser) {
5395 struct policy_handle user_handle;
5396 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5397 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5398 info->general.domain_name.string);
5400 test_samr_handle_Close(p, tctx, &user_handle);
5406 if (info->general.num_groups != r.in.start_idx) {
5407 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5408 r.in.start_idx, info->general.num_groups,
5409 info->general.domain_name.string);
5421 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5422 struct torture_context *tctx,
5423 struct policy_handle *handle)
5426 struct samr_QueryDisplayInfo2 r;
5428 uint16_t levels[] = {1, 2, 3, 4, 5};
5430 uint32_t total_size;
5431 uint32_t returned_size;
5432 union samr_DispInfo info;
5434 for (i=0;i<ARRAY_SIZE(levels);i++) {
5435 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5437 r.in.domain_handle = handle;
5438 r.in.level = levels[i];
5440 r.in.max_entries = 1000;
5441 r.in.buf_size = (uint32_t)-1;
5442 r.out.total_size = &total_size;
5443 r.out.returned_size = &returned_size;
5446 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5447 if (!NT_STATUS_IS_OK(status)) {
5448 printf("QueryDisplayInfo2 level %u failed - %s\n",
5449 levels[i], nt_errstr(status));
5457 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5458 struct policy_handle *handle)
5461 struct samr_QueryDisplayInfo3 r;
5463 uint16_t levels[] = {1, 2, 3, 4, 5};
5465 uint32_t total_size;
5466 uint32_t returned_size;
5467 union samr_DispInfo info;
5469 for (i=0;i<ARRAY_SIZE(levels);i++) {
5470 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5472 r.in.domain_handle = handle;
5473 r.in.level = levels[i];
5475 r.in.max_entries = 1000;
5476 r.in.buf_size = (uint32_t)-1;
5477 r.out.total_size = &total_size;
5478 r.out.returned_size = &returned_size;
5481 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5482 if (!NT_STATUS_IS_OK(status)) {
5483 printf("QueryDisplayInfo3 level %u failed - %s\n",
5484 levels[i], nt_errstr(status));
5493 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5494 struct torture_context *tctx,
5495 struct policy_handle *handle)
5498 struct samr_QueryDisplayInfo r;
5500 uint32_t total_size;
5501 uint32_t returned_size;
5502 union samr_DispInfo info;
5504 printf("Testing QueryDisplayInfo continuation\n");
5506 r.in.domain_handle = handle;
5509 r.in.max_entries = 1;
5510 r.in.buf_size = (uint32_t)-1;
5511 r.out.total_size = &total_size;
5512 r.out.returned_size = &returned_size;
5516 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5517 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5518 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5519 printf("expected idx %d but got %d\n",
5521 r.out.info->info1.entries[0].idx);
5525 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5526 !NT_STATUS_IS_OK(status)) {
5527 printf("QueryDisplayInfo level %u failed - %s\n",
5528 r.in.level, nt_errstr(status));
5533 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5534 NT_STATUS_IS_OK(status)) &&
5535 *r.out.returned_size != 0);
5540 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5541 struct policy_handle *handle)
5544 struct samr_QueryDomainInfo r;
5545 union samr_DomainInfo *info = NULL;
5546 struct samr_SetDomainInfo s;
5547 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5548 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5551 const char *domain_comment = talloc_asprintf(tctx,
5552 "Tortured by Samba4 RPC-SAMR: %s",
5553 timestring(tctx, time(NULL)));
5555 s.in.domain_handle = handle;
5557 s.in.info = talloc(tctx, union samr_DomainInfo);
5559 s.in.info->oem.oem_information.string = domain_comment;
5560 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5561 if (!NT_STATUS_IS_OK(status)) {
5562 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5563 s.in.level, nt_errstr(status));
5567 for (i=0;i<ARRAY_SIZE(levels);i++) {
5568 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5570 r.in.domain_handle = handle;
5571 r.in.level = levels[i];
5574 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5575 if (!NT_STATUS_IS_OK(status)) {
5576 printf("QueryDomainInfo level %u failed - %s\n",
5577 r.in.level, nt_errstr(status));
5582 switch (levels[i]) {
5584 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5585 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5586 levels[i], info->general.oem_information.string, domain_comment);
5589 if (!info->general.primary.string) {
5590 printf("QueryDomainInfo level %u returned no PDC name\n",
5593 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5594 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5595 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5596 levels[i], info->general.primary.string, dcerpc_server_name(p));
5601 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5602 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5603 levels[i], info->oem.oem_information.string, domain_comment);
5608 if (!info->info6.primary.string) {
5609 printf("QueryDomainInfo level %u returned no PDC name\n",
5615 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5616 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5617 levels[i], info->general2.general.oem_information.string, domain_comment);
5623 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5625 s.in.domain_handle = handle;
5626 s.in.level = levels[i];
5629 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5631 if (!NT_STATUS_IS_OK(status)) {
5632 printf("SetDomainInfo level %u failed - %s\n",
5633 r.in.level, nt_errstr(status));
5638 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5639 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5640 r.in.level, nt_errstr(status));
5646 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5647 if (!NT_STATUS_IS_OK(status)) {
5648 printf("QueryDomainInfo level %u failed - %s\n",
5649 r.in.level, nt_errstr(status));
5659 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5660 struct policy_handle *handle)
5663 struct samr_QueryDomainInfo2 r;
5664 union samr_DomainInfo *info = NULL;
5665 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5669 for (i=0;i<ARRAY_SIZE(levels);i++) {
5670 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5672 r.in.domain_handle = handle;
5673 r.in.level = levels[i];
5676 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5677 if (!NT_STATUS_IS_OK(status)) {
5678 printf("QueryDomainInfo2 level %u failed - %s\n",
5679 r.in.level, nt_errstr(status));
5688 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5689 set of group names. */
5690 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5691 struct policy_handle *handle)
5693 struct samr_EnumDomainGroups q1;
5694 struct samr_QueryDisplayInfo q2;
5696 uint32_t resume_handle=0;
5697 struct samr_SamArray *sam = NULL;
5698 uint32_t num_entries = 0;
5701 uint32_t total_size;
5702 uint32_t returned_size;
5703 union samr_DispInfo info;
5706 const char **names = NULL;
5708 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5710 q1.in.domain_handle = handle;
5711 q1.in.resume_handle = &resume_handle;
5713 q1.out.resume_handle = &resume_handle;
5714 q1.out.num_entries = &num_entries;
5717 status = STATUS_MORE_ENTRIES;
5718 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5719 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5721 if (!NT_STATUS_IS_OK(status) &&
5722 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5725 for (i=0; i<*q1.out.num_entries; i++) {
5726 add_string_to_array(tctx,
5727 sam->entries[i].name.string,
5728 &names, &num_names);
5732 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5734 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5736 q2.in.domain_handle = handle;
5738 q2.in.start_idx = 0;
5739 q2.in.max_entries = 5;
5740 q2.in.buf_size = (uint32_t)-1;
5741 q2.out.total_size = &total_size;
5742 q2.out.returned_size = &returned_size;
5743 q2.out.info = &info;
5745 status = STATUS_MORE_ENTRIES;
5746 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5747 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5749 if (!NT_STATUS_IS_OK(status) &&
5750 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5753 for (i=0; i<q2.out.info->info5.count; i++) {
5755 const char *name = q2.out.info->info5.entries[i].account_name.string;
5757 for (j=0; j<num_names; j++) {
5758 if (names[j] == NULL)
5760 if (strequal(names[j], name)) {
5768 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5773 q2.in.start_idx += q2.out.info->info5.count;
5776 if (!NT_STATUS_IS_OK(status)) {
5777 printf("QueryDisplayInfo level 5 failed - %s\n",
5782 for (i=0; i<num_names; i++) {
5783 if (names[i] != NULL) {
5784 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5793 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5794 struct policy_handle *group_handle)
5796 struct samr_DeleteDomainGroup d;
5799 torture_comment(tctx, "Testing DeleteDomainGroup\n");
5801 d.in.group_handle = group_handle;
5802 d.out.group_handle = group_handle;
5804 status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5805 torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5810 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5811 struct policy_handle *domain_handle)
5813 struct samr_TestPrivateFunctionsDomain r;
5817 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5819 r.in.domain_handle = domain_handle;
5821 status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5822 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5827 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5828 struct dom_sid *domain_sid,
5829 struct policy_handle *domain_handle)
5831 struct samr_RidToSid r;
5834 struct dom_sid *calc_sid, *out_sid;
5835 int rids[] = { 0, 42, 512, 10200 };
5838 for (i=0;i<ARRAY_SIZE(rids);i++) {
5839 torture_comment(tctx, "Testing RidToSid\n");
5841 calc_sid = dom_sid_dup(tctx, domain_sid);
5842 r.in.domain_handle = domain_handle;
5844 r.out.sid = &out_sid;
5846 status = dcerpc_samr_RidToSid(p, tctx, &r);
5847 if (!NT_STATUS_IS_OK(status)) {
5848 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5851 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5853 if (!dom_sid_equal(calc_sid, out_sid)) {
5854 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5855 dom_sid_string(tctx, out_sid),
5856 dom_sid_string(tctx, calc_sid));
5865 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5866 struct policy_handle *domain_handle)
5868 struct samr_GetBootKeyInformation r;
5871 uint32_t unknown = 0;
5873 torture_comment(tctx, "Testing GetBootKeyInformation\n");
5875 r.in.domain_handle = domain_handle;
5876 r.out.unknown = &unknown;
5878 status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5879 if (!NT_STATUS_IS_OK(status)) {
5880 /* w2k3 seems to fail this sometimes and pass it sometimes */
5881 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5887 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5888 struct policy_handle *domain_handle,
5889 struct policy_handle *group_handle)
5892 struct samr_AddGroupMember r;
5893 struct samr_DeleteGroupMember d;
5894 struct samr_QueryGroupMember q;
5895 struct samr_RidTypeArray *rids = NULL;
5896 struct samr_SetMemberAttributesOfGroup s;
5899 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5900 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5902 r.in.group_handle = group_handle;
5904 r.in.flags = 0; /* ??? */
5906 torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5908 d.in.group_handle = group_handle;
5911 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5912 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5914 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5915 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5917 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5918 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5920 if (torture_setting_bool(tctx, "samba4", false) ||
5921 torture_setting_bool(tctx, "samba3", false)) {
5922 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5924 /* this one is quite strange. I am using random inputs in the
5925 hope of triggering an error that might give us a clue */
5927 s.in.group_handle = group_handle;
5928 s.in.unknown1 = random();
5929 s.in.unknown2 = random();
5931 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5932 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5935 q.in.group_handle = group_handle;
5938 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5939 torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5941 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5942 torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5944 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5945 torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5951 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5952 struct torture_context *tctx,
5953 struct policy_handle *domain_handle,
5954 const char *group_name,
5955 struct policy_handle *group_handle,
5956 struct dom_sid *domain_sid,
5960 struct samr_CreateDomainGroup r;
5962 struct lsa_String name;
5965 init_lsa_String(&name, group_name);
5967 r.in.domain_handle = domain_handle;
5969 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5970 r.out.group_handle = group_handle;
5973 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5975 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5977 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5978 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5979 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5982 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5988 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5989 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5990 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5994 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5996 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5997 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5999 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6003 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6005 torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6011 if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6012 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
6016 if (!test_SetGroupInfo(p, tctx, group_handle)) {
6025 its not totally clear what this does. It seems to accept any sid you like.
6027 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6028 struct torture_context *tctx,
6029 struct policy_handle *domain_handle)
6032 struct samr_RemoveMemberFromForeignDomain r;
6034 r.in.domain_handle = domain_handle;
6035 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6037 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6038 torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6045 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6046 struct policy_handle *handle);
6048 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6049 struct policy_handle *handle, struct dom_sid *sid,
6050 enum torture_samr_choice which_ops,
6051 struct cli_credentials *machine_credentials)
6054 struct samr_OpenDomain r;
6055 struct policy_handle domain_handle;
6056 struct policy_handle alias_handle;
6057 struct policy_handle user_handle;
6058 struct policy_handle group_handle;
6061 ZERO_STRUCT(alias_handle);
6062 ZERO_STRUCT(user_handle);
6063 ZERO_STRUCT(group_handle);
6064 ZERO_STRUCT(domain_handle);
6066 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6068 r.in.connect_handle = handle;
6069 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6071 r.out.domain_handle = &domain_handle;
6073 status = dcerpc_samr_OpenDomain(p, tctx, &r);
6074 torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6076 /* run the domain tests with the main handle closed - this tests
6077 the servers reference counting */
6078 ret &= test_samr_handle_Close(p, tctx, handle);
6080 switch (which_ops) {
6081 case TORTURE_SAMR_USER_ATTRIBUTES:
6082 case TORTURE_SAMR_USER_PRIVILEGES:
6083 case TORTURE_SAMR_PASSWORDS:
6084 if (!torture_setting_bool(tctx, "samba3", false)) {
6085 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6087 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6088 /* This test needs 'complex' users to validate */
6089 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6091 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6094 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6095 if (!torture_setting_bool(tctx, "samba3", false)) {
6096 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6098 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6100 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6103 case TORTURE_SAMR_OTHER:
6104 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6106 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6108 if (!torture_setting_bool(tctx, "samba3", false)) {
6109 ret &= test_QuerySecurity(p, tctx, &domain_handle);
6111 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6112 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6113 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6114 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6115 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6116 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
6117 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6118 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
6119 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
6120 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6121 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6122 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6124 if (torture_setting_bool(tctx, "samba4", false)) {
6125 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6127 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6128 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6130 ret &= test_GroupList(p, tctx, &domain_handle);
6131 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6132 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6133 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6135 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6140 if (!policy_handle_empty(&user_handle) &&
6141 !test_DeleteUser(p, tctx, &user_handle)) {
6145 if (!policy_handle_empty(&alias_handle) &&
6146 !test_DeleteAlias(p, tctx, &alias_handle)) {
6150 if (!policy_handle_empty(&group_handle) &&
6151 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6155 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
6157 /* reconnect the main handle */
6158 ret &= test_Connect(p, tctx, handle);
6161 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6167 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6168 struct policy_handle *handle, const char *domain,
6169 enum torture_samr_choice which_ops,
6170 struct cli_credentials *machine_credentials)
6173 struct samr_LookupDomain r;
6174 struct dom_sid2 *sid = NULL;
6175 struct lsa_String n1;
6176 struct lsa_String n2;
6179 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6181 /* check for correct error codes */
6182 r.in.connect_handle = handle;
6183 r.in.domain_name = &n2;
6187 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6188 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6190 init_lsa_String(&n2, "xxNODOMAINxx");
6192 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6193 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6195 r.in.connect_handle = handle;
6197 init_lsa_String(&n1, domain);
6198 r.in.domain_name = &n1;
6200 status = dcerpc_samr_LookupDomain(p, tctx, &r);
6201 torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6203 if (!test_GetDomPwInfo(p, tctx, &n1)) {
6207 if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6208 machine_credentials)) {
6216 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6217 struct policy_handle *handle, enum torture_samr_choice which_ops,
6218 struct cli_credentials *machine_credentials)
6221 struct samr_EnumDomains r;
6222 uint32_t resume_handle = 0;
6223 uint32_t num_entries = 0;
6224 struct samr_SamArray *sam = NULL;
6228 r.in.connect_handle = handle;
6229 r.in.resume_handle = &resume_handle;
6230 r.in.buf_size = (uint32_t)-1;
6231 r.out.resume_handle = &resume_handle;
6232 r.out.num_entries = &num_entries;
6235 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6236 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6242 for (i=0;i<sam->count;i++) {
6243 if (!test_LookupDomain(p, tctx, handle,
6244 sam->entries[i].name.string, which_ops,
6245 machine_credentials)) {
6250 status = dcerpc_samr_EnumDomains(p, tctx, &r);
6251 torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6257 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6258 struct policy_handle *handle)
6261 struct samr_Connect r;
6262 struct samr_Connect2 r2;
6263 struct samr_Connect3 r3;
6264 struct samr_Connect4 r4;
6265 struct samr_Connect5 r5;
6266 union samr_ConnectInfo info;
6267 struct policy_handle h;
6268 uint32_t level_out = 0;
6269 bool ret = true, got_handle = false;
6271 torture_comment(tctx, "testing samr_Connect\n");
6273 r.in.system_name = 0;
6274 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6275 r.out.connect_handle = &h;
6277 status = dcerpc_samr_Connect(p, tctx, &r);
6278 if (!NT_STATUS_IS_OK(status)) {
6279 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6286 torture_comment(tctx, "testing samr_Connect2\n");
6288 r2.in.system_name = NULL;
6289 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6290 r2.out.connect_handle = &h;
6292 status = dcerpc_samr_Connect2(p, tctx, &r2);
6293 if (!NT_STATUS_IS_OK(status)) {
6294 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6298 test_samr_handle_Close(p, tctx, handle);
6304 torture_comment(tctx, "testing samr_Connect3\n");
6306 r3.in.system_name = NULL;
6308 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6309 r3.out.connect_handle = &h;
6311 status = dcerpc_samr_Connect3(p, tctx, &r3);
6312 if (!NT_STATUS_IS_OK(status)) {
6313 printf("Connect3 failed - %s\n", nt_errstr(status));
6317 test_samr_handle_Close(p, tctx, handle);
6323 torture_comment(tctx, "testing samr_Connect4\n");
6325 r4.in.system_name = "";
6326 r4.in.client_version = 0;
6327 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6328 r4.out.connect_handle = &h;
6330 status = dcerpc_samr_Connect4(p, tctx, &r4);
6331 if (!NT_STATUS_IS_OK(status)) {
6332 printf("Connect4 failed - %s\n", nt_errstr(status));
6336 test_samr_handle_Close(p, tctx, handle);
6342 torture_comment(tctx, "testing samr_Connect5\n");
6344 info.info1.client_version = 0;
6345 info.info1.unknown2 = 0;
6347 r5.in.system_name = "";
6348 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6350 r5.out.level_out = &level_out;
6351 r5.in.info_in = &info;
6352 r5.out.info_out = &info;
6353 r5.out.connect_handle = &h;
6355 status = dcerpc_samr_Connect5(p, tctx, &r5);
6356 if (!NT_STATUS_IS_OK(status)) {
6357 printf("Connect5 failed - %s\n", nt_errstr(status));
6361 test_samr_handle_Close(p, tctx, handle);
6371 bool torture_rpc_samr(struct torture_context *torture)
6374 struct dcerpc_pipe *p;
6376 struct policy_handle handle;
6378 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6379 if (!NT_STATUS_IS_OK(status)) {
6383 ret &= test_Connect(p, torture, &handle);
6385 if (!torture_setting_bool(torture, "samba3", false)) {
6386 ret &= test_QuerySecurity(p, torture, &handle);
6389 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6391 ret &= test_SetDsrmPassword(p, torture, &handle);
6393 ret &= test_Shutdown(p, torture, &handle);
6395 ret &= test_samr_handle_Close(p, torture, &handle);
6401 bool torture_rpc_samr_users(struct torture_context *torture)
6404 struct dcerpc_pipe *p;
6406 struct policy_handle handle;
6408 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6409 if (!NT_STATUS_IS_OK(status)) {
6413 ret &= test_Connect(p, torture, &handle);
6415 if (!torture_setting_bool(torture, "samba3", false)) {
6416 ret &= test_QuerySecurity(p, torture, &handle);
6419 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6421 ret &= test_SetDsrmPassword(p, torture, &handle);
6423 ret &= test_Shutdown(p, torture, &handle);
6425 ret &= test_samr_handle_Close(p, torture, &handle);
6431 bool torture_rpc_samr_passwords(struct torture_context *torture)
6434 struct dcerpc_pipe *p;
6436 struct policy_handle handle;
6438 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6439 if (!NT_STATUS_IS_OK(status)) {
6443 ret &= test_Connect(p, torture, &handle);
6445 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6447 ret &= test_samr_handle_Close(p, torture, &handle);
6452 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6453 struct dcerpc_pipe *p2,
6454 struct cli_credentials *machine_credentials)
6457 struct dcerpc_pipe *p;
6459 struct policy_handle handle;
6461 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6462 if (!NT_STATUS_IS_OK(status)) {
6466 ret &= test_Connect(p, torture, &handle);
6468 ret &= test_EnumDomains(p, torture, &handle,
6469 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6470 machine_credentials);
6472 ret &= test_samr_handle_Close(p, torture, &handle);
6477 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6479 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6480 struct torture_rpc_tcase *tcase;
6482 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6484 TEST_ACCOUNT_NAME_PWD);
6486 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6487 torture_rpc_samr_pwdlastset);
6492 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6493 struct dcerpc_pipe *p2,
6494 struct cli_credentials *machine_credentials)
6497 struct dcerpc_pipe *p;
6499 struct policy_handle handle;
6501 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6502 if (!NT_STATUS_IS_OK(status)) {
6506 ret &= test_Connect(p, torture, &handle);
6508 ret &= test_EnumDomains(p, torture, &handle,
6509 TORTURE_SAMR_USER_PRIVILEGES,
6510 machine_credentials);
6512 ret &= test_samr_handle_Close(p, torture, &handle);
6517 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6519 struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6520 struct torture_rpc_tcase *tcase;
6522 tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6524 TEST_ACCOUNT_NAME_PWD);
6526 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6527 torture_rpc_samr_users_privileges_delete_user);