Rework our SAMR test and SAMR server.
[Samba.git] / source / torture / rpc / samr.c
blob55c75ba270eb415cc0227e8986516ea18e32fbcc
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31 #include "param/param.h"
33 #define TEST_ACCOUNT_NAME "samrtorturetest"
34 #define TEST_ALIASNAME "samrtorturetestalias"
35 #define TEST_GROUPNAME "samrtorturetestgroup"
36 #define TEST_MACHINENAME "samrtestmach$"
37 #define TEST_DOMAINNAME "samrtestdom$"
39 enum torture_samr_choice {
40 TORTURE_SAMR_PASSWORDS,
41 TORTURE_SAMR_USER_ATTRIBUTES,
42 TORTURE_SAMR_OTHER
45 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
46 struct policy_handle *handle);
48 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
49 struct policy_handle *handle);
51 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
52 struct policy_handle *handle);
54 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
55 const char *acct_name,
56 struct policy_handle *domain_handle, char **password);
58 static void init_lsa_String(struct lsa_String *string, const char *s)
60 string->string = s;
63 bool test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
64 struct policy_handle *handle)
66 NTSTATUS status;
67 struct samr_Close r;
69 r.in.handle = handle;
70 r.out.handle = handle;
72 status = dcerpc_samr_Close(p, mem_ctx, &r);
73 if (!NT_STATUS_IS_OK(status)) {
74 printf("Close handle failed - %s\n", nt_errstr(status));
75 return false;
78 return true;
81 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
82 struct policy_handle *handle)
84 NTSTATUS status;
85 struct samr_Shutdown r;
87 if (!torture_setting_bool(tctx, "dangerous", false)) {
88 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
89 return true;
92 r.in.connect_handle = handle;
94 printf("testing samr_Shutdown\n");
96 status = dcerpc_samr_Shutdown(p, tctx, &r);
97 if (!NT_STATUS_IS_OK(status)) {
98 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
99 return false;
102 return true;
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle)
108 NTSTATUS status;
109 struct samr_SetDsrmPassword r;
110 struct lsa_String string;
111 struct samr_Password hash;
113 if (!torture_setting_bool(tctx, "dangerous", false)) {
114 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
115 return true;
118 E_md4hash("TeSTDSRM123", hash.hash);
120 init_lsa_String(&string, "Administrator");
122 r.in.name = &string;
123 r.in.unknown = 0;
124 r.in.hash = &hash;
126 printf("testing samr_SetDsrmPassword\n");
128 status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
129 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
130 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
131 return false;
134 return true;
138 static bool test_QuerySecurity(struct dcerpc_pipe *p,
139 struct torture_context *tctx,
140 struct policy_handle *handle)
142 NTSTATUS status;
143 struct samr_QuerySecurity r;
144 struct samr_SetSecurity s;
146 r.in.handle = handle;
147 r.in.sec_info = 7;
149 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
150 if (!NT_STATUS_IS_OK(status)) {
151 printf("QuerySecurity failed - %s\n", nt_errstr(status));
152 return false;
155 if (r.out.sdbuf == NULL) {
156 return false;
159 s.in.handle = handle;
160 s.in.sec_info = 7;
161 s.in.sdbuf = r.out.sdbuf;
163 if (torture_setting_bool(tctx, "samba4", false)) {
164 printf("skipping SetSecurity test against Samba4\n");
165 return true;
168 status = dcerpc_samr_SetSecurity(p, tctx, &s);
169 if (!NT_STATUS_IS_OK(status)) {
170 printf("SetSecurity failed - %s\n", nt_errstr(status));
171 return false;
174 status = dcerpc_samr_QuerySecurity(p, tctx, &r);
175 if (!NT_STATUS_IS_OK(status)) {
176 printf("QuerySecurity failed - %s\n", nt_errstr(status));
177 return false;
180 return true;
184 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
185 struct policy_handle *handle, uint32_t base_acct_flags,
186 const char *base_account_name)
188 NTSTATUS status;
189 struct samr_SetUserInfo s;
190 struct samr_SetUserInfo2 s2;
191 struct samr_QueryUserInfo q;
192 struct samr_QueryUserInfo q0;
193 union samr_UserInfo u;
194 bool ret = true;
195 const char *test_account_name;
197 uint32_t user_extra_flags = 0;
198 if (base_acct_flags == ACB_NORMAL) {
199 /* When created, accounts are expired by default */
200 user_extra_flags = ACB_PW_EXPIRED;
203 s.in.user_handle = handle;
204 s.in.info = &u;
206 s2.in.user_handle = handle;
207 s2.in.info = &u;
209 q.in.user_handle = handle;
210 q.out.info = &u;
211 q0 = q;
213 #define TESTCALL(call, r) \
214 status = dcerpc_samr_ ##call(p, tctx, &r); \
215 if (!NT_STATUS_IS_OK(status)) { \
216 printf(#call " level %u failed - %s (%s)\n", \
217 r.in.level, nt_errstr(status), __location__); \
218 ret = false; \
219 break; \
222 #define STRING_EQUAL(s1, s2, field) \
223 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
224 printf("Failed to set %s to '%s' (%s)\n", \
225 #field, s2, __location__); \
226 ret = false; \
227 break; \
230 #define INT_EQUAL(i1, i2, field) \
231 if (i1 != i2) { \
232 printf("Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
233 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
234 ret = false; \
235 break; \
238 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
239 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
240 q.in.level = lvl1; \
241 TESTCALL(QueryUserInfo, q) \
242 s.in.level = lvl1; \
243 s2.in.level = lvl1; \
244 u = *q.out.info; \
245 if (lvl1 == 21) { \
246 ZERO_STRUCT(u.info21); \
247 u.info21.fields_present = fpval; \
249 init_lsa_String(&u.info ## lvl1.field1, value); \
250 TESTCALL(SetUserInfo, s) \
251 TESTCALL(SetUserInfo2, s2) \
252 init_lsa_String(&u.info ## lvl1.field1, ""); \
253 TESTCALL(QueryUserInfo, q); \
254 u = *q.out.info; \
255 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
256 q.in.level = lvl2; \
257 TESTCALL(QueryUserInfo, q) \
258 u = *q.out.info; \
259 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260 } while (0)
262 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
263 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
264 q.in.level = lvl1; \
265 TESTCALL(QueryUserInfo, q) \
266 s.in.level = lvl1; \
267 s2.in.level = lvl1; \
268 u = *q.out.info; \
269 if (lvl1 == 21) { \
270 uint8_t *bits = u.info21.logon_hours.bits; \
271 ZERO_STRUCT(u.info21); \
272 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
273 u.info21.logon_hours.units_per_week = 168; \
274 u.info21.logon_hours.bits = bits; \
276 u.info21.fields_present = fpval; \
278 u.info ## lvl1.field1 = value; \
279 TESTCALL(SetUserInfo, s) \
280 TESTCALL(SetUserInfo2, s2) \
281 u.info ## lvl1.field1 = 0; \
282 TESTCALL(QueryUserInfo, q); \
283 u = *q.out.info; \
284 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
285 q.in.level = lvl2; \
286 TESTCALL(QueryUserInfo, q) \
287 u = *q.out.info; \
288 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
289 } while (0)
291 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
292 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
293 } while (0)
295 q0.in.level = 12;
296 do { TESTCALL(QueryUserInfo, q0) } while (0);
298 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
299 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
300 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
301 SAMR_FIELD_COMMENT);
303 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
304 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
305 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
306 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
307 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
308 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
309 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
310 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
311 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
312 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
313 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
314 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
315 test_account_name = base_account_name;
316 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
317 SAMR_FIELD_ACCOUNT_NAME);
319 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
320 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
321 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
322 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
323 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
324 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
325 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
326 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
327 SAMR_FIELD_FULL_NAME);
329 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
330 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
331 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
332 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
333 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
334 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
335 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
336 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
337 SAMR_FIELD_FULL_NAME);
339 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
340 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
341 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
342 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
343 SAMR_FIELD_LOGON_SCRIPT);
345 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
346 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
347 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
348 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
349 SAMR_FIELD_PROFILE_PATH);
351 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
352 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
353 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
354 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
355 SAMR_FIELD_HOME_DIRECTORY);
356 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
357 SAMR_FIELD_HOME_DIRECTORY);
359 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
360 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
361 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
362 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
363 SAMR_FIELD_HOME_DRIVE);
364 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
365 SAMR_FIELD_HOME_DRIVE);
367 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
368 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
369 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
370 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
371 SAMR_FIELD_DESCRIPTION);
373 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
374 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
375 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
376 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
377 SAMR_FIELD_WORKSTATIONS);
378 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
379 SAMR_FIELD_WORKSTATIONS);
380 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
381 SAMR_FIELD_WORKSTATIONS);
382 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
383 SAMR_FIELD_WORKSTATIONS);
385 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
386 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
387 SAMR_FIELD_PARAMETERS);
388 TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
389 SAMR_FIELD_PARAMETERS);
391 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
392 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
393 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
394 SAMR_FIELD_COUNTRY_CODE);
395 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
396 SAMR_FIELD_COUNTRY_CODE);
398 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
399 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
400 SAMR_FIELD_CODE_PAGE);
401 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
402 SAMR_FIELD_CODE_PAGE);
404 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
405 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
406 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
407 SAMR_FIELD_ACCT_EXPIRY);
408 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
409 SAMR_FIELD_ACCT_EXPIRY);
410 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
411 SAMR_FIELD_ACCT_EXPIRY);
413 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
414 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
415 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
416 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
417 SAMR_FIELD_LOGON_HOURS);
419 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
420 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
421 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
423 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
424 (base_acct_flags | ACB_DISABLED),
425 (base_acct_flags | ACB_DISABLED | user_extra_flags),
428 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
429 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
430 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
431 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
433 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
434 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
435 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
439 /* The 'autolock' flag doesn't stick - check this */
440 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
441 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
442 (base_acct_flags | ACB_DISABLED | user_extra_flags),
444 #if 0
445 /* Removing the 'disabled' flag doesn't stick - check this */
446 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
447 (base_acct_flags),
448 (base_acct_flags | ACB_DISABLED | user_extra_flags),
450 #endif
451 /* The 'store plaintext' flag does stick */
452 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
453 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
454 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
456 /* The 'use DES' flag does stick */
457 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
458 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
459 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
461 /* The 'don't require kerberos pre-authentication flag does stick */
462 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
463 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
464 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
466 /* The 'no kerberos PAC required' flag sticks */
467 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
468 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
469 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
472 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
473 (base_acct_flags | ACB_DISABLED),
474 (base_acct_flags | ACB_DISABLED | user_extra_flags),
475 SAMR_FIELD_ACCT_FLAGS);
477 #if 0
478 /* these fail with win2003 - it appears you can't set the primary gid?
479 the set succeeds, but the gid isn't changed. Very weird! */
480 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
481 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
482 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
483 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
484 #endif
486 return ret;
490 generate a random password for password change tests
492 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
494 size_t len = MAX(8, min_len) + (random() % 6);
495 char *s = generate_random_str(mem_ctx, len);
496 printf("Generated password '%s'\n", s);
497 return s;
501 generate a random password for password change tests (fixed length)
503 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
505 char *s = generate_random_str(mem_ctx, len);
506 printf("Generated password '%s'\n", s);
507 return s;
510 static bool test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
511 struct policy_handle *handle, char **password)
513 NTSTATUS status;
514 struct samr_SetUserInfo s;
515 union samr_UserInfo u;
516 bool ret = true;
517 DATA_BLOB session_key;
518 char *newpass;
519 struct samr_GetUserPwInfo pwp;
520 int policy_min_pw_len = 0;
521 pwp.in.user_handle = handle;
523 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
524 if (NT_STATUS_IS_OK(status)) {
525 policy_min_pw_len = pwp.out.info.min_password_length;
527 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
529 s.in.user_handle = handle;
530 s.in.info = &u;
531 s.in.level = 24;
533 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
534 /* w2k3 ignores this length */
535 u.info24.pw_len = strlen_m(newpass) * 2;
537 status = dcerpc_fetch_session_key(p, &session_key);
538 if (!NT_STATUS_IS_OK(status)) {
539 printf("SetUserInfo level %u - no session key - %s\n",
540 s.in.level, nt_errstr(status));
541 return false;
544 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
546 printf("Testing SetUserInfo level 24 (set password)\n");
548 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
549 if (!NT_STATUS_IS_OK(status)) {
550 printf("SetUserInfo level %u failed - %s\n",
551 s.in.level, nt_errstr(status));
552 ret = false;
553 } else {
554 *password = newpass;
557 return ret;
561 static bool test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
562 struct policy_handle *handle, uint32_t fields_present,
563 char **password)
565 NTSTATUS status;
566 struct samr_SetUserInfo s;
567 union samr_UserInfo u;
568 bool ret = true;
569 DATA_BLOB session_key;
570 char *newpass;
571 struct samr_GetUserPwInfo pwp;
572 int policy_min_pw_len = 0;
573 pwp.in.user_handle = handle;
575 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
576 if (NT_STATUS_IS_OK(status)) {
577 policy_min_pw_len = pwp.out.info.min_password_length;
579 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
581 s.in.user_handle = handle;
582 s.in.info = &u;
583 s.in.level = 23;
585 ZERO_STRUCT(u);
587 u.info23.info.fields_present = fields_present;
589 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
591 status = dcerpc_fetch_session_key(p, &session_key);
592 if (!NT_STATUS_IS_OK(status)) {
593 printf("SetUserInfo level %u - no session key - %s\n",
594 s.in.level, nt_errstr(status));
595 return false;
598 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
600 printf("Testing SetUserInfo level 23 (set password)\n");
602 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
603 if (!NT_STATUS_IS_OK(status)) {
604 printf("SetUserInfo level %u failed - %s\n",
605 s.in.level, nt_errstr(status));
606 ret = false;
607 } else {
608 *password = newpass;
611 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
613 status = dcerpc_fetch_session_key(p, &session_key);
614 if (!NT_STATUS_IS_OK(status)) {
615 printf("SetUserInfo level %u - no session key - %s\n",
616 s.in.level, nt_errstr(status));
617 return false;
620 /* This should break the key nicely */
621 session_key.length--;
622 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
624 printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
626 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
627 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
628 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
629 s.in.level, nt_errstr(status));
630 ret = false;
633 return ret;
637 static bool test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
638 struct policy_handle *handle, bool makeshort,
639 char **password)
641 NTSTATUS status;
642 struct samr_SetUserInfo s;
643 union samr_UserInfo u;
644 bool ret = true;
645 DATA_BLOB session_key;
646 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
647 uint8_t confounder[16];
648 char *newpass;
649 struct MD5Context ctx;
650 struct samr_GetUserPwInfo pwp;
651 int policy_min_pw_len = 0;
652 pwp.in.user_handle = handle;
654 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
655 if (NT_STATUS_IS_OK(status)) {
656 policy_min_pw_len = pwp.out.info.min_password_length;
658 if (makeshort && policy_min_pw_len) {
659 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
660 } else {
661 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
664 s.in.user_handle = handle;
665 s.in.info = &u;
666 s.in.level = 26;
668 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
669 u.info26.pw_len = strlen(newpass);
671 status = dcerpc_fetch_session_key(p, &session_key);
672 if (!NT_STATUS_IS_OK(status)) {
673 printf("SetUserInfo level %u - no session key - %s\n",
674 s.in.level, nt_errstr(status));
675 return false;
678 generate_random_buffer((uint8_t *)confounder, 16);
680 MD5Init(&ctx);
681 MD5Update(&ctx, confounder, 16);
682 MD5Update(&ctx, session_key.data, session_key.length);
683 MD5Final(confounded_session_key.data, &ctx);
685 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
686 memcpy(&u.info26.password.data[516], confounder, 16);
688 printf("Testing SetUserInfo level 26 (set password ex)\n");
690 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
691 if (!NT_STATUS_IS_OK(status)) {
692 printf("SetUserInfo level %u failed - %s\n",
693 s.in.level, nt_errstr(status));
694 ret = false;
695 } else {
696 *password = newpass;
699 /* This should break the key nicely */
700 confounded_session_key.data[0]++;
702 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
703 memcpy(&u.info26.password.data[516], confounder, 16);
705 printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
707 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
708 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
709 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
710 s.in.level, nt_errstr(status));
711 ret = false;
712 } else {
713 *password = newpass;
716 return ret;
719 static bool test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
720 struct policy_handle *handle, uint32_t fields_present,
721 char **password)
723 NTSTATUS status;
724 struct samr_SetUserInfo s;
725 union samr_UserInfo u;
726 bool ret = true;
727 DATA_BLOB session_key;
728 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
729 struct MD5Context ctx;
730 uint8_t confounder[16];
731 char *newpass;
732 struct samr_GetUserPwInfo pwp;
733 int policy_min_pw_len = 0;
734 pwp.in.user_handle = handle;
736 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
737 if (NT_STATUS_IS_OK(status)) {
738 policy_min_pw_len = pwp.out.info.min_password_length;
740 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
742 s.in.user_handle = handle;
743 s.in.info = &u;
744 s.in.level = 25;
746 ZERO_STRUCT(u);
748 u.info25.info.fields_present = fields_present;
750 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
752 status = dcerpc_fetch_session_key(p, &session_key);
753 if (!NT_STATUS_IS_OK(status)) {
754 printf("SetUserInfo level %u - no session key - %s\n",
755 s.in.level, nt_errstr(status));
756 return false;
759 generate_random_buffer((uint8_t *)confounder, 16);
761 MD5Init(&ctx);
762 MD5Update(&ctx, confounder, 16);
763 MD5Update(&ctx, session_key.data, session_key.length);
764 MD5Final(confounded_session_key.data, &ctx);
766 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
767 memcpy(&u.info25.password.data[516], confounder, 16);
769 printf("Testing SetUserInfo level 25 (set password ex)\n");
771 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
772 if (!NT_STATUS_IS_OK(status)) {
773 printf("SetUserInfo level %u failed - %s\n",
774 s.in.level, nt_errstr(status));
775 ret = false;
776 } else {
777 *password = newpass;
780 /* This should break the key nicely */
781 confounded_session_key.data[0]++;
783 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
784 memcpy(&u.info25.password.data[516], confounder, 16);
786 printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
788 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
789 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
790 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
791 s.in.level, nt_errstr(status));
792 ret = false;
795 return ret;
798 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
799 struct policy_handle *handle)
801 NTSTATUS status;
802 struct samr_SetAliasInfo r;
803 struct samr_QueryAliasInfo q;
804 uint16_t levels[] = {2, 3};
805 int i;
806 bool ret = true;
808 /* Ignoring switch level 1, as that includes the number of members for the alias
809 * and setting this to a wrong value might have negative consequences
812 for (i=0;i<ARRAY_SIZE(levels);i++) {
813 printf("Testing SetAliasInfo level %u\n", levels[i]);
815 r.in.alias_handle = handle;
816 r.in.level = levels[i];
817 r.in.info = talloc(tctx, union samr_AliasInfo);
818 switch (r.in.level) {
819 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
820 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
821 "Test Description, should test I18N as well"); break;
822 case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
825 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
826 if (!NT_STATUS_IS_OK(status)) {
827 printf("SetAliasInfo level %u failed - %s\n",
828 levels[i], nt_errstr(status));
829 ret = false;
832 q.in.alias_handle = handle;
833 q.in.level = levels[i];
835 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
836 if (!NT_STATUS_IS_OK(status)) {
837 printf("QueryAliasInfo level %u failed - %s\n",
838 levels[i], nt_errstr(status));
839 ret = false;
843 return ret;
846 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
847 struct policy_handle *user_handle)
849 struct samr_GetGroupsForUser r;
850 NTSTATUS status;
851 bool ret = true;
853 printf("testing GetGroupsForUser\n");
855 r.in.user_handle = user_handle;
857 status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
858 if (!NT_STATUS_IS_OK(status)) {
859 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
860 ret = false;
863 return ret;
867 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
868 struct lsa_String *domain_name)
870 NTSTATUS status;
871 struct samr_GetDomPwInfo r;
872 bool ret = true;
874 r.in.domain_name = domain_name;
875 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
877 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
878 if (!NT_STATUS_IS_OK(status)) {
879 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
880 ret = false;
883 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
884 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
886 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
887 if (!NT_STATUS_IS_OK(status)) {
888 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
889 ret = false;
892 r.in.domain_name->string = "\\\\__NONAME__";
893 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
895 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
896 if (!NT_STATUS_IS_OK(status)) {
897 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
898 ret = false;
901 r.in.domain_name->string = "\\\\Builtin";
902 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
904 status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
905 if (!NT_STATUS_IS_OK(status)) {
906 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
907 ret = false;
911 return ret;
914 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
915 struct policy_handle *handle)
917 NTSTATUS status;
918 struct samr_GetUserPwInfo r;
919 bool ret = true;
921 printf("Testing GetUserPwInfo\n");
923 r.in.user_handle = handle;
925 status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
926 if (!NT_STATUS_IS_OK(status)) {
927 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
928 ret = false;
931 return ret;
934 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
935 struct policy_handle *domain_handle, const char *name,
936 uint32_t *rid)
938 NTSTATUS status;
939 struct samr_LookupNames n;
940 struct lsa_String sname[2];
942 init_lsa_String(&sname[0], name);
944 n.in.domain_handle = domain_handle;
945 n.in.num_names = 1;
946 n.in.names = sname;
947 status = dcerpc_samr_LookupNames(p, tctx, &n);
948 if (NT_STATUS_IS_OK(status)) {
949 *rid = n.out.rids.ids[0];
950 } else {
951 return status;
954 init_lsa_String(&sname[1], "xxNONAMExx");
955 n.in.num_names = 2;
956 status = dcerpc_samr_LookupNames(p, tctx, &n);
957 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
958 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
959 if (NT_STATUS_IS_OK(status)) {
960 return NT_STATUS_UNSUCCESSFUL;
962 return status;
965 n.in.num_names = 0;
966 status = dcerpc_samr_LookupNames(p, tctx, &n);
967 if (!NT_STATUS_IS_OK(status)) {
968 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
969 return status;
972 init_lsa_String(&sname[0], "xxNONAMExx");
973 n.in.num_names = 1;
974 status = dcerpc_samr_LookupNames(p, tctx, &n);
975 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
976 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
977 if (NT_STATUS_IS_OK(status)) {
978 return NT_STATUS_UNSUCCESSFUL;
980 return status;
983 init_lsa_String(&sname[0], "xxNONAMExx");
984 init_lsa_String(&sname[1], "xxNONAME2xx");
985 n.in.num_names = 2;
986 status = dcerpc_samr_LookupNames(p, tctx, &n);
987 if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
988 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
989 if (NT_STATUS_IS_OK(status)) {
990 return NT_STATUS_UNSUCCESSFUL;
992 return status;
995 return NT_STATUS_OK;
998 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
999 struct policy_handle *domain_handle,
1000 const char *name, struct policy_handle *user_handle)
1002 NTSTATUS status;
1003 struct samr_OpenUser r;
1004 uint32_t rid;
1006 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1007 if (!NT_STATUS_IS_OK(status)) {
1008 return status;
1011 r.in.domain_handle = domain_handle;
1012 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1013 r.in.rid = rid;
1014 r.out.user_handle = user_handle;
1015 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1016 if (!NT_STATUS_IS_OK(status)) {
1017 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1020 return status;
1023 #if 0
1024 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1025 struct policy_handle *handle)
1027 NTSTATUS status;
1028 struct samr_ChangePasswordUser r;
1029 bool ret = true;
1030 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1031 struct policy_handle user_handle;
1032 char *oldpass = "test";
1033 char *newpass = "test2";
1034 uint8_t old_nt_hash[16], new_nt_hash[16];
1035 uint8_t old_lm_hash[16], new_lm_hash[16];
1037 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1038 if (!NT_STATUS_IS_OK(status)) {
1039 return false;
1042 printf("Testing ChangePasswordUser for user 'testuser'\n");
1044 printf("old password: %s\n", oldpass);
1045 printf("new password: %s\n", newpass);
1047 E_md4hash(oldpass, old_nt_hash);
1048 E_md4hash(newpass, new_nt_hash);
1049 E_deshash(oldpass, old_lm_hash);
1050 E_deshash(newpass, new_lm_hash);
1052 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1053 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1054 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1055 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1056 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1057 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1059 r.in.handle = &user_handle;
1060 r.in.lm_present = 1;
1061 r.in.old_lm_crypted = &hash1;
1062 r.in.new_lm_crypted = &hash2;
1063 r.in.nt_present = 1;
1064 r.in.old_nt_crypted = &hash3;
1065 r.in.new_nt_crypted = &hash4;
1066 r.in.cross1_present = 1;
1067 r.in.nt_cross = &hash5;
1068 r.in.cross2_present = 1;
1069 r.in.lm_cross = &hash6;
1071 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1072 if (!NT_STATUS_IS_OK(status)) {
1073 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1074 ret = false;
1077 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1078 ret = false;
1081 return ret;
1083 #endif
1085 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1086 const char *acct_name,
1087 struct policy_handle *handle, char **password)
1089 NTSTATUS status;
1090 struct samr_ChangePasswordUser r;
1091 bool ret = true;
1092 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1093 struct policy_handle user_handle;
1094 char *oldpass;
1095 uint8_t old_nt_hash[16], new_nt_hash[16];
1096 uint8_t old_lm_hash[16], new_lm_hash[16];
1097 bool changed = true;
1099 char *newpass;
1100 struct samr_GetUserPwInfo pwp;
1101 int policy_min_pw_len = 0;
1103 status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1104 if (!NT_STATUS_IS_OK(status)) {
1105 return false;
1107 pwp.in.user_handle = &user_handle;
1109 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1110 if (NT_STATUS_IS_OK(status)) {
1111 policy_min_pw_len = pwp.out.info.min_password_length;
1113 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1115 printf("Testing ChangePasswordUser\n");
1117 if (!*password) {
1118 printf("Failing ChangePasswordUser as old password was NULL. Previous test failed?\n");
1119 return false;
1122 oldpass = *password;
1124 E_md4hash(oldpass, old_nt_hash);
1125 E_md4hash(newpass, new_nt_hash);
1126 E_deshash(oldpass, old_lm_hash);
1127 E_deshash(newpass, new_lm_hash);
1129 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1130 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1131 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1132 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1133 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1134 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1136 r.in.user_handle = &user_handle;
1137 r.in.lm_present = 1;
1138 /* Break the LM hash */
1139 hash1.hash[0]++;
1140 r.in.old_lm_crypted = &hash1;
1141 r.in.new_lm_crypted = &hash2;
1142 r.in.nt_present = 1;
1143 r.in.old_nt_crypted = &hash3;
1144 r.in.new_nt_crypted = &hash4;
1145 r.in.cross1_present = 1;
1146 r.in.nt_cross = &hash5;
1147 r.in.cross2_present = 1;
1148 r.in.lm_cross = &hash6;
1150 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1151 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1152 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1153 ret = false;
1156 /* Unbreak the LM hash */
1157 hash1.hash[0]--;
1159 r.in.user_handle = &user_handle;
1160 r.in.lm_present = 1;
1161 r.in.old_lm_crypted = &hash1;
1162 r.in.new_lm_crypted = &hash2;
1163 /* Break the NT hash */
1164 hash3.hash[0]--;
1165 r.in.nt_present = 1;
1166 r.in.old_nt_crypted = &hash3;
1167 r.in.new_nt_crypted = &hash4;
1168 r.in.cross1_present = 1;
1169 r.in.nt_cross = &hash5;
1170 r.in.cross2_present = 1;
1171 r.in.lm_cross = &hash6;
1173 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1174 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1175 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1176 ret = false;
1179 /* Unbreak the NT hash */
1180 hash3.hash[0]--;
1182 r.in.user_handle = &user_handle;
1183 r.in.lm_present = 1;
1184 r.in.old_lm_crypted = &hash1;
1185 r.in.new_lm_crypted = &hash2;
1186 r.in.nt_present = 1;
1187 r.in.old_nt_crypted = &hash3;
1188 r.in.new_nt_crypted = &hash4;
1189 r.in.cross1_present = 1;
1190 r.in.nt_cross = &hash5;
1191 r.in.cross2_present = 1;
1192 /* Break the LM cross */
1193 hash6.hash[0]++;
1194 r.in.lm_cross = &hash6;
1196 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1197 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1198 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1199 ret = false;
1202 /* Unbreak the LM cross */
1203 hash6.hash[0]--;
1205 r.in.user_handle = &user_handle;
1206 r.in.lm_present = 1;
1207 r.in.old_lm_crypted = &hash1;
1208 r.in.new_lm_crypted = &hash2;
1209 r.in.nt_present = 1;
1210 r.in.old_nt_crypted = &hash3;
1211 r.in.new_nt_crypted = &hash4;
1212 r.in.cross1_present = 1;
1213 /* Break the NT cross */
1214 hash5.hash[0]++;
1215 r.in.nt_cross = &hash5;
1216 r.in.cross2_present = 1;
1217 r.in.lm_cross = &hash6;
1219 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1220 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1221 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1222 ret = false;
1225 /* Unbreak the NT cross */
1226 hash5.hash[0]--;
1229 /* Reset the hashes to not broken values */
1230 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1231 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1232 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1233 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1234 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1235 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1237 r.in.user_handle = &user_handle;
1238 r.in.lm_present = 1;
1239 r.in.old_lm_crypted = &hash1;
1240 r.in.new_lm_crypted = &hash2;
1241 r.in.nt_present = 1;
1242 r.in.old_nt_crypted = &hash3;
1243 r.in.new_nt_crypted = &hash4;
1244 r.in.cross1_present = 1;
1245 r.in.nt_cross = &hash5;
1246 r.in.cross2_present = 0;
1247 r.in.lm_cross = NULL;
1249 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1250 if (NT_STATUS_IS_OK(status)) {
1251 changed = true;
1252 *password = newpass;
1253 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1254 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1255 ret = false;
1258 oldpass = newpass;
1259 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1261 E_md4hash(oldpass, old_nt_hash);
1262 E_md4hash(newpass, new_nt_hash);
1263 E_deshash(oldpass, old_lm_hash);
1264 E_deshash(newpass, new_lm_hash);
1267 /* Reset the hashes to not broken values */
1268 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1269 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1270 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1271 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1272 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1273 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1275 r.in.user_handle = &user_handle;
1276 r.in.lm_present = 1;
1277 r.in.old_lm_crypted = &hash1;
1278 r.in.new_lm_crypted = &hash2;
1279 r.in.nt_present = 1;
1280 r.in.old_nt_crypted = &hash3;
1281 r.in.new_nt_crypted = &hash4;
1282 r.in.cross1_present = 0;
1283 r.in.nt_cross = NULL;
1284 r.in.cross2_present = 1;
1285 r.in.lm_cross = &hash6;
1287 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1288 if (NT_STATUS_IS_OK(status)) {
1289 changed = true;
1290 *password = newpass;
1291 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1292 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1293 ret = false;
1296 oldpass = newpass;
1297 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1299 E_md4hash(oldpass, old_nt_hash);
1300 E_md4hash(newpass, new_nt_hash);
1301 E_deshash(oldpass, old_lm_hash);
1302 E_deshash(newpass, new_lm_hash);
1305 /* Reset the hashes to not broken values */
1306 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1307 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1308 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1309 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1310 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1311 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1313 r.in.user_handle = &user_handle;
1314 r.in.lm_present = 1;
1315 r.in.old_lm_crypted = &hash1;
1316 r.in.new_lm_crypted = &hash2;
1317 r.in.nt_present = 1;
1318 r.in.old_nt_crypted = &hash3;
1319 r.in.new_nt_crypted = &hash4;
1320 r.in.cross1_present = 1;
1321 r.in.nt_cross = &hash5;
1322 r.in.cross2_present = 1;
1323 r.in.lm_cross = &hash6;
1325 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1326 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1327 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1328 } else if (!NT_STATUS_IS_OK(status)) {
1329 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1330 ret = false;
1331 } else {
1332 changed = true;
1333 *password = newpass;
1336 r.in.user_handle = &user_handle;
1337 r.in.lm_present = 1;
1338 r.in.old_lm_crypted = &hash1;
1339 r.in.new_lm_crypted = &hash2;
1340 r.in.nt_present = 1;
1341 r.in.old_nt_crypted = &hash3;
1342 r.in.new_nt_crypted = &hash4;
1343 r.in.cross1_present = 1;
1344 r.in.nt_cross = &hash5;
1345 r.in.cross2_present = 1;
1346 r.in.lm_cross = &hash6;
1348 if (changed) {
1349 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1350 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1351 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1352 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1353 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1354 ret = false;
1359 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1360 ret = false;
1363 return ret;
1367 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1368 const char *acct_name,
1369 struct policy_handle *handle, char **password)
1371 NTSTATUS status;
1372 struct samr_OemChangePasswordUser2 r;
1373 bool ret = true;
1374 struct samr_Password lm_verifier;
1375 struct samr_CryptPassword lm_pass;
1376 struct lsa_AsciiString server, account, account_bad;
1377 char *oldpass;
1378 char *newpass;
1379 uint8_t old_lm_hash[16], new_lm_hash[16];
1381 struct samr_GetDomPwInfo dom_pw_info;
1382 int policy_min_pw_len = 0;
1384 struct lsa_String domain_name;
1386 domain_name.string = "";
1387 dom_pw_info.in.domain_name = &domain_name;
1389 printf("Testing OemChangePasswordUser2\n");
1391 if (!*password) {
1392 printf("Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?\n");
1393 return false;
1396 oldpass = *password;
1398 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1399 if (NT_STATUS_IS_OK(status)) {
1400 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1403 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1405 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1406 account.string = acct_name;
1408 E_deshash(oldpass, old_lm_hash);
1409 E_deshash(newpass, new_lm_hash);
1411 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1412 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1413 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1415 r.in.server = &server;
1416 r.in.account = &account;
1417 r.in.password = &lm_pass;
1418 r.in.hash = &lm_verifier;
1420 /* Break the verification */
1421 lm_verifier.hash[0]++;
1423 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1425 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1426 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1427 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1428 nt_errstr(status));
1429 ret = false;
1432 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1433 /* Break the old password */
1434 old_lm_hash[0]++;
1435 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1436 /* unbreak it for the next operation */
1437 old_lm_hash[0]--;
1438 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1440 r.in.server = &server;
1441 r.in.account = &account;
1442 r.in.password = &lm_pass;
1443 r.in.hash = &lm_verifier;
1445 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1447 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1448 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1449 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1450 nt_errstr(status));
1451 ret = false;
1454 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1455 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1457 r.in.server = &server;
1458 r.in.account = &account;
1459 r.in.password = &lm_pass;
1460 r.in.hash = NULL;
1462 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1464 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1465 && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1466 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1467 nt_errstr(status));
1468 ret = false;
1471 /* This shouldn't be a valid name */
1472 account_bad.string = TEST_ACCOUNT_NAME "XX";
1473 r.in.account = &account_bad;
1475 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1477 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1478 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1479 nt_errstr(status));
1480 ret = false;
1483 /* This shouldn't be a valid name */
1484 account_bad.string = TEST_ACCOUNT_NAME "XX";
1485 r.in.account = &account_bad;
1486 r.in.password = &lm_pass;
1487 r.in.hash = &lm_verifier;
1489 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1491 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1492 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1493 nt_errstr(status));
1494 ret = false;
1497 /* This shouldn't be a valid name */
1498 account_bad.string = TEST_ACCOUNT_NAME "XX";
1499 r.in.account = &account_bad;
1500 r.in.password = NULL;
1501 r.in.hash = &lm_verifier;
1503 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1505 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1506 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1507 nt_errstr(status));
1508 ret = false;
1511 E_deshash(oldpass, old_lm_hash);
1512 E_deshash(newpass, new_lm_hash);
1514 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1515 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1516 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1518 r.in.server = &server;
1519 r.in.account = &account;
1520 r.in.password = &lm_pass;
1521 r.in.hash = &lm_verifier;
1523 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1524 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1525 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1526 } else if (!NT_STATUS_IS_OK(status)) {
1527 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1528 ret = false;
1529 } else {
1530 *password = newpass;
1533 return ret;
1537 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1538 const char *acct_name,
1539 char **password,
1540 char *newpass, bool allow_password_restriction)
1542 NTSTATUS status;
1543 struct samr_ChangePasswordUser2 r;
1544 bool ret = true;
1545 struct lsa_String server, account;
1546 struct samr_CryptPassword nt_pass, lm_pass;
1547 struct samr_Password nt_verifier, lm_verifier;
1548 char *oldpass;
1549 uint8_t old_nt_hash[16], new_nt_hash[16];
1550 uint8_t old_lm_hash[16], new_lm_hash[16];
1552 struct samr_GetDomPwInfo dom_pw_info;
1554 struct lsa_String domain_name;
1556 domain_name.string = "";
1557 dom_pw_info.in.domain_name = &domain_name;
1559 printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1561 if (!*password) {
1562 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1563 return false;
1565 oldpass = *password;
1567 if (!newpass) {
1568 int policy_min_pw_len = 0;
1569 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1570 if (NT_STATUS_IS_OK(status)) {
1571 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1574 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1577 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1578 init_lsa_String(&account, acct_name);
1580 E_md4hash(oldpass, old_nt_hash);
1581 E_md4hash(newpass, new_nt_hash);
1583 E_deshash(oldpass, old_lm_hash);
1584 E_deshash(newpass, new_lm_hash);
1586 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1587 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1588 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1590 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1591 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1592 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1594 r.in.server = &server;
1595 r.in.account = &account;
1596 r.in.nt_password = &nt_pass;
1597 r.in.nt_verifier = &nt_verifier;
1598 r.in.lm_change = 1;
1599 r.in.lm_password = &lm_pass;
1600 r.in.lm_verifier = &lm_verifier;
1602 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1603 if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1604 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1605 } else if (!NT_STATUS_IS_OK(status)) {
1606 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1607 ret = false;
1608 } else {
1609 *password = newpass;
1612 return ret;
1616 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1617 const char *account_string,
1618 int policy_min_pw_len,
1619 char **password,
1620 const char *newpass,
1621 NTTIME last_password_change,
1622 bool handle_reject_reason)
1624 NTSTATUS status;
1625 struct samr_ChangePasswordUser3 r;
1626 bool ret = true;
1627 struct lsa_String server, account, account_bad;
1628 struct samr_CryptPassword nt_pass, lm_pass;
1629 struct samr_Password nt_verifier, lm_verifier;
1630 char *oldpass;
1631 uint8_t old_nt_hash[16], new_nt_hash[16];
1632 uint8_t old_lm_hash[16], new_lm_hash[16];
1633 NTTIME t;
1635 printf("Testing ChangePasswordUser3\n");
1637 if (newpass == NULL) {
1638 do {
1639 if (policy_min_pw_len == 0) {
1640 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1641 } else {
1642 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1644 } while (check_password_quality(newpass) == false);
1645 } else {
1646 printf("Using password '%s'\n", newpass);
1649 if (!*password) {
1650 printf("Failing ChangePasswordUser3 as old password was NULL. Previous test failed?\n");
1651 return false;
1654 oldpass = *password;
1655 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1656 init_lsa_String(&account, account_string);
1658 E_md4hash(oldpass, old_nt_hash);
1659 E_md4hash(newpass, new_nt_hash);
1661 E_deshash(oldpass, old_lm_hash);
1662 E_deshash(newpass, new_lm_hash);
1664 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1665 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1666 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1668 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1669 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1670 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1672 /* Break the verification */
1673 nt_verifier.hash[0]++;
1675 r.in.server = &server;
1676 r.in.account = &account;
1677 r.in.nt_password = &nt_pass;
1678 r.in.nt_verifier = &nt_verifier;
1679 r.in.lm_change = 1;
1680 r.in.lm_password = &lm_pass;
1681 r.in.lm_verifier = &lm_verifier;
1682 r.in.password3 = NULL;
1684 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1685 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1686 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1687 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1688 nt_errstr(status));
1689 ret = false;
1692 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1693 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1694 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1696 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1697 /* Break the NT hash */
1698 old_nt_hash[0]++;
1699 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1700 /* Unbreak it again */
1701 old_nt_hash[0]--;
1702 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1704 r.in.server = &server;
1705 r.in.account = &account;
1706 r.in.nt_password = &nt_pass;
1707 r.in.nt_verifier = &nt_verifier;
1708 r.in.lm_change = 1;
1709 r.in.lm_password = &lm_pass;
1710 r.in.lm_verifier = &lm_verifier;
1711 r.in.password3 = NULL;
1713 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1714 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1715 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1716 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1717 nt_errstr(status));
1718 ret = false;
1721 /* This shouldn't be a valid name */
1722 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1724 r.in.account = &account_bad;
1725 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1726 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1727 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1728 nt_errstr(status));
1729 ret = false;
1732 E_md4hash(oldpass, old_nt_hash);
1733 E_md4hash(newpass, new_nt_hash);
1735 E_deshash(oldpass, old_lm_hash);
1736 E_deshash(newpass, new_lm_hash);
1738 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1739 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1740 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1742 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1743 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1744 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1746 r.in.server = &server;
1747 r.in.account = &account;
1748 r.in.nt_password = &nt_pass;
1749 r.in.nt_verifier = &nt_verifier;
1750 r.in.lm_change = 1;
1751 r.in.lm_password = &lm_pass;
1752 r.in.lm_verifier = &lm_verifier;
1753 r.in.password3 = NULL;
1755 unix_to_nt_time(&t, time(NULL));
1757 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1759 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1760 && r.out.dominfo
1761 && r.out.reject
1762 && handle_reject_reason
1763 && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1764 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1766 if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1767 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1768 SAMR_REJECT_OTHER, r.out.reject->reason);
1769 return false;
1773 /* We tested the order of precendence which is as follows:
1775 * pwd min_age
1776 * pwd length
1777 * pwd complexity
1778 * pwd history
1780 Guenther */
1782 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
1783 (last_password_change + r.out.dominfo->min_password_age > t)) {
1785 if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1786 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1787 SAMR_REJECT_OTHER, r.out.reject->reason);
1788 return false;
1791 } else if ((r.out.dominfo->min_password_length > 0) &&
1792 (strlen(newpass) < r.out.dominfo->min_password_length)) {
1794 if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1795 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
1796 SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1797 return false;
1800 } else if ((r.out.dominfo->password_history_length > 0) &&
1801 strequal(oldpass, newpass)) {
1803 if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1804 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
1805 SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1806 return false;
1808 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1810 if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1811 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
1812 SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1813 return false;
1818 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1819 /* retry with adjusted size */
1820 return test_ChangePasswordUser3(p, mem_ctx, account_string,
1821 r.out.dominfo->min_password_length,
1822 password, NULL, 0, false);
1826 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1827 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1828 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
1829 SAMR_REJECT_OTHER, r.out.reject->reason);
1830 return false;
1832 /* Perhaps the server has a 'min password age' set? */
1834 } else if (!NT_STATUS_IS_OK(status)) {
1835 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1836 ret = false;
1837 } else {
1838 *password = talloc_strdup(mem_ctx, newpass);
1841 return ret;
1845 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1846 struct policy_handle *alias_handle)
1848 struct samr_GetMembersInAlias r;
1849 struct lsa_SidArray sids;
1850 NTSTATUS status;
1851 bool ret = true;
1853 printf("Testing GetMembersInAlias\n");
1855 r.in.alias_handle = alias_handle;
1856 r.out.sids = &sids;
1858 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1859 if (!NT_STATUS_IS_OK(status)) {
1860 printf("GetMembersInAlias failed - %s\n",
1861 nt_errstr(status));
1862 ret = false;
1865 return ret;
1868 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1869 struct policy_handle *alias_handle,
1870 const struct dom_sid *domain_sid)
1872 struct samr_AddAliasMember r;
1873 struct samr_DeleteAliasMember d;
1874 NTSTATUS status;
1875 bool ret = true;
1876 struct dom_sid *sid;
1878 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1880 printf("testing AddAliasMember\n");
1881 r.in.alias_handle = alias_handle;
1882 r.in.sid = sid;
1884 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1885 if (!NT_STATUS_IS_OK(status)) {
1886 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1887 ret = false;
1890 d.in.alias_handle = alias_handle;
1891 d.in.sid = sid;
1893 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1894 if (!NT_STATUS_IS_OK(status)) {
1895 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1896 ret = false;
1899 return ret;
1902 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1903 struct policy_handle *alias_handle)
1905 struct samr_AddMultipleMembersToAlias a;
1906 struct samr_RemoveMultipleMembersFromAlias r;
1907 NTSTATUS status;
1908 bool ret = true;
1909 struct lsa_SidArray sids;
1911 printf("testing AddMultipleMembersToAlias\n");
1912 a.in.alias_handle = alias_handle;
1913 a.in.sids = &sids;
1915 sids.num_sids = 3;
1916 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1918 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1919 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1920 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1922 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1923 if (!NT_STATUS_IS_OK(status)) {
1924 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1925 ret = false;
1929 printf("testing RemoveMultipleMembersFromAlias\n");
1930 r.in.alias_handle = alias_handle;
1931 r.in.sids = &sids;
1933 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1934 if (!NT_STATUS_IS_OK(status)) {
1935 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1936 ret = false;
1939 /* strange! removing twice doesn't give any error */
1940 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1941 if (!NT_STATUS_IS_OK(status)) {
1942 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1943 ret = false;
1946 /* but removing an alias that isn't there does */
1947 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1949 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1950 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1951 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1952 ret = false;
1955 return ret;
1958 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1959 struct policy_handle *user_handle)
1961 struct samr_TestPrivateFunctionsUser r;
1962 NTSTATUS status;
1963 bool ret = true;
1965 printf("Testing TestPrivateFunctionsUser\n");
1967 r.in.user_handle = user_handle;
1969 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1970 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1971 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1972 ret = false;
1975 return ret;
1979 static bool test_user_ops(struct dcerpc_pipe *p,
1980 struct torture_context *tctx,
1981 struct policy_handle *user_handle,
1982 struct policy_handle *domain_handle,
1983 uint32_t base_acct_flags,
1984 const char *base_acct_name, enum torture_samr_choice which_ops)
1986 char *password = NULL;
1987 struct samr_QueryUserInfo q;
1988 NTSTATUS status;
1990 bool ret = true;
1991 int i;
1992 uint32_t rid;
1993 const uint32_t password_fields[] = {
1994 SAMR_FIELD_PASSWORD,
1995 SAMR_FIELD_PASSWORD2,
1996 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2000 status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2001 if (!NT_STATUS_IS_OK(status)) {
2002 ret = false;
2005 switch (which_ops) {
2006 case TORTURE_SAMR_USER_ATTRIBUTES:
2007 if (!test_QuerySecurity(p, tctx, user_handle)) {
2008 ret = false;
2011 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2012 ret = false;
2015 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2016 ret = false;
2019 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2020 base_acct_name)) {
2021 ret = false;
2024 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2025 ret = false;
2028 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2029 ret = false;
2032 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2033 ret = false;
2035 break;
2036 case TORTURE_SAMR_PASSWORDS:
2037 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2038 char simple_pass[9];
2039 char *v = generate_random_str(tctx, 1);
2041 ZERO_STRUCT(simple_pass);
2042 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2044 printf("Testing machine account password policy rules\n");
2046 /* Workstation trust accounts don't seem to need to honour password quality policy */
2047 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2048 ret = false;
2051 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2052 ret = false;
2055 /* reset again, to allow another 'user' password change */
2056 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2057 ret = false;
2060 /* Try a 'short' password */
2061 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2062 ret = false;
2067 for (i = 0; password_fields[i]; i++) {
2068 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2069 ret = false;
2072 /* check it was set right */
2073 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2074 ret = false;
2078 for (i = 0; password_fields[i]; i++) {
2079 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2080 ret = false;
2083 /* check it was set right */
2084 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2085 ret = false;
2089 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2090 ret = false;
2093 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2094 ret = false;
2097 q.in.user_handle = user_handle;
2098 q.in.level = 5;
2100 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2101 if (!NT_STATUS_IS_OK(status)) {
2102 printf("QueryUserInfo level %u failed - %s\n",
2103 q.in.level, nt_errstr(status));
2104 ret = false;
2105 } else {
2106 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2107 if ((q.out.info->info5.acct_flags) != expected_flags) {
2108 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2109 q.out.info->info5.acct_flags,
2110 expected_flags);
2111 ret = false;
2113 if (q.out.info->info5.rid != rid) {
2114 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2115 q.out.info->info5.rid, rid);
2120 break;
2121 case TORTURE_SAMR_OTHER:
2122 /* We just need the account to exist */
2123 break;
2125 return ret;
2128 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2129 struct policy_handle *alias_handle,
2130 const struct dom_sid *domain_sid)
2132 bool ret = true;
2134 if (!test_QuerySecurity(p, tctx, alias_handle)) {
2135 ret = false;
2138 if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2139 ret = false;
2142 if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2143 ret = false;
2146 if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2147 ret = false;
2150 if (torture_setting_bool(tctx, "samba4", false)) {
2151 printf("skipping MultipleMembers Alias tests against Samba4\n");
2152 return ret;
2155 if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2156 ret = false;
2159 return ret;
2163 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2164 struct policy_handle *user_handle)
2166 struct samr_DeleteUser d;
2167 NTSTATUS status;
2168 bool ret = true;
2169 printf("Testing DeleteUser\n");
2171 d.in.user_handle = user_handle;
2172 d.out.user_handle = user_handle;
2174 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2175 if (!NT_STATUS_IS_OK(status)) {
2176 printf("DeleteUser failed - %s\n", nt_errstr(status));
2177 ret = false;
2180 return ret;
2183 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2184 struct policy_handle *handle, const char *name)
2186 NTSTATUS status;
2187 struct samr_DeleteUser d;
2188 struct policy_handle user_handle;
2189 uint32_t rid;
2191 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2192 if (!NT_STATUS_IS_OK(status)) {
2193 goto failed;
2196 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2197 if (!NT_STATUS_IS_OK(status)) {
2198 goto failed;
2201 d.in.user_handle = &user_handle;
2202 d.out.user_handle = &user_handle;
2203 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2204 if (!NT_STATUS_IS_OK(status)) {
2205 goto failed;
2208 return true;
2210 failed:
2211 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2212 return false;
2216 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2217 struct policy_handle *handle, const char *name)
2219 NTSTATUS status;
2220 struct samr_OpenGroup r;
2221 struct samr_DeleteDomainGroup d;
2222 struct policy_handle group_handle;
2223 uint32_t rid;
2225 status = test_LookupName(p, mem_ctx, handle, name, &rid);
2226 if (!NT_STATUS_IS_OK(status)) {
2227 goto failed;
2230 r.in.domain_handle = handle;
2231 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2232 r.in.rid = rid;
2233 r.out.group_handle = &group_handle;
2234 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2235 if (!NT_STATUS_IS_OK(status)) {
2236 goto failed;
2239 d.in.group_handle = &group_handle;
2240 d.out.group_handle = &group_handle;
2241 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2242 if (!NT_STATUS_IS_OK(status)) {
2243 goto failed;
2246 return true;
2248 failed:
2249 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2250 return false;
2254 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2255 struct policy_handle *domain_handle, const char *name)
2257 NTSTATUS status;
2258 struct samr_OpenAlias r;
2259 struct samr_DeleteDomAlias d;
2260 struct policy_handle alias_handle;
2261 uint32_t rid;
2263 printf("testing DeleteAlias_byname\n");
2265 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2266 if (!NT_STATUS_IS_OK(status)) {
2267 goto failed;
2270 r.in.domain_handle = domain_handle;
2271 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2272 r.in.rid = rid;
2273 r.out.alias_handle = &alias_handle;
2274 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2275 if (!NT_STATUS_IS_OK(status)) {
2276 goto failed;
2279 d.in.alias_handle = &alias_handle;
2280 d.out.alias_handle = &alias_handle;
2281 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2282 if (!NT_STATUS_IS_OK(status)) {
2283 goto failed;
2286 return true;
2288 failed:
2289 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2290 return false;
2293 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2294 struct policy_handle *alias_handle)
2296 struct samr_DeleteDomAlias d;
2297 NTSTATUS status;
2298 bool ret = true;
2299 printf("Testing DeleteAlias\n");
2301 d.in.alias_handle = alias_handle;
2302 d.out.alias_handle = alias_handle;
2304 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2305 if (!NT_STATUS_IS_OK(status)) {
2306 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2307 ret = false;
2310 return ret;
2313 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2314 struct policy_handle *domain_handle,
2315 struct policy_handle *alias_handle,
2316 const struct dom_sid *domain_sid)
2318 NTSTATUS status;
2319 struct samr_CreateDomAlias r;
2320 struct lsa_String name;
2321 uint32_t rid;
2322 bool ret = true;
2324 init_lsa_String(&name, TEST_ALIASNAME);
2325 r.in.domain_handle = domain_handle;
2326 r.in.alias_name = &name;
2327 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2328 r.out.alias_handle = alias_handle;
2329 r.out.rid = &rid;
2331 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2333 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2335 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2336 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2337 printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2338 return true;
2339 } else {
2340 printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
2341 nt_errstr(status));
2342 return false;
2346 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2347 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2348 return false;
2350 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2353 if (!NT_STATUS_IS_OK(status)) {
2354 printf("CreateAlias failed - %s\n", nt_errstr(status));
2355 return false;
2358 if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2359 ret = false;
2362 return ret;
2365 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2366 const char *acct_name,
2367 struct policy_handle *domain_handle, char **password)
2369 bool ret = true;
2371 if (!*password) {
2372 return false;
2375 if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2376 ret = false;
2379 if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2380 ret = false;
2383 if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2384 ret = false;
2387 /* test what happens when setting the old password again */
2388 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2389 ret = false;
2393 char simple_pass[9];
2394 char *v = generate_random_str(mem_ctx, 1);
2396 ZERO_STRUCT(simple_pass);
2397 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2399 /* test what happens when picking a simple password */
2400 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2401 ret = false;
2405 /* set samr_SetDomainInfo level 1 with min_length 5 */
2407 struct samr_QueryDomainInfo r;
2408 struct samr_SetDomainInfo s;
2409 uint16_t len_old, len;
2410 uint32_t pwd_prop_old;
2411 int64_t min_pwd_age_old;
2412 NTSTATUS status;
2414 len = 5;
2416 r.in.domain_handle = domain_handle;
2417 r.in.level = 1;
2419 printf("testing samr_QueryDomainInfo level 1\n");
2420 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2421 if (!NT_STATUS_IS_OK(status)) {
2422 return false;
2425 s.in.domain_handle = domain_handle;
2426 s.in.level = 1;
2427 s.in.info = r.out.info;
2429 /* remember the old min length, so we can reset it */
2430 len_old = s.in.info->info1.min_password_length;
2431 s.in.info->info1.min_password_length = len;
2432 pwd_prop_old = s.in.info->info1.password_properties;
2433 /* turn off password complexity checks for this test */
2434 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2436 min_pwd_age_old = s.in.info->info1.min_password_age;
2437 s.in.info->info1.min_password_age = 0;
2439 printf("testing samr_SetDomainInfo level 1\n");
2440 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2441 if (!NT_STATUS_IS_OK(status)) {
2442 return false;
2445 printf("calling test_ChangePasswordUser3 with too short password\n");
2447 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2448 ret = false;
2451 s.in.info->info1.min_password_length = len_old;
2452 s.in.info->info1.password_properties = pwd_prop_old;
2453 s.in.info->info1.min_password_age = min_pwd_age_old;
2455 printf("testing samr_SetDomainInfo level 1\n");
2456 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2457 if (!NT_STATUS_IS_OK(status)) {
2458 return false;
2464 NTSTATUS status;
2465 struct samr_OpenUser r;
2466 struct samr_QueryUserInfo q;
2467 struct samr_LookupNames n;
2468 struct policy_handle user_handle;
2470 n.in.domain_handle = domain_handle;
2471 n.in.num_names = 1;
2472 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2473 n.in.names[0].string = acct_name;
2475 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2476 if (!NT_STATUS_IS_OK(status)) {
2477 printf("LookupNames failed - %s\n", nt_errstr(status));
2478 return false;
2481 r.in.domain_handle = domain_handle;
2482 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2483 r.in.rid = n.out.rids.ids[0];
2484 r.out.user_handle = &user_handle;
2486 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2487 if (!NT_STATUS_IS_OK(status)) {
2488 printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2489 return false;
2492 q.in.user_handle = &user_handle;
2493 q.in.level = 5;
2495 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2496 if (!NT_STATUS_IS_OK(status)) {
2497 printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2498 return false;
2501 printf("calling test_ChangePasswordUser3 with too early password change\n");
2503 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
2504 q.out.info->info5.last_password_change, true)) {
2505 ret = false;
2509 /* we change passwords twice - this has the effect of verifying
2510 they were changed correctly for the final call */
2511 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2512 ret = false;
2515 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2516 ret = false;
2519 return ret;
2522 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2523 struct policy_handle *domain_handle,
2524 struct policy_handle *user_handle_out,
2525 struct dom_sid *domain_sid,
2526 enum torture_samr_choice which_ops)
2529 TALLOC_CTX *user_ctx;
2531 NTSTATUS status;
2532 struct samr_CreateUser r;
2533 struct samr_QueryUserInfo q;
2534 struct samr_DeleteUser d;
2535 uint32_t rid;
2537 /* This call creates a 'normal' account - check that it really does */
2538 const uint32_t acct_flags = ACB_NORMAL;
2539 struct lsa_String name;
2540 bool ret = true;
2542 struct policy_handle user_handle;
2543 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2544 init_lsa_String(&name, TEST_ACCOUNT_NAME);
2546 r.in.domain_handle = domain_handle;
2547 r.in.account_name = &name;
2548 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2549 r.out.user_handle = &user_handle;
2550 r.out.rid = &rid;
2552 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2554 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2556 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2557 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2558 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2559 return true;
2560 } else {
2561 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2562 nt_errstr(status));
2563 return false;
2567 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2568 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2569 talloc_free(user_ctx);
2570 return false;
2572 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2574 if (!NT_STATUS_IS_OK(status)) {
2575 talloc_free(user_ctx);
2576 printf("CreateUser failed - %s\n", nt_errstr(status));
2577 return false;
2578 } else {
2579 q.in.user_handle = &user_handle;
2580 q.in.level = 16;
2582 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2583 if (!NT_STATUS_IS_OK(status)) {
2584 printf("QueryUserInfo level %u failed - %s\n",
2585 q.in.level, nt_errstr(status));
2586 ret = false;
2587 } else {
2588 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2589 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2590 q.out.info->info16.acct_flags,
2591 acct_flags);
2592 ret = false;
2596 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2597 acct_flags, name.string, which_ops)) {
2598 ret = false;
2601 if (user_handle_out) {
2602 *user_handle_out = user_handle;
2603 } else {
2604 printf("Testing DeleteUser (createuser test)\n");
2606 d.in.user_handle = &user_handle;
2607 d.out.user_handle = &user_handle;
2609 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2610 if (!NT_STATUS_IS_OK(status)) {
2611 printf("DeleteUser failed - %s\n", nt_errstr(status));
2612 ret = false;
2618 talloc_free(user_ctx);
2620 return ret;
2624 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2625 struct policy_handle *domain_handle,
2626 struct dom_sid *domain_sid,
2627 enum torture_samr_choice which_ops)
2629 NTSTATUS status;
2630 struct samr_CreateUser2 r;
2631 struct samr_QueryUserInfo q;
2632 struct samr_DeleteUser d;
2633 struct policy_handle user_handle;
2634 uint32_t rid;
2635 struct lsa_String name;
2636 bool ret = true;
2637 int i;
2639 struct {
2640 uint32_t acct_flags;
2641 const char *account_name;
2642 NTSTATUS nt_status;
2643 } account_types[] = {
2644 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2645 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2646 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2647 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2648 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2649 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2650 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2651 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2652 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2653 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2654 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2655 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2656 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2657 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2658 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2661 for (i = 0; account_types[i].account_name; i++) {
2662 TALLOC_CTX *user_ctx;
2663 uint32_t acct_flags = account_types[i].acct_flags;
2664 uint32_t access_granted;
2665 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2666 init_lsa_String(&name, account_types[i].account_name);
2668 r.in.domain_handle = domain_handle;
2669 r.in.account_name = &name;
2670 r.in.acct_flags = acct_flags;
2671 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2672 r.out.user_handle = &user_handle;
2673 r.out.access_granted = &access_granted;
2674 r.out.rid = &rid;
2676 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2678 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2680 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2681 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2682 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2683 continue;
2684 } else {
2685 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
2686 nt_errstr(status));
2687 ret = false;
2688 continue;
2692 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2693 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2694 talloc_free(user_ctx);
2695 ret = false;
2696 continue;
2698 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2701 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2702 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
2703 nt_errstr(status), nt_errstr(account_types[i].nt_status));
2704 ret = false;
2707 if (NT_STATUS_IS_OK(status)) {
2708 q.in.user_handle = &user_handle;
2709 q.in.level = 5;
2711 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2712 if (!NT_STATUS_IS_OK(status)) {
2713 printf("QueryUserInfo level %u failed - %s\n",
2714 q.in.level, nt_errstr(status));
2715 ret = false;
2716 } else {
2717 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2718 if (acct_flags == ACB_NORMAL) {
2719 expected_flags |= ACB_PW_EXPIRED;
2721 if ((q.out.info->info5.acct_flags) != expected_flags) {
2722 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2723 q.out.info->info5.acct_flags,
2724 expected_flags);
2725 ret = false;
2727 switch (acct_flags) {
2728 case ACB_SVRTRUST:
2729 if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2730 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
2731 DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2732 ret = false;
2734 break;
2735 case ACB_WSTRUST:
2736 if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2737 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
2738 DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2739 ret = false;
2741 break;
2742 case ACB_NORMAL:
2743 if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2744 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
2745 DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2746 ret = false;
2748 break;
2752 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
2753 acct_flags, name.string, which_ops)) {
2754 ret = false;
2757 printf("Testing DeleteUser (createuser2 test)\n");
2759 d.in.user_handle = &user_handle;
2760 d.out.user_handle = &user_handle;
2762 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2763 if (!NT_STATUS_IS_OK(status)) {
2764 printf("DeleteUser failed - %s\n", nt_errstr(status));
2765 ret = false;
2768 talloc_free(user_ctx);
2771 return ret;
2774 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2775 struct policy_handle *handle)
2777 NTSTATUS status;
2778 struct samr_QueryAliasInfo r;
2779 uint16_t levels[] = {1, 2, 3};
2780 int i;
2781 bool ret = true;
2783 for (i=0;i<ARRAY_SIZE(levels);i++) {
2784 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2786 r.in.alias_handle = handle;
2787 r.in.level = levels[i];
2789 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2790 if (!NT_STATUS_IS_OK(status)) {
2791 printf("QueryAliasInfo level %u failed - %s\n",
2792 levels[i], nt_errstr(status));
2793 ret = false;
2797 return ret;
2800 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2801 struct policy_handle *handle)
2803 NTSTATUS status;
2804 struct samr_QueryGroupInfo r;
2805 uint16_t levels[] = {1, 2, 3, 4, 5};
2806 int i;
2807 bool ret = true;
2809 for (i=0;i<ARRAY_SIZE(levels);i++) {
2810 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2812 r.in.group_handle = handle;
2813 r.in.level = levels[i];
2815 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2816 if (!NT_STATUS_IS_OK(status)) {
2817 printf("QueryGroupInfo level %u failed - %s\n",
2818 levels[i], nt_errstr(status));
2819 ret = false;
2823 return ret;
2826 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2827 struct policy_handle *handle)
2829 NTSTATUS status;
2830 struct samr_QueryGroupMember r;
2831 bool ret = true;
2833 printf("Testing QueryGroupMember\n");
2835 r.in.group_handle = handle;
2837 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2838 if (!NT_STATUS_IS_OK(status)) {
2839 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2840 ret = false;
2843 return ret;
2847 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2848 struct policy_handle *handle)
2850 NTSTATUS status;
2851 struct samr_QueryGroupInfo r;
2852 struct samr_SetGroupInfo s;
2853 uint16_t levels[] = {1, 2, 3, 4};
2854 uint16_t set_ok[] = {0, 1, 1, 1};
2855 int i;
2856 bool ret = true;
2858 for (i=0;i<ARRAY_SIZE(levels);i++) {
2859 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2861 r.in.group_handle = handle;
2862 r.in.level = levels[i];
2864 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2865 if (!NT_STATUS_IS_OK(status)) {
2866 printf("QueryGroupInfo level %u failed - %s\n",
2867 levels[i], nt_errstr(status));
2868 ret = false;
2871 printf("Testing SetGroupInfo level %u\n", levels[i]);
2873 s.in.group_handle = handle;
2874 s.in.level = levels[i];
2875 s.in.info = r.out.info;
2877 #if 0
2878 /* disabled this, as it changes the name only from the point of view of samr,
2879 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2880 the name is still reserved, so creating the old name fails, but deleting by the old name
2881 also fails */
2882 if (s.in.level == 2) {
2883 init_lsa_String(&s.in.info->string, "NewName");
2885 #endif
2887 if (s.in.level == 4) {
2888 init_lsa_String(&s.in.info->description, "test description");
2891 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2892 if (set_ok[i]) {
2893 if (!NT_STATUS_IS_OK(status)) {
2894 printf("SetGroupInfo level %u failed - %s\n",
2895 r.in.level, nt_errstr(status));
2896 ret = false;
2897 continue;
2899 } else {
2900 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2901 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2902 r.in.level, nt_errstr(status));
2903 ret = false;
2904 continue;
2909 return ret;
2912 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2913 struct policy_handle *handle)
2915 NTSTATUS status;
2916 struct samr_QueryUserInfo r;
2917 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2918 11, 12, 13, 14, 16, 17, 20, 21};
2919 int i;
2920 bool ret = true;
2922 for (i=0;i<ARRAY_SIZE(levels);i++) {
2923 printf("Testing QueryUserInfo level %u\n", levels[i]);
2925 r.in.user_handle = handle;
2926 r.in.level = levels[i];
2928 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2929 if (!NT_STATUS_IS_OK(status)) {
2930 printf("QueryUserInfo level %u failed - %s\n",
2931 levels[i], nt_errstr(status));
2932 ret = false;
2936 return ret;
2939 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2940 struct policy_handle *handle)
2942 NTSTATUS status;
2943 struct samr_QueryUserInfo2 r;
2944 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2945 11, 12, 13, 14, 16, 17, 20, 21};
2946 int i;
2947 bool ret = true;
2949 for (i=0;i<ARRAY_SIZE(levels);i++) {
2950 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2952 r.in.user_handle = handle;
2953 r.in.level = levels[i];
2955 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2956 if (!NT_STATUS_IS_OK(status)) {
2957 printf("QueryUserInfo2 level %u failed - %s\n",
2958 levels[i], nt_errstr(status));
2959 ret = false;
2963 return ret;
2966 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2967 struct policy_handle *handle, uint32_t rid)
2969 NTSTATUS status;
2970 struct samr_OpenUser r;
2971 struct policy_handle user_handle;
2972 bool ret = true;
2974 printf("Testing OpenUser(%u)\n", rid);
2976 r.in.domain_handle = handle;
2977 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2978 r.in.rid = rid;
2979 r.out.user_handle = &user_handle;
2981 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2982 if (!NT_STATUS_IS_OK(status)) {
2983 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2984 return false;
2987 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2988 ret = false;
2991 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2992 ret = false;
2995 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2996 ret = false;
2999 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3000 ret = false;
3003 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3004 ret = false;
3007 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3008 ret = false;
3011 return ret;
3014 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3015 struct policy_handle *handle, uint32_t rid)
3017 NTSTATUS status;
3018 struct samr_OpenGroup r;
3019 struct policy_handle group_handle;
3020 bool ret = true;
3022 printf("Testing OpenGroup(%u)\n", rid);
3024 r.in.domain_handle = handle;
3025 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3026 r.in.rid = rid;
3027 r.out.group_handle = &group_handle;
3029 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3030 if (!NT_STATUS_IS_OK(status)) {
3031 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3032 return false;
3035 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3036 ret = false;
3039 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3040 ret = false;
3043 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3044 ret = false;
3047 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3048 ret = false;
3051 return ret;
3054 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3055 struct policy_handle *handle, uint32_t rid)
3057 NTSTATUS status;
3058 struct samr_OpenAlias r;
3059 struct policy_handle alias_handle;
3060 bool ret = true;
3062 printf("Testing OpenAlias(%u)\n", rid);
3064 r.in.domain_handle = handle;
3065 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3066 r.in.rid = rid;
3067 r.out.alias_handle = &alias_handle;
3069 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3070 if (!NT_STATUS_IS_OK(status)) {
3071 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3072 return false;
3075 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3076 ret = false;
3079 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3080 ret = false;
3083 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3084 ret = false;
3087 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3088 ret = false;
3091 return ret;
3094 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3095 struct policy_handle *handle, uint32_t rid,
3096 uint32_t acct_flag_mask)
3098 NTSTATUS status;
3099 struct samr_OpenUser r;
3100 struct samr_QueryUserInfo q;
3101 struct policy_handle user_handle;
3102 bool ret = true;
3104 printf("Testing OpenUser(%u)\n", rid);
3106 r.in.domain_handle = handle;
3107 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3108 r.in.rid = rid;
3109 r.out.user_handle = &user_handle;
3111 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3114 return false;
3117 q.in.user_handle = &user_handle;
3118 q.in.level = 16;
3120 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3121 if (!NT_STATUS_IS_OK(status)) {
3122 printf("QueryUserInfo level 16 failed - %s\n",
3123 nt_errstr(status));
3124 ret = false;
3125 } else {
3126 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3127 printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3128 acct_flag_mask, q.out.info->info16.acct_flags, rid);
3129 ret = false;
3133 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3134 ret = false;
3137 return ret;
3140 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3141 struct policy_handle *handle)
3143 NTSTATUS status = STATUS_MORE_ENTRIES;
3144 struct samr_EnumDomainUsers r;
3145 uint32_t mask, resume_handle=0;
3146 int i, mask_idx;
3147 bool ret = true;
3148 struct samr_LookupNames n;
3149 struct samr_LookupRids lr ;
3150 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
3151 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
3152 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
3153 ACB_PWNOEXP, 0};
3155 printf("Testing EnumDomainUsers\n");
3157 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3158 r.in.domain_handle = handle;
3159 r.in.resume_handle = &resume_handle;
3160 r.in.acct_flags = mask = masks[mask_idx];
3161 r.in.max_size = (uint32_t)-1;
3162 r.out.resume_handle = &resume_handle;
3164 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3165 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3166 !NT_STATUS_IS_OK(status)) {
3167 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3168 return false;
3171 if (!r.out.sam) {
3172 printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3173 return false;
3176 if (r.out.sam->count == 0) {
3177 continue;
3180 for (i=0;i<r.out.sam->count;i++) {
3181 if (mask) {
3182 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3183 ret = false;
3185 } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3186 ret = false;
3191 printf("Testing LookupNames\n");
3192 n.in.domain_handle = handle;
3193 n.in.num_names = r.out.sam->count;
3194 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3195 for (i=0;i<r.out.sam->count;i++) {
3196 n.in.names[i].string = r.out.sam->entries[i].name.string;
3198 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3199 if (!NT_STATUS_IS_OK(status)) {
3200 printf("LookupNames failed - %s\n", nt_errstr(status));
3201 ret = false;
3205 printf("Testing LookupRids\n");
3206 lr.in.domain_handle = handle;
3207 lr.in.num_rids = r.out.sam->count;
3208 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3209 for (i=0;i<r.out.sam->count;i++) {
3210 lr.in.rids[i] = r.out.sam->entries[i].idx;
3212 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 printf("LookupRids failed - %s\n", nt_errstr(status));
3215 ret = false;
3218 return ret;
3222 try blasting the server with a bunch of sync requests
3224 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx,
3225 struct policy_handle *handle)
3227 NTSTATUS status;
3228 struct samr_EnumDomainUsers r;
3229 uint32_t resume_handle=0;
3230 int i;
3231 #define ASYNC_COUNT 100
3232 struct rpc_request *req[ASYNC_COUNT];
3234 if (!torture_setting_bool(tctx, "dangerous", false)) {
3235 printf("samr async test disabled - enable dangerous tests to use\n");
3236 return true;
3239 printf("Testing EnumDomainUsers_async\n");
3241 r.in.domain_handle = handle;
3242 r.in.resume_handle = &resume_handle;
3243 r.in.acct_flags = 0;
3244 r.in.max_size = (uint32_t)-1;
3245 r.out.resume_handle = &resume_handle;
3247 for (i=0;i<ASYNC_COUNT;i++) {
3248 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3251 for (i=0;i<ASYNC_COUNT;i++) {
3252 status = dcerpc_ndr_request_recv(req[i]);
3253 if (!NT_STATUS_IS_OK(status)) {
3254 printf("EnumDomainUsers[%d] failed - %s\n",
3255 i, nt_errstr(status));
3256 return false;
3260 printf("%d async requests OK\n", i);
3262 return true;
3265 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3266 struct policy_handle *handle)
3268 NTSTATUS status;
3269 struct samr_EnumDomainGroups r;
3270 uint32_t resume_handle=0;
3271 int i;
3272 bool ret = true;
3274 printf("Testing EnumDomainGroups\n");
3276 r.in.domain_handle = handle;
3277 r.in.resume_handle = &resume_handle;
3278 r.in.max_size = (uint32_t)-1;
3279 r.out.resume_handle = &resume_handle;
3281 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3282 if (!NT_STATUS_IS_OK(status)) {
3283 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3284 return false;
3287 if (!r.out.sam) {
3288 return false;
3291 for (i=0;i<r.out.sam->count;i++) {
3292 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3293 ret = false;
3297 return ret;
3300 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3301 struct policy_handle *handle)
3303 NTSTATUS status;
3304 struct samr_EnumDomainAliases r;
3305 uint32_t resume_handle=0;
3306 int i;
3307 bool ret = true;
3309 printf("Testing EnumDomainAliases\n");
3311 r.in.domain_handle = handle;
3312 r.in.resume_handle = &resume_handle;
3313 r.in.acct_flags = (uint32_t)-1;
3314 r.out.resume_handle = &resume_handle;
3316 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3317 if (!NT_STATUS_IS_OK(status)) {
3318 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3319 return false;
3322 if (!r.out.sam) {
3323 return false;
3326 for (i=0;i<r.out.sam->count;i++) {
3327 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3328 ret = false;
3332 return ret;
3335 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3336 struct policy_handle *handle)
3338 NTSTATUS status;
3339 struct samr_GetDisplayEnumerationIndex r;
3340 bool ret = true;
3341 uint16_t levels[] = {1, 2, 3, 4, 5};
3342 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3343 int i;
3345 for (i=0;i<ARRAY_SIZE(levels);i++) {
3346 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3348 r.in.domain_handle = handle;
3349 r.in.level = levels[i];
3350 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3352 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3354 if (ok_lvl[i] &&
3355 !NT_STATUS_IS_OK(status) &&
3356 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3357 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3358 levels[i], nt_errstr(status));
3359 ret = false;
3362 init_lsa_String(&r.in.name, "zzzzzzzz");
3364 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3366 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3367 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
3368 levels[i], nt_errstr(status));
3369 ret = false;
3373 return ret;
3376 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3377 struct policy_handle *handle)
3379 NTSTATUS status;
3380 struct samr_GetDisplayEnumerationIndex2 r;
3381 bool ret = true;
3382 uint16_t levels[] = {1, 2, 3, 4, 5};
3383 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3384 int i;
3386 for (i=0;i<ARRAY_SIZE(levels);i++) {
3387 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3389 r.in.domain_handle = handle;
3390 r.in.level = levels[i];
3391 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3393 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3394 if (ok_lvl[i] &&
3395 !NT_STATUS_IS_OK(status) &&
3396 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3397 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3398 levels[i], nt_errstr(status));
3399 ret = false;
3402 init_lsa_String(&r.in.name, "zzzzzzzz");
3404 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3405 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3406 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
3407 levels[i], nt_errstr(status));
3408 ret = false;
3412 return ret;
3415 #define STRING_EQUAL_QUERY(s1, s2, user) \
3416 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3417 /* odd, but valid */ \
3418 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3419 printf("%s mismatch for %s: %s != %s (%s)\n", \
3420 #s1, user.string, s1.string, s2.string, __location__); \
3421 ret = false; \
3423 #define INT_EQUAL_QUERY(s1, s2, user) \
3424 if (s1 != s2) { \
3425 printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3426 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3427 ret = false; \
3430 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3431 struct samr_QueryDisplayInfo *querydisplayinfo,
3432 bool *seen_testuser)
3434 struct samr_OpenUser r;
3435 struct samr_QueryUserInfo q;
3436 struct policy_handle user_handle;
3437 int i, ret = true;
3438 NTSTATUS status;
3439 r.in.domain_handle = querydisplayinfo->in.domain_handle;
3440 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3441 for (i = 0; ; i++) {
3442 switch (querydisplayinfo->in.level) {
3443 case 1:
3444 if (i >= querydisplayinfo->out.info.info1.count) {
3445 return ret;
3447 r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3448 break;
3449 case 2:
3450 if (i >= querydisplayinfo->out.info.info2.count) {
3451 return ret;
3453 r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3454 break;
3455 case 3:
3456 /* Groups */
3457 case 4:
3458 case 5:
3459 /* Not interested in validating just the account name */
3460 return true;
3463 r.out.user_handle = &user_handle;
3465 switch (querydisplayinfo->in.level) {
3466 case 1:
3467 case 2:
3468 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3469 if (!NT_STATUS_IS_OK(status)) {
3470 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3471 return false;
3475 q.in.user_handle = &user_handle;
3476 q.in.level = 21;
3477 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3478 if (!NT_STATUS_IS_OK(status)) {
3479 printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3480 return false;
3483 switch (querydisplayinfo->in.level) {
3484 case 1:
3485 if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3486 *seen_testuser = true;
3488 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
3489 q.out.info->info21.full_name, q.out.info->info21.account_name);
3490 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
3491 q.out.info->info21.account_name, q.out.info->info21.account_name);
3492 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
3493 q.out.info->info21.description, q.out.info->info21.account_name);
3494 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
3495 q.out.info->info21.rid, q.out.info->info21.account_name);
3496 INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
3497 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3499 break;
3500 case 2:
3501 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
3502 q.out.info->info21.account_name, q.out.info->info21.account_name);
3503 STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
3504 q.out.info->info21.description, q.out.info->info21.account_name);
3505 INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
3506 q.out.info->info21.rid, q.out.info->info21.account_name);
3507 INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
3508 q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3510 if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3511 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
3512 q.out.info->info21.account_name.string);
3515 if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3516 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3517 q.out.info->info21.account_name.string,
3518 querydisplayinfo->out.info.info2.entries[i].acct_flags,
3519 q.out.info->info21.acct_flags);
3520 return false;
3523 break;
3526 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3527 return false;
3530 return ret;
3533 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3534 struct policy_handle *handle)
3536 NTSTATUS status;
3537 struct samr_QueryDisplayInfo r;
3538 struct samr_QueryDomainInfo dom_info;
3539 bool ret = true;
3540 uint16_t levels[] = {1, 2, 3, 4, 5};
3541 int i;
3542 bool seen_testuser = false;
3544 for (i=0;i<ARRAY_SIZE(levels);i++) {
3545 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3547 r.in.start_idx = 0;
3548 status = STATUS_MORE_ENTRIES;
3549 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3550 r.in.domain_handle = handle;
3551 r.in.level = levels[i];
3552 r.in.max_entries = 2;
3553 r.in.buf_size = (uint32_t)-1;
3555 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3556 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3557 printf("QueryDisplayInfo level %u failed - %s\n",
3558 levels[i], nt_errstr(status));
3559 ret = false;
3561 switch (r.in.level) {
3562 case 1:
3563 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3564 ret = false;
3566 r.in.start_idx += r.out.info.info1.count;
3567 break;
3568 case 2:
3569 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3570 ret = false;
3572 r.in.start_idx += r.out.info.info2.count;
3573 break;
3574 case 3:
3575 r.in.start_idx += r.out.info.info3.count;
3576 break;
3577 case 4:
3578 r.in.start_idx += r.out.info.info4.count;
3579 break;
3580 case 5:
3581 r.in.start_idx += r.out.info.info5.count;
3582 break;
3585 dom_info.in.domain_handle = handle;
3586 dom_info.in.level = 2;
3587 /* Check number of users returned is correct */
3588 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3589 if (!NT_STATUS_IS_OK(status)) {
3590 printf("QueryDomainInfo level %u failed - %s\n",
3591 r.in.level, nt_errstr(status));
3592 ret = false;
3593 break;
3595 switch (r.in.level) {
3596 case 1:
3597 case 4:
3598 if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3599 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3600 r.in.start_idx, dom_info.out.info->info2.num_groups,
3601 dom_info.out.info->info2.domain_name.string);
3602 ret = false;
3604 if (!seen_testuser) {
3605 struct policy_handle user_handle;
3606 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3607 printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
3608 dom_info.out.info->info2.domain_name.string);
3609 ret = false;
3610 test_samr_handle_Close(p, mem_ctx, &user_handle);
3613 break;
3614 case 3:
3615 case 5:
3616 if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3617 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3618 r.in.start_idx, dom_info.out.info->info2.num_groups,
3619 dom_info.out.info->info2.domain_name.string);
3620 ret = false;
3623 break;
3628 return ret;
3631 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3632 struct policy_handle *handle)
3634 NTSTATUS status;
3635 struct samr_QueryDisplayInfo2 r;
3636 bool ret = true;
3637 uint16_t levels[] = {1, 2, 3, 4, 5};
3638 int i;
3640 for (i=0;i<ARRAY_SIZE(levels);i++) {
3641 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3643 r.in.domain_handle = handle;
3644 r.in.level = levels[i];
3645 r.in.start_idx = 0;
3646 r.in.max_entries = 1000;
3647 r.in.buf_size = (uint32_t)-1;
3649 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3650 if (!NT_STATUS_IS_OK(status)) {
3651 printf("QueryDisplayInfo2 level %u failed - %s\n",
3652 levels[i], nt_errstr(status));
3653 ret = false;
3657 return ret;
3660 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3661 struct policy_handle *handle)
3663 NTSTATUS status;
3664 struct samr_QueryDisplayInfo3 r;
3665 bool ret = true;
3666 uint16_t levels[] = {1, 2, 3, 4, 5};
3667 int i;
3669 for (i=0;i<ARRAY_SIZE(levels);i++) {
3670 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3672 r.in.domain_handle = handle;
3673 r.in.level = levels[i];
3674 r.in.start_idx = 0;
3675 r.in.max_entries = 1000;
3676 r.in.buf_size = (uint32_t)-1;
3678 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3679 if (!NT_STATUS_IS_OK(status)) {
3680 printf("QueryDisplayInfo3 level %u failed - %s\n",
3681 levels[i], nt_errstr(status));
3682 ret = false;
3686 return ret;
3690 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3691 struct policy_handle *handle)
3693 NTSTATUS status;
3694 struct samr_QueryDisplayInfo r;
3695 bool ret = true;
3697 printf("Testing QueryDisplayInfo continuation\n");
3699 r.in.domain_handle = handle;
3700 r.in.level = 1;
3701 r.in.start_idx = 0;
3702 r.in.max_entries = 1;
3703 r.in.buf_size = (uint32_t)-1;
3705 do {
3706 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3707 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3708 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3709 printf("expected idx %d but got %d\n",
3710 r.in.start_idx + 1,
3711 r.out.info.info1.entries[0].idx);
3712 break;
3715 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3716 !NT_STATUS_IS_OK(status)) {
3717 printf("QueryDisplayInfo level %u failed - %s\n",
3718 r.in.level, nt_errstr(status));
3719 ret = false;
3720 break;
3722 r.in.start_idx++;
3723 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3724 NT_STATUS_IS_OK(status)) &&
3725 r.out.returned_size != 0);
3727 return ret;
3730 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3731 struct policy_handle *handle)
3733 NTSTATUS status;
3734 struct samr_QueryDomainInfo r;
3735 struct samr_SetDomainInfo s;
3736 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3737 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
3738 int i;
3739 bool ret = true;
3740 const char *domain_comment = talloc_asprintf(mem_ctx,
3741 "Tortured by Samba4 RPC-SAMR: %s",
3742 timestring(mem_ctx, time(NULL)));
3744 s.in.domain_handle = handle;
3745 s.in.level = 4;
3746 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3748 s.in.info->info4.comment.string = domain_comment;
3749 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 printf("SetDomainInfo level %u (set comment) failed - %s\n",
3752 r.in.level, nt_errstr(status));
3753 return false;
3756 for (i=0;i<ARRAY_SIZE(levels);i++) {
3757 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3759 r.in.domain_handle = handle;
3760 r.in.level = levels[i];
3762 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3763 if (!NT_STATUS_IS_OK(status)) {
3764 printf("QueryDomainInfo level %u failed - %s\n",
3765 r.in.level, nt_errstr(status));
3766 ret = false;
3767 continue;
3770 switch (levels[i]) {
3771 case 2:
3772 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3773 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3774 levels[i], r.out.info->info2.comment.string, domain_comment);
3775 ret = false;
3777 if (!r.out.info->info2.primary.string) {
3778 printf("QueryDomainInfo level %u returned no PDC name\n",
3779 levels[i]);
3780 ret = false;
3781 } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3782 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3783 printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3784 levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3787 break;
3788 case 4:
3789 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3790 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3791 levels[i], r.out.info->info4.comment.string, domain_comment);
3792 ret = false;
3794 break;
3795 case 6:
3796 if (!r.out.info->info6.primary.string) {
3797 printf("QueryDomainInfo level %u returned no PDC name\n",
3798 levels[i]);
3799 ret = false;
3801 break;
3802 case 11:
3803 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3804 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3805 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3806 ret = false;
3808 break;
3811 printf("Testing SetDomainInfo level %u\n", levels[i]);
3813 s.in.domain_handle = handle;
3814 s.in.level = levels[i];
3815 s.in.info = r.out.info;
3817 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3818 if (set_ok[i]) {
3819 if (!NT_STATUS_IS_OK(status)) {
3820 printf("SetDomainInfo level %u failed - %s\n",
3821 r.in.level, nt_errstr(status));
3822 ret = false;
3823 continue;
3825 } else {
3826 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3827 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
3828 r.in.level, nt_errstr(status));
3829 ret = false;
3830 continue;
3834 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3835 if (!NT_STATUS_IS_OK(status)) {
3836 printf("QueryDomainInfo level %u failed - %s\n",
3837 r.in.level, nt_errstr(status));
3838 ret = false;
3839 continue;
3843 return ret;
3847 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3848 struct policy_handle *handle)
3850 NTSTATUS status;
3851 struct samr_QueryDomainInfo2 r;
3852 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3853 int i;
3854 bool ret = true;
3856 for (i=0;i<ARRAY_SIZE(levels);i++) {
3857 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3859 r.in.domain_handle = handle;
3860 r.in.level = levels[i];
3862 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3863 if (!NT_STATUS_IS_OK(status)) {
3864 printf("QueryDomainInfo2 level %u failed - %s\n",
3865 r.in.level, nt_errstr(status));
3866 ret = false;
3867 continue;
3871 return true;
3874 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3875 set of group names. */
3876 static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3877 struct policy_handle *handle)
3879 struct samr_EnumDomainGroups q1;
3880 struct samr_QueryDisplayInfo q2;
3881 NTSTATUS status;
3882 uint32_t resume_handle=0;
3883 int i;
3884 bool ret = true;
3886 int num_names = 0;
3887 const char **names = NULL;
3889 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3891 q1.in.domain_handle = handle;
3892 q1.in.resume_handle = &resume_handle;
3893 q1.in.max_size = 5;
3894 q1.out.resume_handle = &resume_handle;
3896 status = STATUS_MORE_ENTRIES;
3897 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3898 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3900 if (!NT_STATUS_IS_OK(status) &&
3901 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3902 break;
3904 for (i=0; i<q1.out.num_entries; i++) {
3905 add_string_to_array(mem_ctx,
3906 q1.out.sam->entries[i].name.string,
3907 &names, &num_names);
3911 if (!NT_STATUS_IS_OK(status)) {
3912 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3913 return false;
3916 if (!q1.out.sam) {
3917 printf("EnumDomainGroups failed to return q1.out.sam\n");
3918 return false;
3921 q2.in.domain_handle = handle;
3922 q2.in.level = 5;
3923 q2.in.start_idx = 0;
3924 q2.in.max_entries = 5;
3925 q2.in.buf_size = (uint32_t)-1;
3927 status = STATUS_MORE_ENTRIES;
3928 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3929 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3931 if (!NT_STATUS_IS_OK(status) &&
3932 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3933 break;
3935 for (i=0; i<q2.out.info.info5.count; i++) {
3936 int j;
3937 const char *name = q2.out.info.info5.entries[i].account_name.string;
3938 bool found = false;
3939 for (j=0; j<num_names; j++) {
3940 if (names[j] == NULL)
3941 continue;
3942 if (strequal(names[j], name)) {
3943 names[j] = NULL;
3944 found = true;
3945 break;
3949 if (!found) {
3950 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3951 name);
3952 ret = false;
3955 q2.in.start_idx += q2.out.info.info5.count;
3958 if (!NT_STATUS_IS_OK(status)) {
3959 printf("QueryDisplayInfo level 5 failed - %s\n",
3960 nt_errstr(status));
3961 ret = false;
3964 for (i=0; i<num_names; i++) {
3965 if (names[i] != NULL) {
3966 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3967 names[i]);
3968 ret = false;
3972 return ret;
3975 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3976 struct policy_handle *group_handle)
3978 struct samr_DeleteDomainGroup d;
3979 NTSTATUS status;
3980 bool ret = true;
3982 printf("Testing DeleteDomainGroup\n");
3984 d.in.group_handle = group_handle;
3985 d.out.group_handle = group_handle;
3987 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3988 if (!NT_STATUS_IS_OK(status)) {
3989 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3990 ret = false;
3993 return ret;
3996 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3997 struct policy_handle *domain_handle)
3999 struct samr_TestPrivateFunctionsDomain r;
4000 NTSTATUS status;
4001 bool ret = true;
4003 printf("Testing TestPrivateFunctionsDomain\n");
4005 r.in.domain_handle = domain_handle;
4007 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
4008 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
4009 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
4010 ret = false;
4013 return ret;
4016 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4017 struct dom_sid *domain_sid,
4018 struct policy_handle *domain_handle)
4020 struct samr_RidToSid r;
4021 NTSTATUS status;
4022 bool ret = true;
4023 struct dom_sid *calc_sid;
4024 int rids[] = { 0, 42, 512, 10200 };
4025 int i;
4027 for (i=0;i<ARRAY_SIZE(rids);i++) {
4029 printf("Testing RidToSid\n");
4031 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
4032 r.in.domain_handle = domain_handle;
4033 r.in.rid = rids[i];
4035 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
4036 if (!NT_STATUS_IS_OK(status)) {
4037 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4038 ret = false;
4039 } else {
4040 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4042 if (!dom_sid_equal(calc_sid, r.out.sid)) {
4043 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
4044 dom_sid_string(mem_ctx, r.out.sid),
4045 dom_sid_string(mem_ctx, calc_sid));
4046 ret = false;
4051 return ret;
4054 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4055 struct policy_handle *domain_handle)
4057 struct samr_GetBootKeyInformation r;
4058 NTSTATUS status;
4059 bool ret = true;
4061 printf("Testing GetBootKeyInformation\n");
4063 r.in.domain_handle = domain_handle;
4065 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4066 if (!NT_STATUS_IS_OK(status)) {
4067 /* w2k3 seems to fail this sometimes and pass it sometimes */
4068 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4071 return ret;
4074 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
4075 struct policy_handle *domain_handle,
4076 struct policy_handle *group_handle)
4078 NTSTATUS status;
4079 struct samr_AddGroupMember r;
4080 struct samr_DeleteGroupMember d;
4081 struct samr_QueryGroupMember q;
4082 struct samr_SetMemberAttributesOfGroup s;
4083 bool ret = true;
4084 uint32_t rid;
4086 status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4087 if (!NT_STATUS_IS_OK(status)) {
4088 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4089 return false;
4092 r.in.group_handle = group_handle;
4093 r.in.rid = rid;
4094 r.in.flags = 0; /* ??? */
4096 printf("Testing AddGroupMember and DeleteGroupMember\n");
4098 d.in.group_handle = group_handle;
4099 d.in.rid = rid;
4101 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4102 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4103 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
4104 nt_errstr(status));
4105 return false;
4108 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4109 if (!NT_STATUS_IS_OK(status)) {
4110 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4111 return false;
4114 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4115 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4116 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
4117 nt_errstr(status));
4118 return false;
4121 if (torture_setting_bool(tctx, "samba4", false)) {
4122 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4123 } else {
4124 /* this one is quite strange. I am using random inputs in the
4125 hope of triggering an error that might give us a clue */
4127 s.in.group_handle = group_handle;
4128 s.in.unknown1 = random();
4129 s.in.unknown2 = random();
4131 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4132 if (!NT_STATUS_IS_OK(status)) {
4133 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4134 return false;
4138 q.in.group_handle = group_handle;
4140 status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4141 if (!NT_STATUS_IS_OK(status)) {
4142 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4143 return false;
4146 status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4147 if (!NT_STATUS_IS_OK(status)) {
4148 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4149 return false;
4152 status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4153 if (!NT_STATUS_IS_OK(status)) {
4154 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4155 return false;
4158 return ret;
4162 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4163 struct policy_handle *domain_handle,
4164 struct policy_handle *group_handle,
4165 struct dom_sid *domain_sid)
4167 NTSTATUS status;
4168 struct samr_CreateDomainGroup r;
4169 uint32_t rid;
4170 struct lsa_String name;
4171 bool ret = true;
4173 init_lsa_String(&name, TEST_GROUPNAME);
4175 r.in.domain_handle = domain_handle;
4176 r.in.name = &name;
4177 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4178 r.out.group_handle = group_handle;
4179 r.out.rid = &rid;
4181 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4183 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4185 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
4186 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4187 printf("Server correctly refused create of '%s'\n", r.in.name->string);
4188 return true;
4189 } else {
4190 printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
4191 nt_errstr(status));
4192 return false;
4196 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4197 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4198 printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
4199 nt_errstr(status));
4200 return false;
4202 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4204 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4205 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4207 printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
4208 nt_errstr(status));
4209 return false;
4211 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4213 if (!NT_STATUS_IS_OK(status)) {
4214 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4215 return false;
4218 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4219 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4220 ret = false;
4223 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4224 ret = false;
4227 return ret;
4232 its not totally clear what this does. It seems to accept any sid you like.
4234 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
4235 TALLOC_CTX *mem_ctx,
4236 struct policy_handle *domain_handle)
4238 NTSTATUS status;
4239 struct samr_RemoveMemberFromForeignDomain r;
4241 r.in.domain_handle = domain_handle;
4242 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4244 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4245 if (!NT_STATUS_IS_OK(status)) {
4246 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4247 return false;
4250 return true;
4255 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4256 struct policy_handle *handle);
4258 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4259 struct policy_handle *handle, struct dom_sid *sid,
4260 enum torture_samr_choice which_ops)
4262 NTSTATUS status;
4263 struct samr_OpenDomain r;
4264 struct policy_handle domain_handle;
4265 struct policy_handle alias_handle;
4266 struct policy_handle user_handle;
4267 struct policy_handle group_handle;
4268 bool ret = true;
4270 ZERO_STRUCT(alias_handle);
4271 ZERO_STRUCT(user_handle);
4272 ZERO_STRUCT(group_handle);
4273 ZERO_STRUCT(domain_handle);
4275 printf("Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4277 r.in.connect_handle = handle;
4278 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4279 r.in.sid = sid;
4280 r.out.domain_handle = &domain_handle;
4282 status = dcerpc_samr_OpenDomain(p, tctx, &r);
4283 if (!NT_STATUS_IS_OK(status)) {
4284 printf("OpenDomain failed - %s\n", nt_errstr(status));
4285 return false;
4288 /* run the domain tests with the main handle closed - this tests
4289 the servers reference counting */
4290 ret &= test_samr_handle_Close(p, tctx, handle);
4292 switch (which_ops) {
4293 case TORTURE_SAMR_USER_ATTRIBUTES:
4294 case TORTURE_SAMR_PASSWORDS:
4295 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4296 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4297 /* This test needs 'complex' users to validate */
4298 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4299 if (!ret) {
4300 printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4302 break;
4303 case TORTURE_SAMR_OTHER:
4304 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4305 if (!ret) {
4306 printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4308 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4309 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4310 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4311 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4312 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4313 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4314 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4315 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4316 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4317 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4318 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4319 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4320 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4322 if (torture_setting_bool(tctx, "samba4", false)) {
4323 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4324 } else {
4325 ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4326 ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4328 ret &= test_GroupList(p, tctx, &domain_handle);
4329 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4330 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4331 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4332 if (!ret) {
4333 printf("Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4335 break;
4338 if (!policy_handle_empty(&user_handle) &&
4339 !test_DeleteUser(p, tctx, &user_handle)) {
4340 ret = false;
4343 if (!policy_handle_empty(&alias_handle) &&
4344 !test_DeleteAlias(p, tctx, &alias_handle)) {
4345 ret = false;
4348 if (!policy_handle_empty(&group_handle) &&
4349 !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4350 ret = false;
4353 ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4355 /* reconnect the main handle */
4356 ret &= test_Connect(p, tctx, handle);
4358 if (!ret) {
4359 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4362 return ret;
4365 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4366 struct policy_handle *handle, const char *domain,
4367 enum torture_samr_choice which_ops)
4369 NTSTATUS status;
4370 struct samr_LookupDomain r;
4371 struct lsa_String n1;
4372 struct lsa_String n2;
4373 bool ret = true;
4375 printf("Testing LookupDomain(%s)\n", domain);
4377 /* check for correct error codes */
4378 r.in.connect_handle = handle;
4379 r.in.domain_name = &n2;
4380 n2.string = NULL;
4382 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4383 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4384 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4385 ret = false;
4388 init_lsa_String(&n2, "xxNODOMAINxx");
4390 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4391 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4392 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4393 ret = false;
4396 r.in.connect_handle = handle;
4398 init_lsa_String(&n1, domain);
4399 r.in.domain_name = &n1;
4401 status = dcerpc_samr_LookupDomain(p, tctx, &r);
4402 if (!NT_STATUS_IS_OK(status)) {
4403 printf("LookupDomain failed - %s\n", nt_errstr(status));
4404 ret = false;
4407 if (!test_GetDomPwInfo(p, tctx, &n1)) {
4408 ret = false;
4411 if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4412 ret = false;
4415 return ret;
4419 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4420 struct policy_handle *handle, enum torture_samr_choice which_ops)
4422 NTSTATUS status;
4423 struct samr_EnumDomains r;
4424 uint32_t resume_handle = 0;
4425 int i;
4426 bool ret = true;
4428 r.in.connect_handle = handle;
4429 r.in.resume_handle = &resume_handle;
4430 r.in.buf_size = (uint32_t)-1;
4431 r.out.resume_handle = &resume_handle;
4433 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4434 if (!NT_STATUS_IS_OK(status)) {
4435 printf("EnumDomains failed - %s\n", nt_errstr(status));
4436 return false;
4439 if (!r.out.sam) {
4440 return false;
4443 for (i=0;i<r.out.sam->count;i++) {
4444 if (!test_LookupDomain(p, tctx, handle,
4445 r.out.sam->entries[i].name.string, which_ops)) {
4446 ret = false;
4450 status = dcerpc_samr_EnumDomains(p, tctx, &r);
4451 if (!NT_STATUS_IS_OK(status)) {
4452 printf("EnumDomains failed - %s\n", nt_errstr(status));
4453 return false;
4456 return ret;
4460 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4461 struct policy_handle *handle)
4463 NTSTATUS status;
4464 struct samr_Connect r;
4465 struct samr_Connect2 r2;
4466 struct samr_Connect3 r3;
4467 struct samr_Connect4 r4;
4468 struct samr_Connect5 r5;
4469 union samr_ConnectInfo info;
4470 struct policy_handle h;
4471 bool ret = true, got_handle = false;
4473 printf("testing samr_Connect\n");
4475 r.in.system_name = 0;
4476 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4477 r.out.connect_handle = &h;
4479 status = dcerpc_samr_Connect(p, mem_ctx, &r);
4480 if (!NT_STATUS_IS_OK(status)) {
4481 printf("Connect failed - %s\n", nt_errstr(status));
4482 ret = false;
4483 } else {
4484 got_handle = true;
4485 *handle = h;
4488 printf("testing samr_Connect2\n");
4490 r2.in.system_name = NULL;
4491 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4492 r2.out.connect_handle = &h;
4494 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4495 if (!NT_STATUS_IS_OK(status)) {
4496 printf("Connect2 failed - %s\n", nt_errstr(status));
4497 ret = false;
4498 } else {
4499 if (got_handle) {
4500 test_samr_handle_Close(p, mem_ctx, handle);
4502 got_handle = true;
4503 *handle = h;
4506 printf("testing samr_Connect3\n");
4508 r3.in.system_name = NULL;
4509 r3.in.unknown = 0;
4510 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4511 r3.out.connect_handle = &h;
4513 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4514 if (!NT_STATUS_IS_OK(status)) {
4515 printf("Connect3 failed - %s\n", nt_errstr(status));
4516 ret = false;
4517 } else {
4518 if (got_handle) {
4519 test_samr_handle_Close(p, mem_ctx, handle);
4521 got_handle = true;
4522 *handle = h;
4525 printf("testing samr_Connect4\n");
4527 r4.in.system_name = "";
4528 r4.in.unknown = 0;
4529 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4530 r4.out.connect_handle = &h;
4532 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4533 if (!NT_STATUS_IS_OK(status)) {
4534 printf("Connect4 failed - %s\n", nt_errstr(status));
4535 ret = false;
4536 } else {
4537 if (got_handle) {
4538 test_samr_handle_Close(p, mem_ctx, handle);
4540 got_handle = true;
4541 *handle = h;
4544 printf("testing samr_Connect5\n");
4546 info.info1.unknown1 = 0;
4547 info.info1.unknown2 = 0;
4549 r5.in.system_name = "";
4550 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4551 r5.in.level = 1;
4552 r5.in.info = &info;
4553 r5.out.info = &info;
4554 r5.out.connect_handle = &h;
4556 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4557 if (!NT_STATUS_IS_OK(status)) {
4558 printf("Connect5 failed - %s\n", nt_errstr(status));
4559 ret = false;
4560 } else {
4561 if (got_handle) {
4562 test_samr_handle_Close(p, mem_ctx, handle);
4564 got_handle = true;
4565 *handle = h;
4568 return ret;
4572 bool torture_rpc_samr(struct torture_context *torture)
4574 NTSTATUS status;
4575 struct dcerpc_pipe *p;
4576 bool ret = true;
4577 struct policy_handle handle;
4579 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4580 if (!NT_STATUS_IS_OK(status)) {
4581 return false;
4584 ret &= test_Connect(p, torture, &handle);
4586 ret &= test_QuerySecurity(p, torture, &handle);
4588 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4590 ret &= test_SetDsrmPassword(p, torture, &handle);
4592 ret &= test_Shutdown(p, torture, &handle);
4594 ret &= test_samr_handle_Close(p, torture, &handle);
4596 return ret;
4600 bool torture_rpc_samr_users(struct torture_context *torture)
4602 NTSTATUS status;
4603 struct dcerpc_pipe *p;
4604 bool ret = true;
4605 struct policy_handle handle;
4607 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4608 if (!NT_STATUS_IS_OK(status)) {
4609 return false;
4612 ret &= test_Connect(p, torture, &handle);
4614 ret &= test_QuerySecurity(p, torture, &handle);
4616 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4618 ret &= test_SetDsrmPassword(p, torture, &handle);
4620 ret &= test_Shutdown(p, torture, &handle);
4622 ret &= test_samr_handle_Close(p, torture, &handle);
4624 return ret;
4628 bool torture_rpc_samr_passwords(struct torture_context *torture)
4630 NTSTATUS status;
4631 struct dcerpc_pipe *p;
4632 bool ret = true;
4633 struct policy_handle handle;
4635 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4636 if (!NT_STATUS_IS_OK(status)) {
4637 return false;
4640 ret &= test_Connect(p, torture, &handle);
4642 ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4644 ret &= test_samr_handle_Close(p, torture, &handle);
4646 return ret;