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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "librpc/gen_ndr/ndr_security.h"
29 #include "lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
34 #define TEST_ACCOUNT_NAME "samrtorturetest"
35 #define TEST_ALIASNAME "samrtorturetestalias"
36 #define TEST_GROUPNAME "samrtorturetestgroup"
37 #define TEST_MACHINENAME "samrtestmach$"
38 #define TEST_DOMAINNAME "samrtestdom$"
41 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
42 struct policy_handle *handle);
44 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static void init_lsa_String(struct lsa_String *string, const char *s)
55 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
56 struct policy_handle *handle)
62 r.out.handle = handle;
64 status = dcerpc_samr_Close(p, mem_ctx, &r);
65 if (!NT_STATUS_IS_OK(status)) {
66 printf("Close handle failed - %s\n", nt_errstr(status));
73 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
74 struct policy_handle *handle)
77 struct samr_Shutdown r;
79 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
80 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
84 r.in.connect_handle = handle;
86 printf("testing samr_Shutdown\n");
88 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
89 if (!NT_STATUS_IS_OK(status)) {
90 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
97 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
98 struct policy_handle *handle)
101 struct samr_SetDsrmPassword r;
102 struct lsa_String string;
103 struct samr_Password hash;
105 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
106 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
110 E_md4hash("TeSTDSRM123", hash.hash);
112 init_lsa_String(&string, "Administrator");
118 printf("testing samr_SetDsrmPassword\n");
120 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
121 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
122 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
130 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
131 struct policy_handle *handle)
134 struct samr_QuerySecurity r;
135 struct samr_SetSecurity s;
137 r.in.handle = handle;
140 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
141 if (!NT_STATUS_IS_OK(status)) {
142 printf("QuerySecurity failed - %s\n", nt_errstr(status));
146 if (r.out.sdbuf == NULL) {
150 s.in.handle = handle;
152 s.in.sdbuf = r.out.sdbuf;
154 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
155 if (!NT_STATUS_IS_OK(status)) {
156 printf("SetSecurity failed - %s\n", nt_errstr(status));
160 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
161 if (!NT_STATUS_IS_OK(status)) {
162 printf("QuerySecurity failed - %s\n", nt_errstr(status));
170 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
171 struct policy_handle *handle, uint32_t base_acct_flags,
172 const char *base_account_name)
175 struct samr_SetUserInfo s;
176 struct samr_SetUserInfo2 s2;
177 struct samr_QueryUserInfo q;
178 struct samr_QueryUserInfo q0;
179 union samr_UserInfo u;
181 const char *test_account_name;
183 uint32_t user_extra_flags = 0;
184 if (base_acct_flags == ACB_NORMAL) {
185 /* When created, accounts are expired by default */
186 user_extra_flags = ACB_PW_EXPIRED;
189 s.in.user_handle = handle;
192 s2.in.user_handle = handle;
195 q.in.user_handle = handle;
199 #define TESTCALL(call, r) \
200 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
201 if (!NT_STATUS_IS_OK(status)) { \
202 printf(#call " level %u failed - %s (%s)\n", \
203 r.in.level, nt_errstr(status), __location__); \
208 #define STRING_EQUAL(s1, s2, field) \
209 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
210 printf("Failed to set %s to '%s' (%s)\n", \
211 #field, s2, __location__); \
216 #define INT_EQUAL(i1, i2, field) \
218 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
219 #field, i2, i1, __location__); \
224 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
225 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
227 TESTCALL(QueryUserInfo, q) \
229 s2.in.level = lvl1; \
232 ZERO_STRUCT(u.info21); \
233 u.info21.fields_present = fpval; \
235 init_lsa_String(&u.info ## lvl1.field1, value); \
236 TESTCALL(SetUserInfo, s) \
237 TESTCALL(SetUserInfo2, s2) \
238 init_lsa_String(&u.info ## lvl1.field1, ""); \
239 TESTCALL(QueryUserInfo, q); \
241 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
243 TESTCALL(QueryUserInfo, q) \
245 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
248 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
249 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
251 TESTCALL(QueryUserInfo, q) \
253 s2.in.level = lvl1; \
256 uint8_t *bits = u.info21.logon_hours.bits; \
257 ZERO_STRUCT(u.info21); \
258 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
259 u.info21.logon_hours.units_per_week = 168; \
260 u.info21.logon_hours.bits = bits; \
262 u.info21.fields_present = fpval; \
264 u.info ## lvl1.field1 = value; \
265 TESTCALL(SetUserInfo, s) \
266 TESTCALL(SetUserInfo2, s2) \
267 u.info ## lvl1.field1 = 0; \
268 TESTCALL(QueryUserInfo, q); \
270 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
272 TESTCALL(QueryUserInfo, q) \
274 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
277 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
278 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
282 do { TESTCALL(QueryUserInfo, q0) } while (0);
284 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
285 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
286 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
289 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
290 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
291 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
292 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
293 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
294 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
295 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
296 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
297 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
298 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
299 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
300 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
301 test_account_name = base_account_name;
302 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
303 SAMR_FIELD_ACCOUNT_NAME);
305 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
306 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
307 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
308 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
309 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
310 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
311 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
312 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
313 SAMR_FIELD_FULL_NAME);
315 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
316 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
317 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
318 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
319 SAMR_FIELD_LOGON_SCRIPT);
321 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
322 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
323 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
324 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
325 SAMR_FIELD_PROFILE_PATH);
327 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
328 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
329 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
330 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
331 SAMR_FIELD_DESCRIPTION);
333 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
334 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
335 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
336 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
337 SAMR_FIELD_WORKSTATIONS);
339 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
340 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
341 SAMR_FIELD_PARAMETERS);
343 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
344 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
345 SAMR_FIELD_COUNTRY_CODE);
347 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
348 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
349 SAMR_FIELD_CODE_PAGE);
351 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
352 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
353 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
354 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
355 SAMR_FIELD_LOGON_HOURS);
357 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
358 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
359 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
361 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
362 (base_acct_flags | ACB_DISABLED),
363 (base_acct_flags | ACB_DISABLED | user_extra_flags),
366 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
367 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
368 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
369 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
371 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
372 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
373 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
376 /* The 'autolock' flag doesn't stick - check this */
377 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
378 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
379 (base_acct_flags | ACB_DISABLED | user_extra_flags),
382 /* The 'store plaintext' flag does stick */
383 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
384 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
385 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
387 /* The 'use DES' flag does stick */
388 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
389 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
390 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
392 /* The 'don't require kerberos pre-authentication flag does stick */
393 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
394 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
395 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
397 /* The 'no kerberos PAC required' flag sticks */
398 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
399 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
400 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
403 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
404 (base_acct_flags | ACB_DISABLED),
405 (base_acct_flags | ACB_DISABLED | user_extra_flags),
406 SAMR_FIELD_ACCT_FLAGS);
409 /* these fail with win2003 - it appears you can't set the primary gid?
410 the set succeeds, but the gid isn't changed. Very weird! */
411 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
412 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
413 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
414 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
421 generate a random password for password change tests
423 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
425 size_t len = MAX(8, min_len) + (random() % 6);
426 char *s = generate_random_str(mem_ctx, len);
427 printf("Generated password '%s'\n", s);
431 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
432 struct policy_handle *handle, char **password)
435 struct samr_SetUserInfo s;
436 union samr_UserInfo u;
438 DATA_BLOB session_key;
440 struct samr_GetUserPwInfo pwp;
441 int policy_min_pw_len = 0;
442 pwp.in.user_handle = handle;
444 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
445 if (NT_STATUS_IS_OK(status)) {
446 policy_min_pw_len = pwp.out.info.min_password_length;
448 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
450 s.in.user_handle = handle;
454 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
455 /* w2k3 ignores this length */
456 u.info24.pw_len = strlen_m(newpass) * 2;
458 status = dcerpc_fetch_session_key(p, &session_key);
459 if (!NT_STATUS_IS_OK(status)) {
460 printf("SetUserInfo level %u - no session key - %s\n",
461 s.in.level, nt_errstr(status));
465 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
467 printf("Testing SetUserInfo level 24 (set password)\n");
469 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
470 if (!NT_STATUS_IS_OK(status)) {
471 printf("SetUserInfo level %u failed - %s\n",
472 s.in.level, nt_errstr(status));
482 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
483 struct policy_handle *handle, uint32_t fields_present,
487 struct samr_SetUserInfo s;
488 union samr_UserInfo u;
490 DATA_BLOB session_key;
492 struct samr_GetUserPwInfo pwp;
493 int policy_min_pw_len = 0;
494 pwp.in.user_handle = handle;
496 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
497 if (NT_STATUS_IS_OK(status)) {
498 policy_min_pw_len = pwp.out.info.min_password_length;
500 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
502 s.in.user_handle = handle;
508 u.info23.info.fields_present = fields_present;
510 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
512 status = dcerpc_fetch_session_key(p, &session_key);
513 if (!NT_STATUS_IS_OK(status)) {
514 printf("SetUserInfo level %u - no session key - %s\n",
515 s.in.level, nt_errstr(status));
519 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
521 printf("Testing SetUserInfo level 23 (set password)\n");
523 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
524 if (!NT_STATUS_IS_OK(status)) {
525 printf("SetUserInfo level %u failed - %s\n",
526 s.in.level, nt_errstr(status));
536 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
537 struct policy_handle *handle, char **password)
540 struct samr_SetUserInfo s;
541 union samr_UserInfo u;
543 DATA_BLOB session_key;
544 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
545 uint8_t confounder[16];
547 struct MD5Context ctx;
548 struct samr_GetUserPwInfo pwp;
549 int policy_min_pw_len = 0;
550 pwp.in.user_handle = handle;
552 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
553 if (NT_STATUS_IS_OK(status)) {
554 policy_min_pw_len = pwp.out.info.min_password_length;
556 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
558 s.in.user_handle = handle;
562 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
563 u.info26.pw_len = strlen(newpass);
565 status = dcerpc_fetch_session_key(p, &session_key);
566 if (!NT_STATUS_IS_OK(status)) {
567 printf("SetUserInfo level %u - no session key - %s\n",
568 s.in.level, nt_errstr(status));
572 generate_random_buffer((uint8_t *)confounder, 16);
575 MD5Update(&ctx, confounder, 16);
576 MD5Update(&ctx, session_key.data, session_key.length);
577 MD5Final(confounded_session_key.data, &ctx);
579 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
580 memcpy(&u.info26.password.data[516], confounder, 16);
582 printf("Testing SetUserInfo level 26 (set password ex)\n");
584 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
585 if (!NT_STATUS_IS_OK(status)) {
586 printf("SetUserInfo level %u failed - %s\n",
587 s.in.level, nt_errstr(status));
596 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
597 struct policy_handle *handle, uint32_t fields_present,
601 struct samr_SetUserInfo s;
602 union samr_UserInfo u;
604 DATA_BLOB session_key;
605 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
606 struct MD5Context ctx;
607 uint8_t confounder[16];
609 struct samr_GetUserPwInfo pwp;
610 int policy_min_pw_len = 0;
611 pwp.in.user_handle = handle;
613 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
614 if (NT_STATUS_IS_OK(status)) {
615 policy_min_pw_len = pwp.out.info.min_password_length;
617 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
619 s.in.user_handle = handle;
625 u.info25.info.fields_present = fields_present;
627 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
629 status = dcerpc_fetch_session_key(p, &session_key);
630 if (!NT_STATUS_IS_OK(status)) {
631 printf("SetUserInfo level %u - no session key - %s\n",
632 s.in.level, nt_errstr(status));
636 generate_random_buffer((uint8_t *)confounder, 16);
639 MD5Update(&ctx, confounder, 16);
640 MD5Update(&ctx, session_key.data, session_key.length);
641 MD5Final(confounded_session_key.data, &ctx);
643 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
644 memcpy(&u.info25.password.data[516], confounder, 16);
646 printf("Testing SetUserInfo level 25 (set password ex)\n");
648 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
649 if (!NT_STATUS_IS_OK(status)) {
650 printf("SetUserInfo level %u failed - %s\n",
651 s.in.level, nt_errstr(status));
660 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
661 struct policy_handle *handle)
664 struct samr_SetAliasInfo r;
665 struct samr_QueryAliasInfo q;
666 uint16_t levels[] = {2, 3};
670 /* Ignoring switch level 1, as that includes the number of members for the alias
671 * and setting this to a wrong value might have negative consequences
674 for (i=0;i<ARRAY_SIZE(levels);i++) {
675 printf("Testing SetAliasInfo level %u\n", levels[i]);
677 r.in.alias_handle = handle;
678 r.in.level = levels[i];
679 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
680 switch (r.in.level) {
681 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
682 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
683 "Test Description, should test I18N as well"); break;
686 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
687 if (!NT_STATUS_IS_OK(status)) {
688 printf("SetAliasInfo level %u failed - %s\n",
689 levels[i], nt_errstr(status));
693 q.in.alias_handle = handle;
694 q.in.level = levels[i];
696 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
697 if (!NT_STATUS_IS_OK(status)) {
698 printf("QueryAliasInfo level %u failed - %s\n",
699 levels[i], nt_errstr(status));
707 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
708 struct policy_handle *user_handle)
710 struct samr_GetGroupsForUser r;
714 printf("testing GetGroupsForUser\n");
716 r.in.user_handle = user_handle;
718 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
719 if (!NT_STATUS_IS_OK(status)) {
720 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
728 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
729 struct lsa_String *domain_name)
732 struct samr_GetDomPwInfo r;
735 r.in.domain_name = domain_name;
736 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
738 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
739 if (!NT_STATUS_IS_OK(status)) {
740 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
744 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
745 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
747 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
748 if (!NT_STATUS_IS_OK(status)) {
749 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
753 r.in.domain_name->string = "\\\\__NONAME__";
754 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
756 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
757 if (!NT_STATUS_IS_OK(status)) {
758 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
762 r.in.domain_name->string = "\\\\Builtin";
763 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
765 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
766 if (!NT_STATUS_IS_OK(status)) {
767 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
775 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
776 struct policy_handle *handle)
779 struct samr_GetUserPwInfo r;
782 printf("Testing GetUserPwInfo\n");
784 r.in.user_handle = handle;
786 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
787 if (!NT_STATUS_IS_OK(status)) {
788 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
795 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
796 struct policy_handle *domain_handle, const char *name,
800 struct samr_LookupNames n;
801 struct lsa_String sname[2];
803 init_lsa_String(&sname[0], name);
805 n.in.domain_handle = domain_handle;
808 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
809 if (NT_STATUS_IS_OK(status)) {
810 *rid = n.out.rids.ids[0];
815 init_lsa_String(&sname[1], "xxNONAMExx");
817 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
818 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
819 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
823 init_lsa_String(&sname[1], "xxNONAMExx");
825 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
826 if (!NT_STATUS_IS_OK(status)) {
827 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
833 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
834 struct policy_handle *domain_handle,
835 const char *name, struct policy_handle *user_handle)
838 struct samr_OpenUser r;
841 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
842 if (!NT_STATUS_IS_OK(status)) {
846 r.in.domain_handle = domain_handle;
847 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
849 r.out.user_handle = user_handle;
850 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
851 if (!NT_STATUS_IS_OK(status)) {
852 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
859 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
860 struct policy_handle *handle)
863 struct samr_ChangePasswordUser r;
865 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
866 struct policy_handle user_handle;
867 char *oldpass = "test";
868 char *newpass = "test2";
869 uint8_t old_nt_hash[16], new_nt_hash[16];
870 uint8_t old_lm_hash[16], new_lm_hash[16];
872 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
873 if (!NT_STATUS_IS_OK(status)) {
877 printf("Testing ChangePasswordUser for user 'testuser'\n");
879 printf("old password: %s\n", oldpass);
880 printf("new password: %s\n", newpass);
882 E_md4hash(oldpass, old_nt_hash);
883 E_md4hash(newpass, new_nt_hash);
884 E_deshash(oldpass, old_lm_hash);
885 E_deshash(newpass, new_lm_hash);
887 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
888 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
889 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
890 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
891 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
892 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
894 r.in.handle = &user_handle;
896 r.in.old_lm_crypted = &hash1;
897 r.in.new_lm_crypted = &hash2;
899 r.in.old_nt_crypted = &hash3;
900 r.in.new_nt_crypted = &hash4;
901 r.in.cross1_present = 1;
902 r.in.nt_cross = &hash5;
903 r.in.cross2_present = 1;
904 r.in.lm_cross = &hash6;
906 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
907 if (!NT_STATUS_IS_OK(status)) {
908 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
912 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
920 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
921 struct policy_handle *handle, char **password)
924 struct samr_ChangePasswordUser r;
926 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
927 struct policy_handle user_handle;
928 char *oldpass = *password;
929 uint8_t old_nt_hash[16], new_nt_hash[16];
930 uint8_t old_lm_hash[16], new_lm_hash[16];
933 struct samr_GetUserPwInfo pwp;
934 int policy_min_pw_len = 0;
936 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
937 if (!NT_STATUS_IS_OK(status)) {
940 pwp.in.user_handle = &user_handle;
942 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
943 if (NT_STATUS_IS_OK(status)) {
944 policy_min_pw_len = pwp.out.info.min_password_length;
946 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
948 printf("Testing ChangePasswordUser\n");
950 E_md4hash(oldpass, old_nt_hash);
951 E_md4hash(newpass, new_nt_hash);
952 E_deshash(oldpass, old_lm_hash);
953 E_deshash(newpass, new_lm_hash);
955 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
956 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
957 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
958 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
959 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
960 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
962 r.in.user_handle = &user_handle;
964 r.in.old_lm_crypted = &hash1;
965 r.in.new_lm_crypted = &hash2;
967 r.in.old_nt_crypted = &hash3;
968 r.in.new_nt_crypted = &hash4;
969 r.in.cross1_present = 1;
970 r.in.nt_cross = &hash5;
971 r.in.cross2_present = 1;
972 r.in.lm_cross = &hash6;
974 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
975 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
976 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
977 } else if (!NT_STATUS_IS_OK(status)) {
978 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
984 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
992 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
993 struct policy_handle *handle, char **password)
996 struct samr_OemChangePasswordUser2 r;
998 struct samr_Password lm_verifier;
999 struct samr_CryptPassword lm_pass;
1000 struct lsa_AsciiString server, account, account_bad;
1001 char *oldpass = *password;
1003 uint8_t old_lm_hash[16], new_lm_hash[16];
1005 struct samr_GetDomPwInfo dom_pw_info;
1006 int policy_min_pw_len = 0;
1008 struct lsa_String domain_name;
1009 domain_name.string = "";
1010 dom_pw_info.in.domain_name = &domain_name;
1012 printf("Testing OemChangePasswordUser2\n");
1014 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1015 if (NT_STATUS_IS_OK(status)) {
1016 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1019 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1021 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1022 account.string = TEST_ACCOUNT_NAME;
1024 E_deshash(oldpass, old_lm_hash);
1025 E_deshash(newpass, new_lm_hash);
1027 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1028 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1029 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1031 r.in.server = &server;
1032 r.in.account = &account;
1033 r.in.password = &lm_pass;
1034 r.in.hash = &lm_verifier;
1036 /* Break the verification */
1037 lm_verifier.hash[0]++;
1039 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1041 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1042 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1043 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1048 /* This shouldn't be a valid name */
1049 account_bad.string = TEST_ACCOUNT_NAME "XX";
1050 r.in.account = &account_bad;
1052 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1054 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1055 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1060 E_deshash(oldpass, old_lm_hash);
1061 E_deshash(newpass, new_lm_hash);
1063 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1064 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1065 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1067 r.in.server = &server;
1068 r.in.account = &account;
1069 r.in.password = &lm_pass;
1070 r.in.hash = &lm_verifier;
1072 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1073 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1074 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1075 } else if (!NT_STATUS_IS_OK(status)) {
1076 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1079 *password = newpass;
1086 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1087 struct policy_handle *handle, char **password)
1090 struct samr_ChangePasswordUser2 r;
1092 struct lsa_String server, account;
1093 struct samr_CryptPassword nt_pass, lm_pass;
1094 struct samr_Password nt_verifier, lm_verifier;
1095 char *oldpass = *password;
1097 uint8_t old_nt_hash[16], new_nt_hash[16];
1098 uint8_t old_lm_hash[16], new_lm_hash[16];
1100 struct samr_GetDomPwInfo dom_pw_info;
1101 int policy_min_pw_len = 0;
1103 struct lsa_String domain_name;
1104 domain_name.string = "";
1105 dom_pw_info.in.domain_name = &domain_name;
1107 printf("Testing ChangePasswordUser2\n");
1109 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1110 if (NT_STATUS_IS_OK(status)) {
1111 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1114 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1116 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1117 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1119 E_md4hash(oldpass, old_nt_hash);
1120 E_md4hash(newpass, new_nt_hash);
1122 E_deshash(oldpass, old_lm_hash);
1123 E_deshash(newpass, new_lm_hash);
1125 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1126 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1127 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1129 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1130 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1131 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1133 r.in.server = &server;
1134 r.in.account = &account;
1135 r.in.nt_password = &nt_pass;
1136 r.in.nt_verifier = &nt_verifier;
1138 r.in.lm_password = &lm_pass;
1139 r.in.lm_verifier = &lm_verifier;
1141 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1142 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1143 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1144 } else if (!NT_STATUS_IS_OK(status)) {
1145 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1148 *password = newpass;
1155 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1156 const char *account_string,
1157 int policy_min_pw_len,
1161 struct samr_ChangePasswordUser3 r;
1163 struct lsa_String server, account, account_bad;
1164 struct samr_CryptPassword nt_pass, lm_pass;
1165 struct samr_Password nt_verifier, lm_verifier;
1166 char *oldpass = *password;
1167 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1168 uint8_t old_nt_hash[16], new_nt_hash[16];
1169 uint8_t old_lm_hash[16], new_lm_hash[16];
1171 printf("Testing ChangePasswordUser3\n");
1173 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1174 init_lsa_String(&account, account_string);
1176 E_md4hash(oldpass, old_nt_hash);
1177 E_md4hash(newpass, new_nt_hash);
1179 E_deshash(oldpass, old_lm_hash);
1180 E_deshash(newpass, new_lm_hash);
1182 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1183 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1184 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1186 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1187 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1188 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1190 /* Break the verification */
1191 nt_verifier.hash[0]++;
1193 r.in.server = &server;
1194 r.in.account = &account;
1195 r.in.nt_password = &nt_pass;
1196 r.in.nt_verifier = &nt_verifier;
1198 r.in.lm_password = &lm_pass;
1199 r.in.lm_verifier = &lm_verifier;
1200 r.in.password3 = NULL;
1202 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1203 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1204 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1205 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1210 /* This shouldn't be a valid name */
1211 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1213 r.in.account = &account_bad;
1214 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1215 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1216 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1221 E_md4hash(oldpass, old_nt_hash);
1222 E_md4hash(newpass, new_nt_hash);
1224 E_deshash(oldpass, old_lm_hash);
1225 E_deshash(newpass, new_lm_hash);
1227 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1228 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1229 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1231 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1232 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1233 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1235 r.in.server = &server;
1236 r.in.account = &account;
1237 r.in.nt_password = &nt_pass;
1238 r.in.nt_verifier = &nt_verifier;
1240 r.in.lm_password = &lm_pass;
1241 r.in.lm_verifier = &lm_verifier;
1242 r.in.password3 = NULL;
1244 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1245 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1246 && !policy_min_pw_len) {
1247 if (r.out.dominfo) {
1248 policy_min_pw_len = r.out.dominfo->min_password_length;
1250 if (policy_min_pw_len) /* try again with the right min password length */ {
1251 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1253 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1256 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1257 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1258 } else if (!NT_STATUS_IS_OK(status)) {
1259 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1262 *password = newpass;
1269 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1270 struct policy_handle *alias_handle)
1272 struct samr_GetMembersInAlias r;
1273 struct lsa_SidArray sids;
1277 printf("Testing GetMembersInAlias\n");
1279 r.in.alias_handle = alias_handle;
1282 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 printf("GetMembersInAlias failed - %s\n",
1292 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1293 struct policy_handle *alias_handle,
1294 const struct dom_sid *domain_sid)
1296 struct samr_AddAliasMember r;
1297 struct samr_DeleteAliasMember d;
1300 struct dom_sid *sid;
1302 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1304 printf("testing AddAliasMember\n");
1305 r.in.alias_handle = alias_handle;
1308 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1309 if (!NT_STATUS_IS_OK(status)) {
1310 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1314 d.in.alias_handle = alias_handle;
1317 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1318 if (!NT_STATUS_IS_OK(status)) {
1319 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1326 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1327 struct policy_handle *alias_handle)
1329 struct samr_AddMultipleMembersToAlias a;
1330 struct samr_RemoveMultipleMembersFromAlias r;
1333 struct lsa_SidArray sids;
1335 printf("testing AddMultipleMembersToAlias\n");
1336 a.in.alias_handle = alias_handle;
1340 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1342 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1343 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1344 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1346 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1347 if (!NT_STATUS_IS_OK(status)) {
1348 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1353 printf("testing RemoveMultipleMembersFromAlias\n");
1354 r.in.alias_handle = alias_handle;
1357 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1358 if (!NT_STATUS_IS_OK(status)) {
1359 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1363 /* strange! removing twice doesn't give any error */
1364 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1365 if (!NT_STATUS_IS_OK(status)) {
1366 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1370 /* but removing an alias that isn't there does */
1371 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1373 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1374 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1375 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1382 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1383 struct policy_handle *user_handle)
1385 struct samr_TestPrivateFunctionsUser r;
1389 printf("Testing TestPrivateFunctionsUser\n");
1391 r.in.user_handle = user_handle;
1393 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1394 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1395 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1403 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1404 struct policy_handle *handle, uint32_t base_acct_flags,
1405 const char *base_acct_name)
1409 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1413 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1417 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1421 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1426 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1430 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1437 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1438 struct policy_handle *alias_handle,
1439 const struct dom_sid *domain_sid)
1443 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1447 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1451 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1455 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1459 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1467 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1468 struct policy_handle *handle, const char *name)
1471 struct samr_DeleteUser d;
1472 struct policy_handle user_handle;
1475 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1476 if (!NT_STATUS_IS_OK(status)) {
1480 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1481 if (!NT_STATUS_IS_OK(status)) {
1485 d.in.user_handle = &user_handle;
1486 d.out.user_handle = &user_handle;
1487 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1488 if (!NT_STATUS_IS_OK(status)) {
1495 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1500 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1501 struct policy_handle *handle, const char *name)
1504 struct samr_OpenGroup r;
1505 struct samr_DeleteDomainGroup d;
1506 struct policy_handle group_handle;
1509 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1510 if (!NT_STATUS_IS_OK(status)) {
1514 r.in.domain_handle = handle;
1515 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1517 r.out.group_handle = &group_handle;
1518 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1519 if (!NT_STATUS_IS_OK(status)) {
1523 d.in.group_handle = &group_handle;
1524 d.out.group_handle = &group_handle;
1525 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1526 if (!NT_STATUS_IS_OK(status)) {
1533 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1538 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1539 struct policy_handle *domain_handle, const char *name)
1542 struct samr_OpenAlias r;
1543 struct samr_DeleteDomAlias d;
1544 struct policy_handle alias_handle;
1547 printf("testing DeleteAlias_byname\n");
1549 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1550 if (!NT_STATUS_IS_OK(status)) {
1554 r.in.domain_handle = domain_handle;
1555 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1557 r.out.alias_handle = &alias_handle;
1558 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1559 if (!NT_STATUS_IS_OK(status)) {
1563 d.in.alias_handle = &alias_handle;
1564 d.out.alias_handle = &alias_handle;
1565 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1566 if (!NT_STATUS_IS_OK(status)) {
1573 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1577 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1578 struct policy_handle *alias_handle)
1580 struct samr_DeleteDomAlias d;
1583 printf("Testing DeleteAlias\n");
1585 d.in.alias_handle = alias_handle;
1586 d.out.alias_handle = alias_handle;
1588 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1589 if (!NT_STATUS_IS_OK(status)) {
1590 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1597 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1598 struct policy_handle *domain_handle,
1599 struct policy_handle *alias_handle,
1600 const struct dom_sid *domain_sid)
1603 struct samr_CreateDomAlias r;
1604 struct lsa_String name;
1608 init_lsa_String(&name, TEST_ALIASNAME);
1609 r.in.domain_handle = domain_handle;
1610 r.in.alias_name = &name;
1611 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1612 r.out.alias_handle = alias_handle;
1615 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1617 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1619 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1620 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1624 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1625 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1628 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1631 if (!NT_STATUS_IS_OK(status)) {
1632 printf("CreateAlias failed - %s\n", nt_errstr(status));
1636 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1643 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1644 struct policy_handle *domain_handle, char **password)
1652 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1656 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1660 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1664 /* we change passwords twice - this has the effect of verifying
1665 they were changed correctly for the final call */
1666 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1670 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1677 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1678 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1681 struct samr_CreateUser r;
1682 struct samr_QueryUserInfo q;
1684 char *password = NULL;
1687 const uint32_t password_fields[] = {
1688 SAMR_FIELD_PASSWORD,
1689 SAMR_FIELD_PASSWORD2,
1690 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1694 TALLOC_CTX *user_ctx;
1696 /* This call creates a 'normal' account - check that it really does */
1697 const uint32_t acct_flags = ACB_NORMAL;
1698 struct lsa_String name;
1701 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1702 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1704 r.in.domain_handle = domain_handle;
1705 r.in.account_name = &name;
1706 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1707 r.out.user_handle = user_handle;
1710 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1712 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1714 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1715 printf("Server refused create of '%s'\n", r.in.account_name->string);
1716 ZERO_STRUCTP(user_handle);
1717 talloc_free(user_ctx);
1721 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1722 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1723 talloc_free(user_ctx);
1726 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1728 if (!NT_STATUS_IS_OK(status)) {
1729 talloc_free(user_ctx);
1730 printf("CreateUser failed - %s\n", nt_errstr(status));
1734 q.in.user_handle = user_handle;
1737 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1738 if (!NT_STATUS_IS_OK(status)) {
1739 printf("QueryUserInfo level %u failed - %s\n",
1740 q.in.level, nt_errstr(status));
1743 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1744 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1745 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1746 acct_flags, acct_flags);
1751 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1755 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1759 for (i = 0; password_fields[i]; i++) {
1760 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1764 /* check it was set right */
1765 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1770 for (i = 0; password_fields[i]; i++) {
1771 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1775 /* check it was set right */
1776 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1781 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1785 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1789 talloc_free(user_ctx);
1795 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1796 struct policy_handle *user_handle)
1798 struct samr_DeleteUser d;
1802 printf("Testing DeleteUser\n");
1804 d.in.user_handle = user_handle;
1805 d.out.user_handle = user_handle;
1807 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1808 if (!NT_STATUS_IS_OK(status)) {
1809 printf("DeleteUser failed - %s\n", nt_errstr(status));
1816 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1817 struct policy_handle *handle)
1820 struct samr_CreateUser2 r;
1821 struct samr_QueryUserInfo q;
1822 struct samr_DeleteUser d;
1823 struct policy_handle user_handle;
1825 struct lsa_String name;
1830 uint32_t acct_flags;
1831 const char *account_name;
1833 } account_types[] = {
1834 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1835 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1836 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1837 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1838 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1839 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1840 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1841 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1842 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1843 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1844 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1845 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1846 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1847 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1848 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1851 for (i = 0; account_types[i].account_name; i++) {
1852 TALLOC_CTX *user_ctx;
1853 uint32_t acct_flags = account_types[i].acct_flags;
1854 uint32_t access_granted;
1855 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1856 init_lsa_String(&name, account_types[i].account_name);
1858 r.in.domain_handle = handle;
1859 r.in.account_name = &name;
1860 r.in.acct_flags = acct_flags;
1861 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1862 r.out.user_handle = &user_handle;
1863 r.out.access_granted = &access_granted;
1866 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1868 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1870 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1871 talloc_free(user_ctx);
1872 printf("Server refused create of '%s'\n", r.in.account_name->string);
1875 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1876 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1877 talloc_free(user_ctx);
1881 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1884 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1885 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1886 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1890 if (NT_STATUS_IS_OK(status)) {
1891 q.in.user_handle = &user_handle;
1894 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1895 if (!NT_STATUS_IS_OK(status)) {
1896 printf("QueryUserInfo level %u failed - %s\n",
1897 q.in.level, nt_errstr(status));
1900 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1901 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1902 q.out.info->info16.acct_flags,
1908 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1912 printf("Testing DeleteUser (createuser2 test)\n");
1914 d.in.user_handle = &user_handle;
1915 d.out.user_handle = &user_handle;
1917 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1918 if (!NT_STATUS_IS_OK(status)) {
1919 printf("DeleteUser failed - %s\n", nt_errstr(status));
1923 talloc_free(user_ctx);
1929 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1930 struct policy_handle *handle)
1933 struct samr_QueryAliasInfo r;
1934 uint16_t levels[] = {1, 2, 3};
1938 for (i=0;i<ARRAY_SIZE(levels);i++) {
1939 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1941 r.in.alias_handle = handle;
1942 r.in.level = levels[i];
1944 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1945 if (!NT_STATUS_IS_OK(status)) {
1946 printf("QueryAliasInfo level %u failed - %s\n",
1947 levels[i], nt_errstr(status));
1955 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1956 struct policy_handle *handle)
1959 struct samr_QueryGroupInfo r;
1960 uint16_t levels[] = {1, 2, 3, 4, 5};
1964 for (i=0;i<ARRAY_SIZE(levels);i++) {
1965 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1967 r.in.group_handle = handle;
1968 r.in.level = levels[i];
1970 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1971 if (!NT_STATUS_IS_OK(status)) {
1972 printf("QueryGroupInfo level %u failed - %s\n",
1973 levels[i], nt_errstr(status));
1981 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1982 struct policy_handle *handle)
1985 struct samr_QueryGroupMember r;
1988 printf("Testing QueryGroupMember\n");
1990 r.in.group_handle = handle;
1992 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1993 if (!NT_STATUS_IS_OK(status)) {
1994 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2002 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2003 struct policy_handle *handle)
2006 struct samr_QueryGroupInfo r;
2007 struct samr_SetGroupInfo s;
2008 uint16_t levels[] = {1, 2, 3, 4};
2009 uint16_t set_ok[] = {0, 1, 1, 1};
2013 for (i=0;i<ARRAY_SIZE(levels);i++) {
2014 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2016 r.in.group_handle = handle;
2017 r.in.level = levels[i];
2019 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2020 if (!NT_STATUS_IS_OK(status)) {
2021 printf("QueryGroupInfo level %u failed - %s\n",
2022 levels[i], nt_errstr(status));
2026 printf("Testing SetGroupInfo level %u\n", levels[i]);
2028 s.in.group_handle = handle;
2029 s.in.level = levels[i];
2030 s.in.info = r.out.info;
2033 /* disabled this, as it changes the name only from the point of view of samr,
2034 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2035 the name is still reserved, so creating the old name fails, but deleting by the old name
2037 if (s.in.level == 2) {
2038 init_lsa_String(&s.in.info->string, "NewName");
2042 if (s.in.level == 4) {
2043 init_lsa_String(&s.in.info->description, "test description");
2046 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2048 if (!NT_STATUS_IS_OK(status)) {
2049 printf("SetGroupInfo level %u failed - %s\n",
2050 r.in.level, nt_errstr(status));
2055 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2056 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2057 r.in.level, nt_errstr(status));
2067 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2068 struct policy_handle *handle)
2071 struct samr_QueryUserInfo r;
2072 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2073 11, 12, 13, 14, 16, 17, 20, 21};
2077 for (i=0;i<ARRAY_SIZE(levels);i++) {
2078 printf("Testing QueryUserInfo level %u\n", levels[i]);
2080 r.in.user_handle = handle;
2081 r.in.level = levels[i];
2083 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2084 if (!NT_STATUS_IS_OK(status)) {
2085 printf("QueryUserInfo level %u failed - %s\n",
2086 levels[i], nt_errstr(status));
2094 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2095 struct policy_handle *handle)
2098 struct samr_QueryUserInfo2 r;
2099 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2100 11, 12, 13, 14, 16, 17, 20, 21};
2104 for (i=0;i<ARRAY_SIZE(levels);i++) {
2105 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2107 r.in.user_handle = handle;
2108 r.in.level = levels[i];
2110 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2111 if (!NT_STATUS_IS_OK(status)) {
2112 printf("QueryUserInfo2 level %u failed - %s\n",
2113 levels[i], nt_errstr(status));
2121 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2122 struct policy_handle *handle, uint32_t rid)
2125 struct samr_OpenUser r;
2126 struct policy_handle user_handle;
2129 printf("Testing OpenUser(%u)\n", rid);
2131 r.in.domain_handle = handle;
2132 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2134 r.out.user_handle = &user_handle;
2136 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2137 if (!NT_STATUS_IS_OK(status)) {
2138 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2142 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2146 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2150 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2154 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2158 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2162 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2169 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2170 struct policy_handle *handle, uint32_t rid)
2173 struct samr_OpenGroup r;
2174 struct policy_handle group_handle;
2177 printf("Testing OpenGroup(%u)\n", rid);
2179 r.in.domain_handle = handle;
2180 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2182 r.out.group_handle = &group_handle;
2184 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2185 if (!NT_STATUS_IS_OK(status)) {
2186 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2190 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2194 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2198 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2202 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2209 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2210 struct policy_handle *handle, uint32_t rid)
2213 struct samr_OpenAlias r;
2214 struct policy_handle alias_handle;
2217 printf("Testing OpenAlias(%u)\n", rid);
2219 r.in.domain_handle = handle;
2220 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2222 r.out.alias_handle = &alias_handle;
2224 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2225 if (!NT_STATUS_IS_OK(status)) {
2226 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2230 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2234 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2238 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2242 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2249 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2250 struct policy_handle *handle)
2253 struct samr_EnumDomainUsers r;
2254 uint32_t resume_handle=0;
2257 struct samr_LookupNames n;
2258 struct samr_LookupRids lr ;
2260 printf("Testing EnumDomainUsers\n");
2262 r.in.domain_handle = handle;
2263 r.in.resume_handle = &resume_handle;
2264 r.in.acct_flags = 0;
2265 r.in.max_size = (uint32_t)-1;
2266 r.out.resume_handle = &resume_handle;
2268 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2269 if (!NT_STATUS_IS_OK(status)) {
2270 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2278 if (r.out.sam->count == 0) {
2282 for (i=0;i<r.out.sam->count;i++) {
2283 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2288 printf("Testing LookupNames\n");
2289 n.in.domain_handle = handle;
2290 n.in.num_names = r.out.sam->count;
2291 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2292 for (i=0;i<r.out.sam->count;i++) {
2293 n.in.names[i].string = r.out.sam->entries[i].name.string;
2295 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2296 if (!NT_STATUS_IS_OK(status)) {
2297 printf("LookupNames failed - %s\n", nt_errstr(status));
2302 printf("Testing LookupRids\n");
2303 lr.in.domain_handle = handle;
2304 lr.in.num_rids = r.out.sam->count;
2305 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2306 for (i=0;i<r.out.sam->count;i++) {
2307 lr.in.rids[i] = r.out.sam->entries[i].idx;
2309 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2310 if (!NT_STATUS_IS_OK(status)) {
2311 printf("LookupRids failed - %s\n", nt_errstr(status));
2319 try blasting the server with a bunch of sync requests
2321 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2322 struct policy_handle *handle)
2325 struct samr_EnumDomainUsers r;
2326 uint32_t resume_handle=0;
2328 #define ASYNC_COUNT 100
2329 struct rpc_request *req[ASYNC_COUNT];
2331 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2332 printf("samr async test disabled - enable dangerous tests to use\n");
2336 printf("Testing EnumDomainUsers_async\n");
2338 r.in.domain_handle = handle;
2339 r.in.resume_handle = &resume_handle;
2340 r.in.acct_flags = 0;
2341 r.in.max_size = (uint32_t)-1;
2342 r.out.resume_handle = &resume_handle;
2344 for (i=0;i<ASYNC_COUNT;i++) {
2345 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2348 for (i=0;i<ASYNC_COUNT;i++) {
2349 status = dcerpc_ndr_request_recv(req[i]);
2350 if (!NT_STATUS_IS_OK(status)) {
2351 printf("EnumDomainUsers[%d] failed - %s\n",
2352 i, nt_errstr(status));
2357 printf("%d async requests OK\n", i);
2362 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2363 struct policy_handle *handle)
2366 struct samr_EnumDomainGroups r;
2367 uint32_t resume_handle=0;
2371 printf("Testing EnumDomainGroups\n");
2373 r.in.domain_handle = handle;
2374 r.in.resume_handle = &resume_handle;
2375 r.in.max_size = (uint32_t)-1;
2376 r.out.resume_handle = &resume_handle;
2378 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2379 if (!NT_STATUS_IS_OK(status)) {
2380 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2388 for (i=0;i<r.out.sam->count;i++) {
2389 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2397 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2398 struct policy_handle *handle)
2401 struct samr_EnumDomainAliases r;
2402 uint32_t resume_handle=0;
2406 printf("Testing EnumDomainAliases\n");
2408 r.in.domain_handle = handle;
2409 r.in.resume_handle = &resume_handle;
2410 r.in.acct_flags = (uint32_t)-1;
2411 r.out.resume_handle = &resume_handle;
2413 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2414 if (!NT_STATUS_IS_OK(status)) {
2415 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2423 for (i=0;i<r.out.sam->count;i++) {
2424 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2432 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2433 struct policy_handle *handle)
2436 struct samr_GetDisplayEnumerationIndex r;
2438 uint16_t levels[] = {1, 2, 3, 4, 5};
2439 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2442 for (i=0;i<ARRAY_SIZE(levels);i++) {
2443 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2445 r.in.domain_handle = handle;
2446 r.in.level = levels[i];
2447 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2449 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2452 !NT_STATUS_IS_OK(status) &&
2453 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2454 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2455 levels[i], nt_errstr(status));
2459 init_lsa_String(&r.in.name, "zzzzzzzz");
2461 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2463 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2464 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2465 levels[i], nt_errstr(status));
2473 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2474 struct policy_handle *handle)
2477 struct samr_GetDisplayEnumerationIndex2 r;
2479 uint16_t levels[] = {1, 2, 3, 4, 5};
2480 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2483 for (i=0;i<ARRAY_SIZE(levels);i++) {
2484 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2486 r.in.domain_handle = handle;
2487 r.in.level = levels[i];
2488 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2490 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2492 !NT_STATUS_IS_OK(status) &&
2493 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2494 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2495 levels[i], nt_errstr(status));
2499 init_lsa_String(&r.in.name, "zzzzzzzz");
2501 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2502 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2503 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2504 levels[i], nt_errstr(status));
2512 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2513 struct policy_handle *handle)
2516 struct samr_QueryDisplayInfo r;
2518 uint16_t levels[] = {1, 2, 3, 4, 5};
2521 for (i=0;i<ARRAY_SIZE(levels);i++) {
2522 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2524 r.in.domain_handle = handle;
2525 r.in.level = levels[i];
2527 r.in.max_entries = 1000;
2528 r.in.buf_size = (uint32_t)-1;
2530 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2531 if (!NT_STATUS_IS_OK(status)) {
2532 printf("QueryDisplayInfo level %u failed - %s\n",
2533 levels[i], nt_errstr(status));
2541 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2542 struct policy_handle *handle)
2545 struct samr_QueryDisplayInfo2 r;
2547 uint16_t levels[] = {1, 2, 3, 4, 5};
2550 for (i=0;i<ARRAY_SIZE(levels);i++) {
2551 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2553 r.in.domain_handle = handle;
2554 r.in.level = levels[i];
2556 r.in.max_entries = 1000;
2557 r.in.buf_size = (uint32_t)-1;
2559 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 printf("QueryDisplayInfo2 level %u failed - %s\n",
2562 levels[i], nt_errstr(status));
2570 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2571 struct policy_handle *handle)
2574 struct samr_QueryDisplayInfo3 r;
2576 uint16_t levels[] = {1, 2, 3, 4, 5};
2579 for (i=0;i<ARRAY_SIZE(levels);i++) {
2580 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2582 r.in.domain_handle = handle;
2583 r.in.level = levels[i];
2585 r.in.max_entries = 1000;
2586 r.in.buf_size = (uint32_t)-1;
2588 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2589 if (!NT_STATUS_IS_OK(status)) {
2590 printf("QueryDisplayInfo3 level %u failed - %s\n",
2591 levels[i], nt_errstr(status));
2600 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2601 struct policy_handle *handle)
2604 struct samr_QueryDisplayInfo r;
2607 printf("Testing QueryDisplayInfo continuation\n");
2609 r.in.domain_handle = handle;
2612 r.in.max_entries = 1;
2613 r.in.buf_size = (uint32_t)-1;
2616 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2617 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2618 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2619 printf("expected idx %d but got %d\n",
2621 r.out.info.info1.entries[0].idx);
2625 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2626 !NT_STATUS_IS_OK(status)) {
2627 printf("QueryDisplayInfo level %u failed - %s\n",
2628 r.in.level, nt_errstr(status));
2633 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2634 NT_STATUS_IS_OK(status)) &&
2635 r.out.returned_size != 0);
2640 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2641 struct policy_handle *handle)
2644 struct samr_QueryDomainInfo r;
2645 struct samr_SetDomainInfo s;
2646 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2647 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2651 for (i=0;i<ARRAY_SIZE(levels);i++) {
2652 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2654 r.in.domain_handle = handle;
2655 r.in.level = levels[i];
2657 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2658 if (!NT_STATUS_IS_OK(status)) {
2659 printf("QueryDomainInfo level %u failed - %s\n",
2660 r.in.level, nt_errstr(status));
2665 printf("Testing SetDomainInfo level %u\n", levels[i]);
2667 s.in.domain_handle = handle;
2668 s.in.level = levels[i];
2669 s.in.info = r.out.info;
2671 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2673 if (!NT_STATUS_IS_OK(status)) {
2674 printf("SetDomainInfo level %u failed - %s\n",
2675 r.in.level, nt_errstr(status));
2680 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2681 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2682 r.in.level, nt_errstr(status));
2688 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2689 if (!NT_STATUS_IS_OK(status)) {
2690 printf("QueryDomainInfo level %u failed - %s\n",
2691 r.in.level, nt_errstr(status));
2701 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2702 struct policy_handle *handle)
2705 struct samr_QueryDomainInfo2 r;
2706 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2710 for (i=0;i<ARRAY_SIZE(levels);i++) {
2711 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2713 r.in.domain_handle = handle;
2714 r.in.level = levels[i];
2716 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2717 if (!NT_STATUS_IS_OK(status)) {
2718 printf("QueryDomainInfo2 level %u failed - %s\n",
2719 r.in.level, nt_errstr(status));
2728 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2729 set of group names. */
2730 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2731 struct policy_handle *handle)
2733 struct samr_EnumDomainGroups q1;
2734 struct samr_QueryDisplayInfo q2;
2736 uint32_t resume_handle=0;
2741 const char **names = NULL;
2743 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2745 q1.in.domain_handle = handle;
2746 q1.in.resume_handle = &resume_handle;
2748 q1.out.resume_handle = &resume_handle;
2750 status = STATUS_MORE_ENTRIES;
2751 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2752 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2754 if (!NT_STATUS_IS_OK(status) &&
2755 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2758 for (i=0; i<q1.out.num_entries; i++) {
2759 add_string_to_array(mem_ctx,
2760 q1.out.sam->entries[i].name.string,
2761 &names, &num_names);
2765 if (!NT_STATUS_IS_OK(status)) {
2766 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2774 q2.in.domain_handle = handle;
2776 q2.in.start_idx = 0;
2777 q2.in.max_entries = 5;
2778 q2.in.buf_size = (uint32_t)-1;
2780 status = STATUS_MORE_ENTRIES;
2781 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2782 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2784 if (!NT_STATUS_IS_OK(status) &&
2785 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2788 for (i=0; i<q2.out.info.info5.count; i++) {
2790 const char *name = q2.out.info.info5.entries[i].account_name.string;
2792 for (j=0; j<num_names; j++) {
2793 if (names[j] == NULL)
2795 /* Hmm. No strequal in samba4 */
2796 if (strequal(names[j], name)) {
2804 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2809 q2.in.start_idx += q2.out.info.info5.count;
2812 if (!NT_STATUS_IS_OK(status)) {
2813 printf("QueryDisplayInfo level 5 failed - %s\n",
2818 for (i=0; i<num_names; i++) {
2819 if (names[i] != NULL) {
2820 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2829 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2830 struct policy_handle *group_handle)
2832 struct samr_DeleteDomainGroup d;
2836 printf("Testing DeleteDomainGroup\n");
2838 d.in.group_handle = group_handle;
2839 d.out.group_handle = group_handle;
2841 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2850 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2851 struct policy_handle *domain_handle)
2853 struct samr_TestPrivateFunctionsDomain r;
2857 printf("Testing TestPrivateFunctionsDomain\n");
2859 r.in.domain_handle = domain_handle;
2861 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2862 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2863 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2870 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2871 struct dom_sid *domain_sid,
2872 struct policy_handle *domain_handle)
2874 struct samr_RidToSid r;
2877 struct dom_sid *calc_sid;
2878 int rids[] = { 0, 42, 512, 10200 };
2881 for (i=0;i<ARRAY_SIZE(rids);i++) {
2883 printf("Testing RidToSid\n");
2885 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2886 r.in.domain_handle = domain_handle;
2889 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2890 if (!NT_STATUS_IS_OK(status)) {
2891 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2894 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2896 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2897 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2898 dom_sid_string(mem_ctx, r.out.sid),
2899 dom_sid_string(mem_ctx, calc_sid));
2908 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2909 struct policy_handle *domain_handle)
2911 struct samr_GetBootKeyInformation r;
2915 printf("Testing GetBootKeyInformation\n");
2917 r.in.domain_handle = domain_handle;
2919 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2920 if (!NT_STATUS_IS_OK(status)) {
2921 /* w2k3 seems to fail this sometimes and pass it sometimes */
2922 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2928 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2929 struct policy_handle *domain_handle,
2930 struct policy_handle *group_handle)
2933 struct samr_AddGroupMember r;
2934 struct samr_DeleteGroupMember d;
2935 struct samr_QueryGroupMember q;
2936 struct samr_SetMemberAttributesOfGroup s;
2940 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2941 if (!NT_STATUS_IS_OK(status)) {
2945 r.in.group_handle = group_handle;
2947 r.in.flags = 0; /* ??? */
2949 printf("Testing AddGroupMember and DeleteGroupMember\n");
2951 d.in.group_handle = group_handle;
2954 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2955 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2956 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2961 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2962 if (!NT_STATUS_IS_OK(status)) {
2963 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2967 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2968 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2969 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2974 /* this one is quite strange. I am using random inputs in the
2975 hope of triggering an error that might give us a clue */
2976 s.in.group_handle = group_handle;
2977 s.in.unknown1 = random();
2978 s.in.unknown2 = random();
2980 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2981 if (!NT_STATUS_IS_OK(status)) {
2982 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2986 q.in.group_handle = group_handle;
2988 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2989 if (!NT_STATUS_IS_OK(status)) {
2990 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2994 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2995 if (!NT_STATUS_IS_OK(status)) {
2996 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
3000 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3001 if (!NT_STATUS_IS_OK(status)) {
3002 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3010 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3011 struct policy_handle *domain_handle, struct policy_handle *group_handle)
3014 struct samr_CreateDomainGroup r;
3016 struct lsa_String name;
3019 init_lsa_String(&name, TEST_GROUPNAME);
3021 r.in.domain_handle = domain_handle;
3023 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3024 r.out.group_handle = group_handle;
3027 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3029 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3031 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3032 printf("Server refused create of '%s'\n", r.in.name->string);
3033 ZERO_STRUCTP(group_handle);
3037 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3038 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3039 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3042 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3044 if (!NT_STATUS_IS_OK(status)) {
3045 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3049 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3053 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3062 its not totally clear what this does. It seems to accept any sid you like.
3064 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3065 TALLOC_CTX *mem_ctx,
3066 struct policy_handle *domain_handle)
3069 struct samr_RemoveMemberFromForeignDomain r;
3071 r.in.domain_handle = domain_handle;
3072 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3074 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3075 if (!NT_STATUS_IS_OK(status)) {
3076 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3085 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3086 struct policy_handle *handle);
3088 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3089 struct policy_handle *handle, struct dom_sid *sid)
3092 struct samr_OpenDomain r;
3093 struct policy_handle domain_handle;
3094 struct policy_handle user_handle;
3095 struct policy_handle alias_handle;
3096 struct policy_handle group_handle;
3099 ZERO_STRUCT(user_handle);
3100 ZERO_STRUCT(alias_handle);
3101 ZERO_STRUCT(group_handle);
3102 ZERO_STRUCT(domain_handle);
3104 printf("Testing OpenDomain\n");
3106 r.in.connect_handle = handle;
3107 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3109 r.out.domain_handle = &domain_handle;
3111 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 printf("OpenDomain failed - %s\n", nt_errstr(status));
3117 /* run the domain tests with the main handle closed - this tests
3118 the servers reference counting */
3119 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3121 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3122 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3123 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3124 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3125 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3126 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3127 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3128 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3129 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3130 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3131 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3132 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3133 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3134 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3135 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3136 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3137 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3138 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3139 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3140 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3141 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3142 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3144 if (!policy_handle_empty(&user_handle) &&
3145 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3149 if (!policy_handle_empty(&alias_handle) &&
3150 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3154 if (!policy_handle_empty(&group_handle) &&
3155 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3159 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3161 /* reconnect the main handle */
3162 ret &= test_Connect(p, mem_ctx, handle);
3167 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3168 struct policy_handle *handle, struct lsa_String *domain)
3171 struct samr_LookupDomain r;
3172 struct lsa_String n2;
3175 printf("Testing LookupDomain(%s)\n", domain->string);
3177 /* check for correct error codes */
3178 r.in.connect_handle = handle;
3179 r.in.domain_name = &n2;
3182 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3183 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3184 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3188 n2.string = "xxNODOMAINxx";
3190 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3191 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3192 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3196 r.in.connect_handle = handle;
3197 r.in.domain_name = domain;
3199 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3200 if (!NT_STATUS_IS_OK(status)) {
3201 printf("LookupDomain failed - %s\n", nt_errstr(status));
3205 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3209 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3217 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3218 struct policy_handle *handle)
3221 struct samr_EnumDomains r;
3222 uint32_t resume_handle = 0;
3226 r.in.connect_handle = handle;
3227 r.in.resume_handle = &resume_handle;
3228 r.in.buf_size = (uint32_t)-1;
3229 r.out.resume_handle = &resume_handle;
3231 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3232 if (!NT_STATUS_IS_OK(status)) {
3233 printf("EnumDomains failed - %s\n", nt_errstr(status));
3241 for (i=0;i<r.out.sam->count;i++) {
3242 if (!test_LookupDomain(p, mem_ctx, handle,
3243 &r.out.sam->entries[i].name)) {
3248 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3249 if (!NT_STATUS_IS_OK(status)) {
3250 printf("EnumDomains failed - %s\n", nt_errstr(status));
3258 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3259 struct policy_handle *handle)
3262 struct samr_Connect r;
3263 struct samr_Connect2 r2;
3264 struct samr_Connect3 r3;
3265 struct samr_Connect4 r4;
3266 struct samr_Connect5 r5;
3267 union samr_ConnectInfo info;
3268 struct policy_handle h;
3269 BOOL ret = True, got_handle = False;
3271 printf("testing samr_Connect\n");
3273 r.in.system_name = 0;
3274 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3275 r.out.connect_handle = &h;
3277 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3278 if (!NT_STATUS_IS_OK(status)) {
3279 printf("Connect failed - %s\n", nt_errstr(status));
3286 printf("testing samr_Connect2\n");
3288 r2.in.system_name = NULL;
3289 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3290 r2.out.connect_handle = &h;
3292 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3293 if (!NT_STATUS_IS_OK(status)) {
3294 printf("Connect2 failed - %s\n", nt_errstr(status));
3298 test_samr_handle_Close(p, mem_ctx, handle);
3304 printf("testing samr_Connect3\n");
3306 r3.in.system_name = NULL;
3308 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3309 r3.out.connect_handle = &h;
3311 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3312 if (!NT_STATUS_IS_OK(status)) {
3313 printf("Connect3 failed - %s\n", nt_errstr(status));
3317 test_samr_handle_Close(p, mem_ctx, handle);
3323 printf("testing samr_Connect4\n");
3325 r4.in.system_name = "";
3327 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3328 r4.out.connect_handle = &h;
3330 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3331 if (!NT_STATUS_IS_OK(status)) {
3332 printf("Connect4 failed - %s\n", nt_errstr(status));
3336 test_samr_handle_Close(p, mem_ctx, handle);
3342 printf("testing samr_Connect5\n");
3344 info.info1.unknown1 = 0;
3345 info.info1.unknown2 = 0;
3347 r5.in.system_name = "";
3348 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3351 r5.out.info = &info;
3352 r5.out.connect_handle = &h;
3354 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3355 if (!NT_STATUS_IS_OK(status)) {
3356 printf("Connect5 failed - %s\n", nt_errstr(status));
3360 test_samr_handle_Close(p, mem_ctx, handle);
3370 BOOL torture_rpc_samr(struct torture_context *torture)
3373 struct dcerpc_pipe *p;
3374 TALLOC_CTX *mem_ctx;
3376 struct policy_handle handle;
3378 mem_ctx = talloc_init("torture_rpc_samr");
3380 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3381 if (!NT_STATUS_IS_OK(status)) {
3382 talloc_free(mem_ctx);
3386 if (!test_Connect(p, mem_ctx, &handle)) {
3390 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3394 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3398 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3402 if (!test_Shutdown(p, mem_ctx, &handle)) {
3406 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3410 talloc_free(mem_ctx);