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 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 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
, 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 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 struct policy_handle
*alias_handle
,
4004 const struct dom_sid
*domain_sid
)
4007 struct samr_CreateDomAlias r
;
4008 struct lsa_String name
;
4012 init_lsa_String(&name
, TEST_ALIASNAME
);
4013 r
.in
.domain_handle
= domain_handle
;
4014 r
.in
.alias_name
= &name
;
4015 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4016 r
.out
.alias_handle
= alias_handle
;
4019 printf("Testing CreateAlias (%s)\n", r
.in
.alias_name
->string
);
4021 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
4023 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4024 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4025 printf("Server correctly refused create of '%s'\n", r
.in
.alias_name
->string
);
4028 printf("Server should have refused create of '%s', got %s instead\n", r
.in
.alias_name
->string
,
4034 if (NT_STATUS_EQUAL(status
, NT_STATUS_ALIAS_EXISTS
)) {
4035 if (!test_DeleteAlias_byname(p
, tctx
, domain_handle
, r
.in
.alias_name
->string
)) {
4038 status
= dcerpc_samr_CreateDomAlias(p
, tctx
, &r
);
4041 if (!NT_STATUS_IS_OK(status
)) {
4042 printf("CreateAlias failed - %s\n", nt_errstr(status
));
4046 if (!test_alias_ops(p
, tctx
, alias_handle
, domain_sid
)) {
4053 static bool test_ChangePassword(struct dcerpc_pipe
*p
,
4054 struct torture_context
*tctx
,
4055 const char *acct_name
,
4056 struct policy_handle
*domain_handle
, char **password
)
4064 if (!test_ChangePasswordUser(p
, tctx
, acct_name
, domain_handle
, password
)) {
4068 if (!test_ChangePasswordUser2(p
, tctx
, acct_name
, password
, 0, true)) {
4072 if (!test_OemChangePasswordUser2(p
, tctx
, acct_name
, domain_handle
, password
)) {
4076 /* test what happens when setting the old password again */
4077 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, *password
, 0, true)) {
4082 char simple_pass
[9];
4083 char *v
= generate_random_str(tctx
, 1);
4085 ZERO_STRUCT(simple_pass
);
4086 memset(simple_pass
, *v
, sizeof(simple_pass
) - 1);
4088 /* test what happens when picking a simple password */
4089 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, simple_pass
, 0, true)) {
4094 /* set samr_SetDomainInfo level 1 with min_length 5 */
4096 struct samr_QueryDomainInfo r
;
4097 union samr_DomainInfo
*info
= NULL
;
4098 struct samr_SetDomainInfo s
;
4099 uint16_t len_old
, len
;
4100 uint32_t pwd_prop_old
;
4101 int64_t min_pwd_age_old
;
4106 r
.in
.domain_handle
= domain_handle
;
4110 printf("testing samr_QueryDomainInfo level 1\n");
4111 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
4112 if (!NT_STATUS_IS_OK(status
)) {
4116 s
.in
.domain_handle
= domain_handle
;
4120 /* remember the old min length, so we can reset it */
4121 len_old
= s
.in
.info
->info1
.min_password_length
;
4122 s
.in
.info
->info1
.min_password_length
= len
;
4123 pwd_prop_old
= s
.in
.info
->info1
.password_properties
;
4124 /* turn off password complexity checks for this test */
4125 s
.in
.info
->info1
.password_properties
&= ~DOMAIN_PASSWORD_COMPLEX
;
4127 min_pwd_age_old
= s
.in
.info
->info1
.min_password_age
;
4128 s
.in
.info
->info1
.min_password_age
= 0;
4130 printf("testing samr_SetDomainInfo level 1\n");
4131 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
4132 if (!NT_STATUS_IS_OK(status
)) {
4136 printf("calling test_ChangePasswordUser3 with too short password\n");
4138 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, len
- 1, password
, NULL
, 0, true)) {
4142 s
.in
.info
->info1
.min_password_length
= len_old
;
4143 s
.in
.info
->info1
.password_properties
= pwd_prop_old
;
4144 s
.in
.info
->info1
.min_password_age
= min_pwd_age_old
;
4146 printf("testing samr_SetDomainInfo level 1\n");
4147 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
4148 if (!NT_STATUS_IS_OK(status
)) {
4156 struct samr_OpenUser r
;
4157 struct samr_QueryUserInfo q
;
4158 union samr_UserInfo
*info
;
4159 struct samr_LookupNames n
;
4160 struct policy_handle user_handle
;
4161 struct samr_Ids rids
, types
;
4163 n
.in
.domain_handle
= domain_handle
;
4165 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, 1);
4166 n
.in
.names
[0].string
= acct_name
;
4168 n
.out
.types
= &types
;
4170 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
4171 if (!NT_STATUS_IS_OK(status
)) {
4172 printf("LookupNames failed - %s\n", nt_errstr(status
));
4176 r
.in
.domain_handle
= domain_handle
;
4177 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4178 r
.in
.rid
= n
.out
.rids
->ids
[0];
4179 r
.out
.user_handle
= &user_handle
;
4181 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
4182 if (!NT_STATUS_IS_OK(status
)) {
4183 printf("OpenUser(%u) failed - %s\n", n
.out
.rids
->ids
[0], nt_errstr(status
));
4187 q
.in
.user_handle
= &user_handle
;
4191 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
4192 if (!NT_STATUS_IS_OK(status
)) {
4193 printf("QueryUserInfo failed - %s\n", nt_errstr(status
));
4197 printf("calling test_ChangePasswordUser3 with too early password change\n");
4199 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
,
4200 info
->info5
.last_password_change
, true)) {
4205 /* we change passwords twice - this has the effect of verifying
4206 they were changed correctly for the final call */
4207 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
4211 if (!test_ChangePasswordUser3(p
, tctx
, acct_name
, 0, password
, NULL
, 0, true)) {
4218 static bool test_CreateUser(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4219 struct policy_handle
*domain_handle
,
4220 struct policy_handle
*user_handle_out
,
4221 struct dom_sid
*domain_sid
,
4222 enum torture_samr_choice which_ops
,
4223 struct cli_credentials
*machine_credentials
)
4226 TALLOC_CTX
*user_ctx
;
4229 struct samr_CreateUser r
;
4230 struct samr_QueryUserInfo q
;
4231 union samr_UserInfo
*info
;
4232 struct samr_DeleteUser d
;
4235 /* This call creates a 'normal' account - check that it really does */
4236 const uint32_t acct_flags
= ACB_NORMAL
;
4237 struct lsa_String name
;
4240 struct policy_handle user_handle
;
4241 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
4242 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
4244 r
.in
.domain_handle
= domain_handle
;
4245 r
.in
.account_name
= &name
;
4246 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4247 r
.out
.user_handle
= &user_handle
;
4250 printf("Testing CreateUser(%s)\n", r
.in
.account_name
->string
);
4252 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
4254 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4255 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
4256 printf("Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
4259 printf("Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
4265 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
4266 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
4267 talloc_free(user_ctx
);
4270 status
= dcerpc_samr_CreateUser(p
, user_ctx
, &r
);
4272 if (!NT_STATUS_IS_OK(status
)) {
4273 talloc_free(user_ctx
);
4274 printf("CreateUser failed - %s\n", nt_errstr(status
));
4277 q
.in
.user_handle
= &user_handle
;
4281 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
4282 if (!NT_STATUS_IS_OK(status
)) {
4283 printf("QueryUserInfo level %u failed - %s\n",
4284 q
.in
.level
, nt_errstr(status
));
4287 if ((info
->info16
.acct_flags
& acct_flags
) != acct_flags
) {
4288 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4289 info
->info16
.acct_flags
,
4295 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
4296 domain_sid
, acct_flags
, name
.string
, which_ops
,
4297 machine_credentials
)) {
4301 if (user_handle_out
) {
4302 *user_handle_out
= user_handle
;
4304 printf("Testing DeleteUser (createuser test)\n");
4306 d
.in
.user_handle
= &user_handle
;
4307 d
.out
.user_handle
= &user_handle
;
4309 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
4310 if (!NT_STATUS_IS_OK(status
)) {
4311 printf("DeleteUser failed - %s\n", nt_errstr(status
));
4318 talloc_free(user_ctx
);
4324 static bool test_CreateUser2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4325 struct policy_handle
*domain_handle
,
4326 struct dom_sid
*domain_sid
,
4327 enum torture_samr_choice which_ops
,
4328 struct cli_credentials
*machine_credentials
)
4331 struct samr_CreateUser2 r
;
4332 struct samr_QueryUserInfo q
;
4333 union samr_UserInfo
*info
;
4334 struct samr_DeleteUser d
;
4335 struct policy_handle user_handle
;
4337 struct lsa_String name
;
4342 uint32_t acct_flags
;
4343 const char *account_name
;
4345 } account_types
[] = {
4346 { ACB_NORMAL
, TEST_ACCOUNT_NAME
, NT_STATUS_OK
},
4347 { ACB_NORMAL
| ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
4348 { ACB_NORMAL
| ACB_PWNOEXP
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
4349 { ACB_WSTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
4350 { ACB_WSTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
4351 { ACB_WSTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
4352 { ACB_SVRTRUST
, TEST_MACHINENAME
, NT_STATUS_OK
},
4353 { ACB_SVRTRUST
| ACB_DISABLED
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
4354 { ACB_SVRTRUST
| ACB_PWNOEXP
, TEST_MACHINENAME
, NT_STATUS_INVALID_PARAMETER
},
4355 { ACB_DOMTRUST
, TEST_DOMAINNAME
, NT_STATUS_OK
},
4356 { ACB_DOMTRUST
| ACB_DISABLED
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
4357 { ACB_DOMTRUST
| ACB_PWNOEXP
, TEST_DOMAINNAME
, NT_STATUS_INVALID_PARAMETER
},
4358 { 0, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
4359 { ACB_DISABLED
, TEST_ACCOUNT_NAME
, NT_STATUS_INVALID_PARAMETER
},
4360 { 0, NULL
, NT_STATUS_INVALID_PARAMETER
}
4363 for (i
= 0; account_types
[i
].account_name
; i
++) {
4364 TALLOC_CTX
*user_ctx
;
4365 uint32_t acct_flags
= account_types
[i
].acct_flags
;
4366 uint32_t access_granted
;
4367 user_ctx
= talloc_named(tctx
, 0, "test_CreateUser2 per-user context");
4368 init_lsa_String(&name
, account_types
[i
].account_name
);
4370 r
.in
.domain_handle
= domain_handle
;
4371 r
.in
.account_name
= &name
;
4372 r
.in
.acct_flags
= acct_flags
;
4373 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4374 r
.out
.user_handle
= &user_handle
;
4375 r
.out
.access_granted
= &access_granted
;
4378 printf("Testing CreateUser2(%s, 0x%x)\n", r
.in
.account_name
->string
, acct_flags
);
4380 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
4382 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
4383 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) || NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
4384 printf("Server correctly refused create of '%s'\n", r
.in
.account_name
->string
);
4387 printf("Server should have refused create of '%s', got %s instead\n", r
.in
.account_name
->string
,
4394 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
4395 if (!test_DeleteUser_byname(p
, user_ctx
, domain_handle
, r
.in
.account_name
->string
)) {
4396 talloc_free(user_ctx
);
4400 status
= dcerpc_samr_CreateUser2(p
, user_ctx
, &r
);
4403 if (!NT_STATUS_EQUAL(status
, account_types
[i
].nt_status
)) {
4404 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4405 nt_errstr(status
), nt_errstr(account_types
[i
].nt_status
));
4409 if (NT_STATUS_IS_OK(status
)) {
4410 q
.in
.user_handle
= &user_handle
;
4414 status
= dcerpc_samr_QueryUserInfo(p
, user_ctx
, &q
);
4415 if (!NT_STATUS_IS_OK(status
)) {
4416 printf("QueryUserInfo level %u failed - %s\n",
4417 q
.in
.level
, nt_errstr(status
));
4420 uint32_t expected_flags
= (acct_flags
| ACB_PWNOTREQ
| ACB_DISABLED
);
4421 if (acct_flags
== ACB_NORMAL
) {
4422 expected_flags
|= ACB_PW_EXPIRED
;
4424 if ((info
->info5
.acct_flags
) != expected_flags
) {
4425 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4426 info
->info5
.acct_flags
,
4430 switch (acct_flags
) {
4432 if (info
->info5
.primary_gid
!= DOMAIN_RID_DCS
) {
4433 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4434 DOMAIN_RID_DCS
, info
->info5
.primary_gid
);
4439 if (info
->info5
.primary_gid
!= DOMAIN_RID_DOMAIN_MEMBERS
) {
4440 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4441 DOMAIN_RID_DOMAIN_MEMBERS
, info
->info5
.primary_gid
);
4446 if (info
->info5
.primary_gid
!= DOMAIN_RID_USERS
) {
4447 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4448 DOMAIN_RID_USERS
, info
->info5
.primary_gid
);
4455 if (!test_user_ops(p
, tctx
, &user_handle
, domain_handle
,
4456 domain_sid
, acct_flags
, name
.string
, which_ops
,
4457 machine_credentials
)) {
4461 if (!policy_handle_empty(&user_handle
)) {
4462 printf("Testing DeleteUser (createuser2 test)\n");
4464 d
.in
.user_handle
= &user_handle
;
4465 d
.out
.user_handle
= &user_handle
;
4467 status
= dcerpc_samr_DeleteUser(p
, user_ctx
, &d
);
4468 if (!NT_STATUS_IS_OK(status
)) {
4469 printf("DeleteUser failed - %s\n", nt_errstr(status
));
4474 talloc_free(user_ctx
);
4480 static bool test_QueryAliasInfo(struct dcerpc_pipe
*p
,
4481 struct torture_context
*tctx
,
4482 struct policy_handle
*handle
)
4485 struct samr_QueryAliasInfo r
;
4486 union samr_AliasInfo
*info
;
4487 uint16_t levels
[] = {1, 2, 3};
4491 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4492 printf("Testing QueryAliasInfo level %u\n", levels
[i
]);
4494 r
.in
.alias_handle
= handle
;
4495 r
.in
.level
= levels
[i
];
4498 status
= dcerpc_samr_QueryAliasInfo(p
, tctx
, &r
);
4499 if (!NT_STATUS_IS_OK(status
)) {
4500 printf("QueryAliasInfo level %u failed - %s\n",
4501 levels
[i
], nt_errstr(status
));
4509 static bool test_QueryGroupInfo(struct dcerpc_pipe
*p
,
4510 struct torture_context
*tctx
,
4511 struct policy_handle
*handle
)
4514 struct samr_QueryGroupInfo r
;
4515 union samr_GroupInfo
*info
;
4516 uint16_t levels
[] = {1, 2, 3, 4, 5};
4520 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4521 printf("Testing QueryGroupInfo level %u\n", levels
[i
]);
4523 r
.in
.group_handle
= handle
;
4524 r
.in
.level
= levels
[i
];
4527 status
= dcerpc_samr_QueryGroupInfo(p
, tctx
, &r
);
4528 if (!NT_STATUS_IS_OK(status
)) {
4529 printf("QueryGroupInfo level %u failed - %s\n",
4530 levels
[i
], nt_errstr(status
));
4538 static bool test_QueryGroupMember(struct dcerpc_pipe
*p
,
4539 struct torture_context
*tctx
,
4540 struct policy_handle
*handle
)
4543 struct samr_QueryGroupMember r
;
4544 struct samr_RidTypeArray
*rids
= NULL
;
4547 printf("Testing QueryGroupMember\n");
4549 r
.in
.group_handle
= handle
;
4552 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &r
);
4553 if (!NT_STATUS_IS_OK(status
)) {
4554 printf("QueryGroupInfo failed - %s\n", nt_errstr(status
));
4562 static bool test_SetGroupInfo(struct dcerpc_pipe
*p
,
4563 struct torture_context
*tctx
,
4564 struct policy_handle
*handle
)
4567 struct samr_QueryGroupInfo r
;
4568 union samr_GroupInfo
*info
;
4569 struct samr_SetGroupInfo s
;
4570 uint16_t levels
[] = {1, 2, 3, 4};
4571 uint16_t set_ok
[] = {0, 1, 1, 1};
4575 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4576 printf("Testing QueryGroupInfo level %u\n", levels
[i
]);
4578 r
.in
.group_handle
= handle
;
4579 r
.in
.level
= levels
[i
];
4582 status
= dcerpc_samr_QueryGroupInfo(p
, tctx
, &r
);
4583 if (!NT_STATUS_IS_OK(status
)) {
4584 printf("QueryGroupInfo level %u failed - %s\n",
4585 levels
[i
], nt_errstr(status
));
4589 printf("Testing SetGroupInfo level %u\n", levels
[i
]);
4591 s
.in
.group_handle
= handle
;
4592 s
.in
.level
= levels
[i
];
4593 s
.in
.info
= *r
.out
.info
;
4596 /* disabled this, as it changes the name only from the point of view of samr,
4597 but leaves the name from the point of view of w2k3 internals (and ldap). This means
4598 the name is still reserved, so creating the old name fails, but deleting by the old name
4600 if (s
.in
.level
== 2) {
4601 init_lsa_String(&s
.in
.info
->string
, "NewName");
4605 if (s
.in
.level
== 4) {
4606 init_lsa_String(&s
.in
.info
->description
, "test description");
4609 status
= dcerpc_samr_SetGroupInfo(p
, tctx
, &s
);
4611 if (!NT_STATUS_IS_OK(status
)) {
4612 printf("SetGroupInfo level %u failed - %s\n",
4613 r
.in
.level
, nt_errstr(status
));
4618 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
4619 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4620 r
.in
.level
, nt_errstr(status
));
4630 static bool test_QueryUserInfo(struct dcerpc_pipe
*p
,
4631 struct torture_context
*tctx
,
4632 struct policy_handle
*handle
)
4635 struct samr_QueryUserInfo r
;
4636 union samr_UserInfo
*info
;
4637 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4638 11, 12, 13, 14, 16, 17, 20, 21};
4642 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4643 printf("Testing QueryUserInfo level %u\n", levels
[i
]);
4645 r
.in
.user_handle
= handle
;
4646 r
.in
.level
= levels
[i
];
4649 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &r
);
4650 if (!NT_STATUS_IS_OK(status
)) {
4651 printf("QueryUserInfo level %u failed - %s\n",
4652 levels
[i
], nt_errstr(status
));
4660 static bool test_QueryUserInfo2(struct dcerpc_pipe
*p
,
4661 struct torture_context
*tctx
,
4662 struct policy_handle
*handle
)
4665 struct samr_QueryUserInfo2 r
;
4666 union samr_UserInfo
*info
;
4667 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4668 11, 12, 13, 14, 16, 17, 20, 21};
4672 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
4673 printf("Testing QueryUserInfo2 level %u\n", levels
[i
]);
4675 r
.in
.user_handle
= handle
;
4676 r
.in
.level
= levels
[i
];
4679 status
= dcerpc_samr_QueryUserInfo2(p
, tctx
, &r
);
4680 if (!NT_STATUS_IS_OK(status
)) {
4681 printf("QueryUserInfo2 level %u failed - %s\n",
4682 levels
[i
], nt_errstr(status
));
4690 static bool test_OpenUser(struct dcerpc_pipe
*p
,
4691 struct torture_context
*tctx
,
4692 struct policy_handle
*handle
, uint32_t rid
)
4695 struct samr_OpenUser r
;
4696 struct policy_handle user_handle
;
4699 printf("Testing OpenUser(%u)\n", rid
);
4701 r
.in
.domain_handle
= handle
;
4702 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4704 r
.out
.user_handle
= &user_handle
;
4706 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
4707 if (!NT_STATUS_IS_OK(status
)) {
4708 printf("OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
4712 if (!test_QuerySecurity(p
, tctx
, &user_handle
)) {
4716 if (!test_QueryUserInfo(p
, tctx
, &user_handle
)) {
4720 if (!test_QueryUserInfo2(p
, tctx
, &user_handle
)) {
4724 if (!test_GetUserPwInfo(p
, tctx
, &user_handle
)) {
4728 if (!test_GetGroupsForUser(p
,tctx
, &user_handle
)) {
4732 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
4739 static bool test_OpenGroup(struct dcerpc_pipe
*p
,
4740 struct torture_context
*tctx
,
4741 struct policy_handle
*handle
, uint32_t rid
)
4744 struct samr_OpenGroup r
;
4745 struct policy_handle group_handle
;
4748 printf("Testing OpenGroup(%u)\n", rid
);
4750 r
.in
.domain_handle
= handle
;
4751 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4753 r
.out
.group_handle
= &group_handle
;
4755 status
= dcerpc_samr_OpenGroup(p
, tctx
, &r
);
4756 if (!NT_STATUS_IS_OK(status
)) {
4757 printf("OpenGroup(%u) failed - %s\n", rid
, nt_errstr(status
));
4761 if (!torture_setting_bool(tctx
, "samba3", false)) {
4762 if (!test_QuerySecurity(p
, tctx
, &group_handle
)) {
4767 if (!test_QueryGroupInfo(p
, tctx
, &group_handle
)) {
4771 if (!test_QueryGroupMember(p
, tctx
, &group_handle
)) {
4775 if (!test_samr_handle_Close(p
, tctx
, &group_handle
)) {
4782 static bool test_OpenAlias(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4783 struct policy_handle
*handle
, uint32_t rid
)
4786 struct samr_OpenAlias r
;
4787 struct policy_handle alias_handle
;
4790 torture_comment(tctx
, "Testing OpenAlias(%u)\n", rid
);
4792 r
.in
.domain_handle
= handle
;
4793 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4795 r
.out
.alias_handle
= &alias_handle
;
4797 status
= dcerpc_samr_OpenAlias(p
, tctx
, &r
);
4798 if (!NT_STATUS_IS_OK(status
)) {
4799 printf("OpenAlias(%u) failed - %s\n", rid
, nt_errstr(status
));
4803 if (!torture_setting_bool(tctx
, "samba3", false)) {
4804 if (!test_QuerySecurity(p
, tctx
, &alias_handle
)) {
4809 if (!test_QueryAliasInfo(p
, tctx
, &alias_handle
)) {
4813 if (!test_GetMembersInAlias(p
, tctx
, &alias_handle
)) {
4817 if (!test_samr_handle_Close(p
, tctx
, &alias_handle
)) {
4824 static bool check_mask(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4825 struct policy_handle
*handle
, uint32_t rid
,
4826 uint32_t acct_flag_mask
)
4829 struct samr_OpenUser r
;
4830 struct samr_QueryUserInfo q
;
4831 union samr_UserInfo
*info
;
4832 struct policy_handle user_handle
;
4835 torture_comment(tctx
, "Testing OpenUser(%u)\n", rid
);
4837 r
.in
.domain_handle
= handle
;
4838 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4840 r
.out
.user_handle
= &user_handle
;
4842 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
4843 if (!NT_STATUS_IS_OK(status
)) {
4844 printf("OpenUser(%u) failed - %s\n", rid
, nt_errstr(status
));
4848 q
.in
.user_handle
= &user_handle
;
4852 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
4853 if (!NT_STATUS_IS_OK(status
)) {
4854 printf("QueryUserInfo level 16 failed - %s\n",
4858 if ((acct_flag_mask
& info
->info16
.acct_flags
) == 0) {
4859 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4860 acct_flag_mask
, info
->info16
.acct_flags
, rid
);
4865 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
4872 static bool test_EnumDomainUsers(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4873 struct policy_handle
*handle
)
4875 NTSTATUS status
= STATUS_MORE_ENTRIES
;
4876 struct samr_EnumDomainUsers r
;
4877 uint32_t mask
, resume_handle
=0;
4880 struct samr_LookupNames n
;
4881 struct samr_LookupRids lr
;
4882 struct lsa_Strings names
;
4883 struct samr_Ids rids
, types
;
4884 struct samr_SamArray
*sam
= NULL
;
4885 uint32_t num_entries
= 0;
4887 uint32_t masks
[] = {ACB_NORMAL
, ACB_DOMTRUST
, ACB_WSTRUST
,
4888 ACB_DISABLED
, ACB_NORMAL
| ACB_DISABLED
,
4889 ACB_SVRTRUST
| ACB_DOMTRUST
| ACB_WSTRUST
,
4892 printf("Testing EnumDomainUsers\n");
4894 for (mask_idx
=0;mask_idx
<ARRAY_SIZE(masks
);mask_idx
++) {
4895 r
.in
.domain_handle
= handle
;
4896 r
.in
.resume_handle
= &resume_handle
;
4897 r
.in
.acct_flags
= mask
= masks
[mask_idx
];
4898 r
.in
.max_size
= (uint32_t)-1;
4899 r
.out
.resume_handle
= &resume_handle
;
4900 r
.out
.num_entries
= &num_entries
;
4903 status
= dcerpc_samr_EnumDomainUsers(p
, tctx
, &r
);
4904 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
4905 !NT_STATUS_IS_OK(status
)) {
4906 printf("EnumDomainUsers failed - %s\n", nt_errstr(status
));
4910 torture_assert(tctx
, sam
, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4912 if (sam
->count
== 0) {
4916 for (i
=0;i
<sam
->count
;i
++) {
4918 if (!check_mask(p
, tctx
, handle
, sam
->entries
[i
].idx
, mask
)) {
4921 } else if (!test_OpenUser(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
4927 printf("Testing LookupNames\n");
4928 n
.in
.domain_handle
= handle
;
4929 n
.in
.num_names
= sam
->count
;
4930 n
.in
.names
= talloc_array(tctx
, struct lsa_String
, sam
->count
);
4932 n
.out
.types
= &types
;
4933 for (i
=0;i
<sam
->count
;i
++) {
4934 n
.in
.names
[i
].string
= sam
->entries
[i
].name
.string
;
4936 status
= dcerpc_samr_LookupNames(p
, tctx
, &n
);
4937 if (!NT_STATUS_IS_OK(status
)) {
4938 printf("LookupNames failed - %s\n", nt_errstr(status
));
4943 printf("Testing LookupRids\n");
4944 lr
.in
.domain_handle
= handle
;
4945 lr
.in
.num_rids
= sam
->count
;
4946 lr
.in
.rids
= talloc_array(tctx
, uint32_t, sam
->count
);
4947 lr
.out
.names
= &names
;
4948 lr
.out
.types
= &types
;
4949 for (i
=0;i
<sam
->count
;i
++) {
4950 lr
.in
.rids
[i
] = sam
->entries
[i
].idx
;
4952 status
= dcerpc_samr_LookupRids(p
, tctx
, &lr
);
4953 torture_assert_ntstatus_ok(tctx
, status
, "LookupRids");
4959 try blasting the server with a bunch of sync requests
4961 static bool test_EnumDomainUsers_async(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
4962 struct policy_handle
*handle
)
4965 struct samr_EnumDomainUsers r
;
4966 uint32_t resume_handle
=0;
4968 #define ASYNC_COUNT 100
4969 struct rpc_request
*req
[ASYNC_COUNT
];
4971 if (!torture_setting_bool(tctx
, "dangerous", false)) {
4972 torture_skip(tctx
, "samr async test disabled - enable dangerous tests to use\n");
4975 torture_comment(tctx
, "Testing EnumDomainUsers_async\n");
4977 r
.in
.domain_handle
= handle
;
4978 r
.in
.resume_handle
= &resume_handle
;
4979 r
.in
.acct_flags
= 0;
4980 r
.in
.max_size
= (uint32_t)-1;
4981 r
.out
.resume_handle
= &resume_handle
;
4983 for (i
=0;i
<ASYNC_COUNT
;i
++) {
4984 req
[i
] = dcerpc_samr_EnumDomainUsers_send(p
, tctx
, &r
);
4987 for (i
=0;i
<ASYNC_COUNT
;i
++) {
4988 status
= dcerpc_ndr_request_recv(req
[i
]);
4989 if (!NT_STATUS_IS_OK(status
)) {
4990 printf("EnumDomainUsers[%d] failed - %s\n",
4991 i
, nt_errstr(status
));
4996 torture_comment(tctx
, "%d async requests OK\n", i
);
5001 static bool test_EnumDomainGroups(struct dcerpc_pipe
*p
,
5002 struct torture_context
*tctx
,
5003 struct policy_handle
*handle
)
5006 struct samr_EnumDomainGroups r
;
5007 uint32_t resume_handle
=0;
5008 struct samr_SamArray
*sam
= NULL
;
5009 uint32_t num_entries
= 0;
5013 printf("Testing EnumDomainGroups\n");
5015 r
.in
.domain_handle
= handle
;
5016 r
.in
.resume_handle
= &resume_handle
;
5017 r
.in
.max_size
= (uint32_t)-1;
5018 r
.out
.resume_handle
= &resume_handle
;
5019 r
.out
.num_entries
= &num_entries
;
5022 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &r
);
5023 if (!NT_STATUS_IS_OK(status
)) {
5024 printf("EnumDomainGroups failed - %s\n", nt_errstr(status
));
5032 for (i
=0;i
<sam
->count
;i
++) {
5033 if (!test_OpenGroup(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5041 static bool test_EnumDomainAliases(struct dcerpc_pipe
*p
,
5042 struct torture_context
*tctx
,
5043 struct policy_handle
*handle
)
5046 struct samr_EnumDomainAliases r
;
5047 uint32_t resume_handle
=0;
5048 struct samr_SamArray
*sam
= NULL
;
5049 uint32_t num_entries
= 0;
5053 printf("Testing EnumDomainAliases\n");
5055 r
.in
.domain_handle
= handle
;
5056 r
.in
.resume_handle
= &resume_handle
;
5057 r
.in
.max_size
= (uint32_t)-1;
5059 r
.out
.num_entries
= &num_entries
;
5060 r
.out
.resume_handle
= &resume_handle
;
5062 status
= dcerpc_samr_EnumDomainAliases(p
, tctx
, &r
);
5063 if (!NT_STATUS_IS_OK(status
)) {
5064 printf("EnumDomainAliases failed - %s\n", nt_errstr(status
));
5072 for (i
=0;i
<sam
->count
;i
++) {
5073 if (!test_OpenAlias(p
, tctx
, handle
, sam
->entries
[i
].idx
)) {
5081 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe
*p
,
5082 struct torture_context
*tctx
,
5083 struct policy_handle
*handle
)
5086 struct samr_GetDisplayEnumerationIndex r
;
5088 uint16_t levels
[] = {1, 2, 3, 4, 5};
5089 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
5090 struct lsa_String name
;
5094 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5095 printf("Testing GetDisplayEnumerationIndex level %u\n", levels
[i
]);
5097 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
5099 r
.in
.domain_handle
= handle
;
5100 r
.in
.level
= levels
[i
];
5104 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, tctx
, &r
);
5107 !NT_STATUS_IS_OK(status
) &&
5108 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
5109 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5110 levels
[i
], nt_errstr(status
));
5114 init_lsa_String(&name
, "zzzzzzzz");
5116 status
= dcerpc_samr_GetDisplayEnumerationIndex(p
, tctx
, &r
);
5118 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
5119 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5120 levels
[i
], nt_errstr(status
));
5128 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe
*p
,
5129 struct torture_context
*tctx
,
5130 struct policy_handle
*handle
)
5133 struct samr_GetDisplayEnumerationIndex2 r
;
5135 uint16_t levels
[] = {1, 2, 3, 4, 5};
5136 uint16_t ok_lvl
[] = {1, 1, 1, 0, 0};
5137 struct lsa_String name
;
5141 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5142 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels
[i
]);
5144 init_lsa_String(&name
, TEST_ACCOUNT_NAME
);
5146 r
.in
.domain_handle
= handle
;
5147 r
.in
.level
= levels
[i
];
5151 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, tctx
, &r
);
5153 !NT_STATUS_IS_OK(status
) &&
5154 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
5155 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5156 levels
[i
], nt_errstr(status
));
5160 init_lsa_String(&name
, "zzzzzzzz");
5162 status
= dcerpc_samr_GetDisplayEnumerationIndex2(p
, tctx
, &r
);
5163 if (ok_lvl
[i
] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES
, status
)) {
5164 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5165 levels
[i
], nt_errstr(status
));
5173 #define STRING_EQUAL_QUERY(s1, s2, user) \
5174 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5175 /* odd, but valid */ \
5176 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5177 printf("%s mismatch for %s: %s != %s (%s)\n", \
5178 #s1, user.string, s1.string, s2.string, __location__); \
5181 #define INT_EQUAL_QUERY(s1, s2, user) \
5183 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5184 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5188 static bool test_each_DisplayInfo_user(struct dcerpc_pipe
*p
,
5189 struct torture_context
*tctx
,
5190 struct samr_QueryDisplayInfo
*querydisplayinfo
,
5191 bool *seen_testuser
)
5193 struct samr_OpenUser r
;
5194 struct samr_QueryUserInfo q
;
5195 union samr_UserInfo
*info
;
5196 struct policy_handle user_handle
;
5199 r
.in
.domain_handle
= querydisplayinfo
->in
.domain_handle
;
5200 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5201 for (i
= 0; ; i
++) {
5202 switch (querydisplayinfo
->in
.level
) {
5204 if (i
>= querydisplayinfo
->out
.info
->info1
.count
) {
5207 r
.in
.rid
= querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
;
5210 if (i
>= querydisplayinfo
->out
.info
->info2
.count
) {
5213 r
.in
.rid
= querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
;
5219 /* Not interested in validating just the account name */
5223 r
.out
.user_handle
= &user_handle
;
5225 switch (querydisplayinfo
->in
.level
) {
5228 status
= dcerpc_samr_OpenUser(p
, tctx
, &r
);
5229 if (!NT_STATUS_IS_OK(status
)) {
5230 printf("OpenUser(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
5235 q
.in
.user_handle
= &user_handle
;
5238 status
= dcerpc_samr_QueryUserInfo(p
, tctx
, &q
);
5239 if (!NT_STATUS_IS_OK(status
)) {
5240 printf("QueryUserInfo(%u) failed - %s\n", r
.in
.rid
, nt_errstr(status
));
5244 switch (querydisplayinfo
->in
.level
) {
5246 if (seen_testuser
&& strcmp(info
->info21
.account_name
.string
, TEST_ACCOUNT_NAME
) == 0) {
5247 *seen_testuser
= true;
5249 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].full_name
,
5250 info
->info21
.full_name
, info
->info21
.account_name
);
5251 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].account_name
,
5252 info
->info21
.account_name
, info
->info21
.account_name
);
5253 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].description
,
5254 info
->info21
.description
, info
->info21
.account_name
);
5255 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].rid
,
5256 info
->info21
.rid
, info
->info21
.account_name
);
5257 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info1
.entries
[i
].acct_flags
,
5258 info
->info21
.acct_flags
, info
->info21
.account_name
);
5262 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].account_name
,
5263 info
->info21
.account_name
, info
->info21
.account_name
);
5264 STRING_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].description
,
5265 info
->info21
.description
, info
->info21
.account_name
);
5266 INT_EQUAL_QUERY(querydisplayinfo
->out
.info
->info2
.entries
[i
].rid
,
5267 info
->info21
.rid
, info
->info21
.account_name
);
5268 INT_EQUAL_QUERY((querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ~ACB_NORMAL
),
5269 info
->info21
.acct_flags
, info
->info21
.account_name
);
5271 if (!(querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
& ACB_NORMAL
)) {
5272 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5273 info
->info21
.account_name
.string
);
5276 if (!(info
->info21
.acct_flags
& (ACB_WSTRUST
| ACB_SVRTRUST
))) {
5277 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5278 info
->info21
.account_name
.string
,
5279 querydisplayinfo
->out
.info
->info2
.entries
[i
].acct_flags
,
5280 info
->info21
.acct_flags
);
5287 if (!test_samr_handle_Close(p
, tctx
, &user_handle
)) {
5294 static bool test_QueryDisplayInfo(struct dcerpc_pipe
*p
,
5295 struct torture_context
*tctx
,
5296 struct policy_handle
*handle
)
5299 struct samr_QueryDisplayInfo r
;
5300 struct samr_QueryDomainInfo dom_info
;
5301 union samr_DomainInfo
*info
= NULL
;
5303 uint16_t levels
[] = {1, 2, 3, 4, 5};
5305 bool seen_testuser
= false;
5306 uint32_t total_size
;
5307 uint32_t returned_size
;
5308 union samr_DispInfo disp_info
;
5311 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5312 printf("Testing QueryDisplayInfo level %u\n", levels
[i
]);
5315 status
= STATUS_MORE_ENTRIES
;
5316 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
5317 r
.in
.domain_handle
= handle
;
5318 r
.in
.level
= levels
[i
];
5319 r
.in
.max_entries
= 2;
5320 r
.in
.buf_size
= (uint32_t)-1;
5321 r
.out
.total_size
= &total_size
;
5322 r
.out
.returned_size
= &returned_size
;
5323 r
.out
.info
= &disp_info
;
5325 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
5326 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) && !NT_STATUS_IS_OK(status
)) {
5327 printf("QueryDisplayInfo level %u failed - %s\n",
5328 levels
[i
], nt_errstr(status
));
5331 switch (r
.in
.level
) {
5333 if (!test_each_DisplayInfo_user(p
, tctx
, &r
, &seen_testuser
)) {
5336 r
.in
.start_idx
+= r
.out
.info
->info1
.count
;
5339 if (!test_each_DisplayInfo_user(p
, tctx
, &r
, NULL
)) {
5342 r
.in
.start_idx
+= r
.out
.info
->info2
.count
;
5345 r
.in
.start_idx
+= r
.out
.info
->info3
.count
;
5348 r
.in
.start_idx
+= r
.out
.info
->info4
.count
;
5351 r
.in
.start_idx
+= r
.out
.info
->info5
.count
;
5355 dom_info
.in
.domain_handle
= handle
;
5356 dom_info
.in
.level
= 2;
5357 dom_info
.out
.info
= &info
;
5359 /* Check number of users returned is correct */
5360 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &dom_info
);
5361 if (!NT_STATUS_IS_OK(status
)) {
5362 printf("QueryDomainInfo level %u failed - %s\n",
5363 r
.in
.level
, nt_errstr(status
));
5367 switch (r
.in
.level
) {
5370 if (info
->general
.num_users
< r
.in
.start_idx
) {
5371 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5372 r
.in
.start_idx
, info
->general
.num_groups
,
5373 info
->general
.domain_name
.string
);
5376 if (!seen_testuser
) {
5377 struct policy_handle user_handle
;
5378 if (NT_STATUS_IS_OK(test_OpenUser_byname(p
, tctx
, handle
, TEST_ACCOUNT_NAME
, &user_handle
))) {
5379 printf("Didn't find test user " TEST_ACCOUNT_NAME
" in enumeration of %s\n",
5380 info
->general
.domain_name
.string
);
5382 test_samr_handle_Close(p
, tctx
, &user_handle
);
5388 if (info
->general
.num_groups
!= r
.in
.start_idx
) {
5389 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5390 r
.in
.start_idx
, info
->general
.num_groups
,
5391 info
->general
.domain_name
.string
);
5403 static bool test_QueryDisplayInfo2(struct dcerpc_pipe
*p
,
5404 struct torture_context
*tctx
,
5405 struct policy_handle
*handle
)
5408 struct samr_QueryDisplayInfo2 r
;
5410 uint16_t levels
[] = {1, 2, 3, 4, 5};
5412 uint32_t total_size
;
5413 uint32_t returned_size
;
5414 union samr_DispInfo info
;
5416 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5417 printf("Testing QueryDisplayInfo2 level %u\n", levels
[i
]);
5419 r
.in
.domain_handle
= handle
;
5420 r
.in
.level
= levels
[i
];
5422 r
.in
.max_entries
= 1000;
5423 r
.in
.buf_size
= (uint32_t)-1;
5424 r
.out
.total_size
= &total_size
;
5425 r
.out
.returned_size
= &returned_size
;
5428 status
= dcerpc_samr_QueryDisplayInfo2(p
, tctx
, &r
);
5429 if (!NT_STATUS_IS_OK(status
)) {
5430 printf("QueryDisplayInfo2 level %u failed - %s\n",
5431 levels
[i
], nt_errstr(status
));
5439 static bool test_QueryDisplayInfo3(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5440 struct policy_handle
*handle
)
5443 struct samr_QueryDisplayInfo3 r
;
5445 uint16_t levels
[] = {1, 2, 3, 4, 5};
5447 uint32_t total_size
;
5448 uint32_t returned_size
;
5449 union samr_DispInfo info
;
5451 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5452 torture_comment(tctx
, "Testing QueryDisplayInfo3 level %u\n", levels
[i
]);
5454 r
.in
.domain_handle
= handle
;
5455 r
.in
.level
= levels
[i
];
5457 r
.in
.max_entries
= 1000;
5458 r
.in
.buf_size
= (uint32_t)-1;
5459 r
.out
.total_size
= &total_size
;
5460 r
.out
.returned_size
= &returned_size
;
5463 status
= dcerpc_samr_QueryDisplayInfo3(p
, tctx
, &r
);
5464 if (!NT_STATUS_IS_OK(status
)) {
5465 printf("QueryDisplayInfo3 level %u failed - %s\n",
5466 levels
[i
], nt_errstr(status
));
5475 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe
*p
,
5476 struct torture_context
*tctx
,
5477 struct policy_handle
*handle
)
5480 struct samr_QueryDisplayInfo r
;
5482 uint32_t total_size
;
5483 uint32_t returned_size
;
5484 union samr_DispInfo info
;
5486 printf("Testing QueryDisplayInfo continuation\n");
5488 r
.in
.domain_handle
= handle
;
5491 r
.in
.max_entries
= 1;
5492 r
.in
.buf_size
= (uint32_t)-1;
5493 r
.out
.total_size
= &total_size
;
5494 r
.out
.returned_size
= &returned_size
;
5498 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &r
);
5499 if (NT_STATUS_IS_OK(status
) && *r
.out
.returned_size
!= 0) {
5500 if (r
.out
.info
->info1
.entries
[0].idx
!= r
.in
.start_idx
+ 1) {
5501 printf("expected idx %d but got %d\n",
5503 r
.out
.info
->info1
.entries
[0].idx
);
5507 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) &&
5508 !NT_STATUS_IS_OK(status
)) {
5509 printf("QueryDisplayInfo level %u failed - %s\n",
5510 r
.in
.level
, nt_errstr(status
));
5515 } while ((NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
) ||
5516 NT_STATUS_IS_OK(status
)) &&
5517 *r
.out
.returned_size
!= 0);
5522 static bool test_QueryDomainInfo(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5523 struct policy_handle
*handle
)
5526 struct samr_QueryDomainInfo r
;
5527 union samr_DomainInfo
*info
= NULL
;
5528 struct samr_SetDomainInfo s
;
5529 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5530 uint16_t set_ok
[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
5533 const char *domain_comment
= talloc_asprintf(tctx
,
5534 "Tortured by Samba4 RPC-SAMR: %s",
5535 timestring(tctx
, time(NULL
)));
5537 s
.in
.domain_handle
= handle
;
5539 s
.in
.info
= talloc(tctx
, union samr_DomainInfo
);
5541 s
.in
.info
->oem
.oem_information
.string
= domain_comment
;
5542 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
5543 if (!NT_STATUS_IS_OK(status
)) {
5544 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5545 s
.in
.level
, nt_errstr(status
));
5549 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5550 torture_comment(tctx
, "Testing QueryDomainInfo level %u\n", levels
[i
]);
5552 r
.in
.domain_handle
= handle
;
5553 r
.in
.level
= levels
[i
];
5556 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
5557 if (!NT_STATUS_IS_OK(status
)) {
5558 printf("QueryDomainInfo level %u failed - %s\n",
5559 r
.in
.level
, nt_errstr(status
));
5564 switch (levels
[i
]) {
5566 if (strcmp(info
->general
.oem_information
.string
, domain_comment
) != 0) {
5567 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5568 levels
[i
], info
->general
.oem_information
.string
, domain_comment
);
5571 if (!info
->general
.primary
.string
) {
5572 printf("QueryDomainInfo level %u returned no PDC name\n",
5575 } else if (info
->general
.role
== SAMR_ROLE_DOMAIN_PDC
) {
5576 if (dcerpc_server_name(p
) && strcasecmp_m(dcerpc_server_name(p
), info
->general
.primary
.string
) != 0) {
5577 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5578 levels
[i
], info
->general
.primary
.string
, dcerpc_server_name(p
));
5583 if (strcmp(info
->oem
.oem_information
.string
, domain_comment
) != 0) {
5584 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5585 levels
[i
], info
->oem
.oem_information
.string
, domain_comment
);
5590 if (!info
->info6
.primary
.string
) {
5591 printf("QueryDomainInfo level %u returned no PDC name\n",
5597 if (strcmp(info
->general2
.general
.oem_information
.string
, domain_comment
) != 0) {
5598 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5599 levels
[i
], info
->general2
.general
.oem_information
.string
, domain_comment
);
5605 torture_comment(tctx
, "Testing SetDomainInfo level %u\n", levels
[i
]);
5607 s
.in
.domain_handle
= handle
;
5608 s
.in
.level
= levels
[i
];
5611 status
= dcerpc_samr_SetDomainInfo(p
, tctx
, &s
);
5613 if (!NT_STATUS_IS_OK(status
)) {
5614 printf("SetDomainInfo level %u failed - %s\n",
5615 r
.in
.level
, nt_errstr(status
));
5620 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS
, status
)) {
5621 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5622 r
.in
.level
, nt_errstr(status
));
5628 status
= dcerpc_samr_QueryDomainInfo(p
, tctx
, &r
);
5629 if (!NT_STATUS_IS_OK(status
)) {
5630 printf("QueryDomainInfo level %u failed - %s\n",
5631 r
.in
.level
, nt_errstr(status
));
5641 static bool test_QueryDomainInfo2(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5642 struct policy_handle
*handle
)
5645 struct samr_QueryDomainInfo2 r
;
5646 union samr_DomainInfo
*info
= NULL
;
5647 uint16_t levels
[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5651 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
5652 printf("Testing QueryDomainInfo2 level %u\n", levels
[i
]);
5654 r
.in
.domain_handle
= handle
;
5655 r
.in
.level
= levels
[i
];
5658 status
= dcerpc_samr_QueryDomainInfo2(p
, tctx
, &r
);
5659 if (!NT_STATUS_IS_OK(status
)) {
5660 printf("QueryDomainInfo2 level %u failed - %s\n",
5661 r
.in
.level
, nt_errstr(status
));
5670 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5671 set of group names. */
5672 static bool test_GroupList(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5673 struct policy_handle
*handle
)
5675 struct samr_EnumDomainGroups q1
;
5676 struct samr_QueryDisplayInfo q2
;
5678 uint32_t resume_handle
=0;
5679 struct samr_SamArray
*sam
= NULL
;
5680 uint32_t num_entries
= 0;
5683 uint32_t total_size
;
5684 uint32_t returned_size
;
5685 union samr_DispInfo info
;
5688 const char **names
= NULL
;
5690 torture_comment(tctx
, "Testing coherency of querydispinfo vs enumdomgroups\n");
5692 q1
.in
.domain_handle
= handle
;
5693 q1
.in
.resume_handle
= &resume_handle
;
5695 q1
.out
.resume_handle
= &resume_handle
;
5696 q1
.out
.num_entries
= &num_entries
;
5699 status
= STATUS_MORE_ENTRIES
;
5700 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
5701 status
= dcerpc_samr_EnumDomainGroups(p
, tctx
, &q1
);
5703 if (!NT_STATUS_IS_OK(status
) &&
5704 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
5707 for (i
=0; i
<*q1
.out
.num_entries
; i
++) {
5708 add_string_to_array(tctx
,
5709 sam
->entries
[i
].name
.string
,
5710 &names
, &num_names
);
5714 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomainGroups");
5716 torture_assert(tctx
, sam
, "EnumDomainGroups failed to return sam");
5718 q2
.in
.domain_handle
= handle
;
5720 q2
.in
.start_idx
= 0;
5721 q2
.in
.max_entries
= 5;
5722 q2
.in
.buf_size
= (uint32_t)-1;
5723 q2
.out
.total_size
= &total_size
;
5724 q2
.out
.returned_size
= &returned_size
;
5725 q2
.out
.info
= &info
;
5727 status
= STATUS_MORE_ENTRIES
;
5728 while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
5729 status
= dcerpc_samr_QueryDisplayInfo(p
, tctx
, &q2
);
5731 if (!NT_STATUS_IS_OK(status
) &&
5732 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
5735 for (i
=0; i
<q2
.out
.info
->info5
.count
; i
++) {
5737 const char *name
= q2
.out
.info
->info5
.entries
[i
].account_name
.string
;
5739 for (j
=0; j
<num_names
; j
++) {
5740 if (names
[j
] == NULL
)
5742 if (strequal(names
[j
], name
)) {
5750 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5755 q2
.in
.start_idx
+= q2
.out
.info
->info5
.count
;
5758 if (!NT_STATUS_IS_OK(status
)) {
5759 printf("QueryDisplayInfo level 5 failed - %s\n",
5764 for (i
=0; i
<num_names
; i
++) {
5765 if (names
[i
] != NULL
) {
5766 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5775 static bool test_DeleteDomainGroup(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5776 struct policy_handle
*group_handle
)
5778 struct samr_DeleteDomainGroup d
;
5781 torture_comment(tctx
, "Testing DeleteDomainGroup\n");
5783 d
.in
.group_handle
= group_handle
;
5784 d
.out
.group_handle
= group_handle
;
5786 status
= dcerpc_samr_DeleteDomainGroup(p
, tctx
, &d
);
5787 torture_assert_ntstatus_ok(tctx
, status
, "DeleteDomainGroup");
5792 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5793 struct policy_handle
*domain_handle
)
5795 struct samr_TestPrivateFunctionsDomain r
;
5799 torture_comment(tctx
, "Testing TestPrivateFunctionsDomain\n");
5801 r
.in
.domain_handle
= domain_handle
;
5803 status
= dcerpc_samr_TestPrivateFunctionsDomain(p
, tctx
, &r
);
5804 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NOT_IMPLEMENTED
, "TestPrivateFunctionsDomain");
5809 static bool test_RidToSid(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5810 struct dom_sid
*domain_sid
,
5811 struct policy_handle
*domain_handle
)
5813 struct samr_RidToSid r
;
5816 struct dom_sid
*calc_sid
, *out_sid
;
5817 int rids
[] = { 0, 42, 512, 10200 };
5820 for (i
=0;i
<ARRAY_SIZE(rids
);i
++) {
5821 torture_comment(tctx
, "Testing RidToSid\n");
5823 calc_sid
= dom_sid_dup(tctx
, domain_sid
);
5824 r
.in
.domain_handle
= domain_handle
;
5826 r
.out
.sid
= &out_sid
;
5828 status
= dcerpc_samr_RidToSid(p
, tctx
, &r
);
5829 if (!NT_STATUS_IS_OK(status
)) {
5830 printf("RidToSid for %d failed - %s\n", rids
[i
], nt_errstr(status
));
5833 calc_sid
= dom_sid_add_rid(calc_sid
, calc_sid
, rids
[i
]);
5835 if (!dom_sid_equal(calc_sid
, out_sid
)) {
5836 printf("RidToSid for %d failed - got %s, expected %s\n", rids
[i
],
5837 dom_sid_string(tctx
, out_sid
),
5838 dom_sid_string(tctx
, calc_sid
));
5847 static bool test_GetBootKeyInformation(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5848 struct policy_handle
*domain_handle
)
5850 struct samr_GetBootKeyInformation r
;
5853 uint32_t unknown
= 0;
5855 torture_comment(tctx
, "Testing GetBootKeyInformation\n");
5857 r
.in
.domain_handle
= domain_handle
;
5858 r
.out
.unknown
= &unknown
;
5860 status
= dcerpc_samr_GetBootKeyInformation(p
, tctx
, &r
);
5861 if (!NT_STATUS_IS_OK(status
)) {
5862 /* w2k3 seems to fail this sometimes and pass it sometimes */
5863 torture_comment(tctx
, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status
));
5869 static bool test_AddGroupMember(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
5870 struct policy_handle
*domain_handle
,
5871 struct policy_handle
*group_handle
)
5874 struct samr_AddGroupMember r
;
5875 struct samr_DeleteGroupMember d
;
5876 struct samr_QueryGroupMember q
;
5877 struct samr_RidTypeArray
*rids
= NULL
;
5878 struct samr_SetMemberAttributesOfGroup s
;
5881 status
= test_LookupName(p
, tctx
, domain_handle
, TEST_ACCOUNT_NAME
, &rid
);
5882 torture_assert_ntstatus_ok(tctx
, status
, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME
);
5884 r
.in
.group_handle
= group_handle
;
5886 r
.in
.flags
= 0; /* ??? */
5888 torture_comment(tctx
, "Testing AddGroupMember and DeleteGroupMember\n");
5890 d
.in
.group_handle
= group_handle
;
5893 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
5894 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_NOT_IN_GROUP
, status
, "DeleteGroupMember");
5896 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
5897 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
5899 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
5900 torture_assert_ntstatus_equal(tctx
, NT_STATUS_MEMBER_IN_GROUP
, status
, "AddGroupMember");
5902 if (torture_setting_bool(tctx
, "samba4", false) ||
5903 torture_setting_bool(tctx
, "samba3", false)) {
5904 torture_comment(tctx
, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5906 /* this one is quite strange. I am using random inputs in the
5907 hope of triggering an error that might give us a clue */
5909 s
.in
.group_handle
= group_handle
;
5910 s
.in
.unknown1
= random();
5911 s
.in
.unknown2
= random();
5913 status
= dcerpc_samr_SetMemberAttributesOfGroup(p
, tctx
, &s
);
5914 torture_assert_ntstatus_ok(tctx
, status
, "SetMemberAttributesOfGroup");
5917 q
.in
.group_handle
= group_handle
;
5920 status
= dcerpc_samr_QueryGroupMember(p
, tctx
, &q
);
5921 torture_assert_ntstatus_ok(tctx
, status
, "QueryGroupMember");
5923 status
= dcerpc_samr_DeleteGroupMember(p
, tctx
, &d
);
5924 torture_assert_ntstatus_ok(tctx
, status
, "DeleteGroupMember");
5926 status
= dcerpc_samr_AddGroupMember(p
, tctx
, &r
);
5927 torture_assert_ntstatus_ok(tctx
, status
, "AddGroupMember");
5933 static bool test_CreateDomainGroup(struct dcerpc_pipe
*p
,
5934 struct torture_context
*tctx
,
5935 struct policy_handle
*domain_handle
,
5936 struct policy_handle
*group_handle
,
5937 struct dom_sid
*domain_sid
)
5940 struct samr_CreateDomainGroup r
;
5942 struct lsa_String name
;
5945 init_lsa_String(&name
, TEST_GROUPNAME
);
5947 r
.in
.domain_handle
= domain_handle
;
5949 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
5950 r
.out
.group_handle
= group_handle
;
5953 printf("Testing CreateDomainGroup(%s)\n", r
.in
.name
->string
);
5955 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
5957 if (dom_sid_equal(domain_sid
, dom_sid_parse_talloc(tctx
, SID_BUILTIN
))) {
5958 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5959 torture_comment(tctx
, "Server correctly refused create of '%s'\n", r
.in
.name
->string
);
5962 printf("Server should have refused create of '%s', got %s instead\n", r
.in
.name
->string
,
5968 if (NT_STATUS_EQUAL(status
, NT_STATUS_GROUP_EXISTS
)) {
5969 if (!test_DeleteGroup_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
5970 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r
.in
.name
->string
,
5974 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
5976 if (NT_STATUS_EQUAL(status
, NT_STATUS_USER_EXISTS
)) {
5977 if (!test_DeleteUser_byname(p
, tctx
, domain_handle
, r
.in
.name
->string
)) {
5979 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r
.in
.name
->string
,
5983 status
= dcerpc_samr_CreateDomainGroup(p
, tctx
, &r
);
5985 torture_assert_ntstatus_ok(tctx
, status
, "CreateDomainGroup");
5987 if (!test_AddGroupMember(p
, tctx
, domain_handle
, group_handle
)) {
5988 printf("CreateDomainGroup failed - %s\n", nt_errstr(status
));
5992 if (!test_SetGroupInfo(p
, tctx
, group_handle
)) {
6001 its not totally clear what this does. It seems to accept any sid you like.
6003 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe
*p
,
6004 struct torture_context
*tctx
,
6005 struct policy_handle
*domain_handle
)
6008 struct samr_RemoveMemberFromForeignDomain r
;
6010 r
.in
.domain_handle
= domain_handle
;
6011 r
.in
.sid
= dom_sid_parse_talloc(tctx
, "S-1-5-32-12-34-56-78");
6013 status
= dcerpc_samr_RemoveMemberFromForeignDomain(p
, tctx
, &r
);
6014 torture_assert_ntstatus_ok(tctx
, status
, "RemoveMemberFromForeignDomain");
6021 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6022 struct policy_handle
*handle
);
6024 static bool test_OpenDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6025 struct policy_handle
*handle
, struct dom_sid
*sid
,
6026 enum torture_samr_choice which_ops
,
6027 struct cli_credentials
*machine_credentials
)
6030 struct samr_OpenDomain r
;
6031 struct policy_handle domain_handle
;
6032 struct policy_handle alias_handle
;
6033 struct policy_handle user_handle
;
6034 struct policy_handle group_handle
;
6037 ZERO_STRUCT(alias_handle
);
6038 ZERO_STRUCT(user_handle
);
6039 ZERO_STRUCT(group_handle
);
6040 ZERO_STRUCT(domain_handle
);
6042 torture_comment(tctx
, "Testing OpenDomain of %s\n", dom_sid_string(tctx
, sid
));
6044 r
.in
.connect_handle
= handle
;
6045 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6047 r
.out
.domain_handle
= &domain_handle
;
6049 status
= dcerpc_samr_OpenDomain(p
, tctx
, &r
);
6050 torture_assert_ntstatus_ok(tctx
, status
, "OpenDomain");
6052 /* run the domain tests with the main handle closed - this tests
6053 the servers reference counting */
6054 ret
&= test_samr_handle_Close(p
, tctx
, handle
);
6056 switch (which_ops
) {
6057 case TORTURE_SAMR_USER_ATTRIBUTES
:
6058 case TORTURE_SAMR_USER_PRIVILEGES
:
6059 case TORTURE_SAMR_PASSWORDS
:
6060 if (!torture_setting_bool(tctx
, "samba3", false)) {
6061 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, which_ops
, NULL
);
6063 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, &user_handle
, sid
, which_ops
, NULL
);
6064 /* This test needs 'complex' users to validate */
6065 ret
&= test_QueryDisplayInfo(p
, tctx
, &domain_handle
);
6067 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx
, sid
));
6070 case TORTURE_SAMR_PASSWORDS_PWDLASTSET
:
6071 if (!torture_setting_bool(tctx
, "samba3", false)) {
6072 ret
&= test_CreateUser2(p
, tctx
, &domain_handle
, sid
, which_ops
, machine_credentials
);
6074 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, &user_handle
, sid
, which_ops
, machine_credentials
);
6076 printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx
, sid
));
6079 case TORTURE_SAMR_OTHER
:
6080 ret
&= test_CreateUser(p
, tctx
, &domain_handle
, &user_handle
, sid
, which_ops
, NULL
);
6082 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx
, sid
));
6084 if (!torture_setting_bool(tctx
, "samba3", false)) {
6085 ret
&= test_QuerySecurity(p
, tctx
, &domain_handle
);
6087 ret
&= test_RemoveMemberFromForeignDomain(p
, tctx
, &domain_handle
);
6088 ret
&= test_CreateAlias(p
, tctx
, &domain_handle
, &alias_handle
, sid
);
6089 ret
&= test_CreateDomainGroup(p
, tctx
, &domain_handle
, &group_handle
, sid
);
6090 ret
&= test_QueryDomainInfo(p
, tctx
, &domain_handle
);
6091 ret
&= test_QueryDomainInfo2(p
, tctx
, &domain_handle
);
6092 ret
&= test_EnumDomainUsers(p
, tctx
, &domain_handle
);
6093 ret
&= test_EnumDomainUsers_async(p
, tctx
, &domain_handle
);
6094 ret
&= test_EnumDomainGroups(p
, tctx
, &domain_handle
);
6095 ret
&= test_EnumDomainAliases(p
, tctx
, &domain_handle
);
6096 ret
&= test_QueryDisplayInfo2(p
, tctx
, &domain_handle
);
6097 ret
&= test_QueryDisplayInfo3(p
, tctx
, &domain_handle
);
6098 ret
&= test_QueryDisplayInfo_continue(p
, tctx
, &domain_handle
);
6100 if (torture_setting_bool(tctx
, "samba4", false)) {
6101 torture_comment(tctx
, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6103 ret
&= test_GetDisplayEnumerationIndex(p
, tctx
, &domain_handle
);
6104 ret
&= test_GetDisplayEnumerationIndex2(p
, tctx
, &domain_handle
);
6106 ret
&= test_GroupList(p
, tctx
, &domain_handle
);
6107 ret
&= test_TestPrivateFunctionsDomain(p
, tctx
, &domain_handle
);
6108 ret
&= test_RidToSid(p
, tctx
, sid
, &domain_handle
);
6109 ret
&= test_GetBootKeyInformation(p
, tctx
, &domain_handle
);
6111 torture_comment(tctx
, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx
, sid
));
6116 if (!policy_handle_empty(&user_handle
) &&
6117 !test_DeleteUser(p
, tctx
, &user_handle
)) {
6121 if (!policy_handle_empty(&alias_handle
) &&
6122 !test_DeleteAlias(p
, tctx
, &alias_handle
)) {
6126 if (!policy_handle_empty(&group_handle
) &&
6127 !test_DeleteDomainGroup(p
, tctx
, &group_handle
)) {
6131 ret
&= test_samr_handle_Close(p
, tctx
, &domain_handle
);
6133 /* reconnect the main handle */
6134 ret
&= test_Connect(p
, tctx
, handle
);
6137 printf("Testing domain %s failed!\n", dom_sid_string(tctx
, sid
));
6143 static bool test_LookupDomain(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6144 struct policy_handle
*handle
, const char *domain
,
6145 enum torture_samr_choice which_ops
,
6146 struct cli_credentials
*machine_credentials
)
6149 struct samr_LookupDomain r
;
6150 struct dom_sid2
*sid
= NULL
;
6151 struct lsa_String n1
;
6152 struct lsa_String n2
;
6155 torture_comment(tctx
, "Testing LookupDomain(%s)\n", domain
);
6157 /* check for correct error codes */
6158 r
.in
.connect_handle
= handle
;
6159 r
.in
.domain_name
= &n2
;
6163 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
6164 torture_assert_ntstatus_equal(tctx
, NT_STATUS_INVALID_PARAMETER
, status
, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6166 init_lsa_String(&n2
, "xxNODOMAINxx");
6168 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
6169 torture_assert_ntstatus_equal(tctx
, NT_STATUS_NO_SUCH_DOMAIN
, status
, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6171 r
.in
.connect_handle
= handle
;
6173 init_lsa_String(&n1
, domain
);
6174 r
.in
.domain_name
= &n1
;
6176 status
= dcerpc_samr_LookupDomain(p
, tctx
, &r
);
6177 torture_assert_ntstatus_ok(tctx
, status
, "LookupDomain");
6179 if (!test_GetDomPwInfo(p
, tctx
, &n1
)) {
6183 if (!test_OpenDomain(p
, tctx
, handle
, *r
.out
.sid
, which_ops
,
6184 machine_credentials
)) {
6192 static bool test_EnumDomains(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6193 struct policy_handle
*handle
, enum torture_samr_choice which_ops
,
6194 struct cli_credentials
*machine_credentials
)
6197 struct samr_EnumDomains r
;
6198 uint32_t resume_handle
= 0;
6199 uint32_t num_entries
= 0;
6200 struct samr_SamArray
*sam
= NULL
;
6204 r
.in
.connect_handle
= handle
;
6205 r
.in
.resume_handle
= &resume_handle
;
6206 r
.in
.buf_size
= (uint32_t)-1;
6207 r
.out
.resume_handle
= &resume_handle
;
6208 r
.out
.num_entries
= &num_entries
;
6211 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
6212 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
6218 for (i
=0;i
<sam
->count
;i
++) {
6219 if (!test_LookupDomain(p
, tctx
, handle
,
6220 sam
->entries
[i
].name
.string
, which_ops
,
6221 machine_credentials
)) {
6226 status
= dcerpc_samr_EnumDomains(p
, tctx
, &r
);
6227 torture_assert_ntstatus_ok(tctx
, status
, "EnumDomains");
6233 static bool test_Connect(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
6234 struct policy_handle
*handle
)
6237 struct samr_Connect r
;
6238 struct samr_Connect2 r2
;
6239 struct samr_Connect3 r3
;
6240 struct samr_Connect4 r4
;
6241 struct samr_Connect5 r5
;
6242 union samr_ConnectInfo info
;
6243 struct policy_handle h
;
6244 uint32_t level_out
= 0;
6245 bool ret
= true, got_handle
= false;
6247 torture_comment(tctx
, "testing samr_Connect\n");
6249 r
.in
.system_name
= 0;
6250 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6251 r
.out
.connect_handle
= &h
;
6253 status
= dcerpc_samr_Connect(p
, tctx
, &r
);
6254 if (!NT_STATUS_IS_OK(status
)) {
6255 torture_comment(tctx
, "Connect failed - %s\n", nt_errstr(status
));
6262 torture_comment(tctx
, "testing samr_Connect2\n");
6264 r2
.in
.system_name
= NULL
;
6265 r2
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6266 r2
.out
.connect_handle
= &h
;
6268 status
= dcerpc_samr_Connect2(p
, tctx
, &r2
);
6269 if (!NT_STATUS_IS_OK(status
)) {
6270 torture_comment(tctx
, "Connect2 failed - %s\n", nt_errstr(status
));
6274 test_samr_handle_Close(p
, tctx
, handle
);
6280 torture_comment(tctx
, "testing samr_Connect3\n");
6282 r3
.in
.system_name
= NULL
;
6284 r3
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6285 r3
.out
.connect_handle
= &h
;
6287 status
= dcerpc_samr_Connect3(p
, tctx
, &r3
);
6288 if (!NT_STATUS_IS_OK(status
)) {
6289 printf("Connect3 failed - %s\n", nt_errstr(status
));
6293 test_samr_handle_Close(p
, tctx
, handle
);
6299 torture_comment(tctx
, "testing samr_Connect4\n");
6301 r4
.in
.system_name
= "";
6302 r4
.in
.client_version
= 0;
6303 r4
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6304 r4
.out
.connect_handle
= &h
;
6306 status
= dcerpc_samr_Connect4(p
, tctx
, &r4
);
6307 if (!NT_STATUS_IS_OK(status
)) {
6308 printf("Connect4 failed - %s\n", nt_errstr(status
));
6312 test_samr_handle_Close(p
, tctx
, handle
);
6318 torture_comment(tctx
, "testing samr_Connect5\n");
6320 info
.info1
.client_version
= 0;
6321 info
.info1
.unknown2
= 0;
6323 r5
.in
.system_name
= "";
6324 r5
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
6326 r5
.out
.level_out
= &level_out
;
6327 r5
.in
.info_in
= &info
;
6328 r5
.out
.info_out
= &info
;
6329 r5
.out
.connect_handle
= &h
;
6331 status
= dcerpc_samr_Connect5(p
, tctx
, &r5
);
6332 if (!NT_STATUS_IS_OK(status
)) {
6333 printf("Connect5 failed - %s\n", nt_errstr(status
));
6337 test_samr_handle_Close(p
, tctx
, handle
);
6347 bool torture_rpc_samr(struct torture_context
*torture
)
6350 struct dcerpc_pipe
*p
;
6352 struct policy_handle handle
;
6354 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6355 if (!NT_STATUS_IS_OK(status
)) {
6359 ret
&= test_Connect(p
, torture
, &handle
);
6361 if (!torture_setting_bool(torture
, "samba3", false)) {
6362 ret
&= test_QuerySecurity(p
, torture
, &handle
);
6365 ret
&= test_EnumDomains(p
, torture
, &handle
, TORTURE_SAMR_OTHER
, NULL
);
6367 ret
&= test_SetDsrmPassword(p
, torture
, &handle
);
6369 ret
&= test_Shutdown(p
, torture
, &handle
);
6371 ret
&= test_samr_handle_Close(p
, torture
, &handle
);
6377 bool torture_rpc_samr_users(struct torture_context
*torture
)
6380 struct dcerpc_pipe
*p
;
6382 struct policy_handle handle
;
6384 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6385 if (!NT_STATUS_IS_OK(status
)) {
6389 ret
&= test_Connect(p
, torture
, &handle
);
6391 if (!torture_setting_bool(torture
, "samba3", false)) {
6392 ret
&= test_QuerySecurity(p
, torture
, &handle
);
6395 ret
&= test_EnumDomains(p
, torture
, &handle
, TORTURE_SAMR_USER_ATTRIBUTES
, NULL
);
6397 ret
&= test_SetDsrmPassword(p
, torture
, &handle
);
6399 ret
&= test_Shutdown(p
, torture
, &handle
);
6401 ret
&= test_samr_handle_Close(p
, torture
, &handle
);
6407 bool torture_rpc_samr_passwords(struct torture_context
*torture
)
6410 struct dcerpc_pipe
*p
;
6412 struct policy_handle handle
;
6414 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6415 if (!NT_STATUS_IS_OK(status
)) {
6419 ret
&= test_Connect(p
, torture
, &handle
);
6421 ret
&= test_EnumDomains(p
, torture
, &handle
, TORTURE_SAMR_PASSWORDS
, NULL
);
6423 ret
&= test_samr_handle_Close(p
, torture
, &handle
);
6428 static bool torture_rpc_samr_pwdlastset(struct torture_context
*torture
,
6429 struct dcerpc_pipe
*p2
,
6430 struct cli_credentials
*machine_credentials
)
6433 struct dcerpc_pipe
*p
;
6435 struct policy_handle handle
;
6437 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6438 if (!NT_STATUS_IS_OK(status
)) {
6442 ret
&= test_Connect(p
, torture
, &handle
);
6444 ret
&= test_EnumDomains(p
, torture
, &handle
,
6445 TORTURE_SAMR_PASSWORDS_PWDLASTSET
,
6446 machine_credentials
);
6448 ret
&= test_samr_handle_Close(p
, torture
, &handle
);
6453 struct torture_suite
*torture_rpc_samr_passwords_pwdlastset(struct torture_context
*tctx
)
6455 struct torture_suite
*suite
= torture_suite_create(tctx
, "SAMR-PASSWORDS-PWDLASTSET");
6456 struct torture_rpc_tcase
*tcase
;
6458 tcase
= torture_suite_add_machine_rpc_iface_tcase(suite
, "samr",
6460 TEST_ACCOUNT_NAME_PWD
);
6462 torture_rpc_tcase_add_test_creds(tcase
, "pwdLastSet",
6463 torture_rpc_samr_pwdlastset
);
6468 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context
*torture
,
6469 struct dcerpc_pipe
*p2
,
6470 struct cli_credentials
*machine_credentials
)
6473 struct dcerpc_pipe
*p
;
6475 struct policy_handle handle
;
6477 status
= torture_rpc_connection(torture
, &p
, &ndr_table_samr
);
6478 if (!NT_STATUS_IS_OK(status
)) {
6482 ret
&= test_Connect(p
, torture
, &handle
);
6484 ret
&= test_EnumDomains(p
, torture
, &handle
,
6485 TORTURE_SAMR_USER_PRIVILEGES
,
6486 machine_credentials
);
6488 ret
&= test_samr_handle_Close(p
, torture
, &handle
);
6493 struct torture_suite
*torture_rpc_samr_user_privileges(TALLOC_CTX
*mem_ctx
)
6495 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "SAMR-USERS-PRIVILEGES");
6496 struct torture_rpc_tcase
*tcase
;
6498 tcase
= torture_suite_add_machine_rpc_iface_tcase(suite
, "samr",
6500 TEST_ACCOUNT_NAME_PWD
);
6502 torture_rpc_tcase_add_test_creds(tcase
, "delete_privileged_user",
6503 torture_rpc_samr_users_privileges_delete_user
);