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/ndr_lsa.h"
26 #include "librpc/gen_ndr/ndr_samr.h"
28 #include "lib/crypto/crypto.h"
30 #define TEST_ACCOUNT_NAME "samrtorturetest"
31 #define TEST_ALIASNAME "samrtorturetestalias"
32 #define TEST_GROUPNAME "samrtorturetestgroup"
33 #define TEST_MACHINENAME "samrtestmach$"
34 #define TEST_DOMAINNAME "samrtestdom$"
37 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
38 struct policy_handle *handle);
40 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
41 struct policy_handle *handle);
43 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
44 struct policy_handle *handle);
46 static void init_lsa_String(struct lsa_String *string, const char *s)
51 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
52 struct policy_handle *handle)
58 r.out.handle = handle;
60 status = dcerpc_samr_Close(p, mem_ctx, &r);
61 if (!NT_STATUS_IS_OK(status)) {
62 printf("Close handle failed - %s\n", nt_errstr(status));
69 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
70 struct policy_handle *handle)
73 struct samr_Shutdown r;
75 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
76 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
80 r.in.connect_handle = handle;
82 printf("testing samr_Shutdown\n");
84 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
85 if (!NT_STATUS_IS_OK(status)) {
86 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
93 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
94 struct policy_handle *handle)
97 struct samr_SetDsrmPassword r;
98 struct lsa_String string;
99 struct samr_Password hash;
101 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
102 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
106 E_md4hash("TeSTDSRM123", hash.hash);
108 init_lsa_String(&string, "Administrator");
114 printf("testing samr_SetDsrmPassword\n");
116 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
117 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
118 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
126 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
127 struct policy_handle *handle)
130 struct samr_QuerySecurity r;
131 struct samr_SetSecurity s;
133 r.in.handle = handle;
136 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
137 if (!NT_STATUS_IS_OK(status)) {
138 printf("QuerySecurity failed - %s\n", nt_errstr(status));
142 if (r.out.sdbuf == NULL) {
146 s.in.handle = handle;
148 s.in.sdbuf = r.out.sdbuf;
150 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
151 if (!NT_STATUS_IS_OK(status)) {
152 printf("SetSecurity failed - %s\n", nt_errstr(status));
156 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
157 if (!NT_STATUS_IS_OK(status)) {
158 printf("QuerySecurity failed - %s\n", nt_errstr(status));
166 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
167 struct policy_handle *handle, uint32_t base_acct_flags,
168 const char *base_account_name)
171 struct samr_SetUserInfo s;
172 struct samr_SetUserInfo2 s2;
173 struct samr_QueryUserInfo q;
174 struct samr_QueryUserInfo q0;
175 union samr_UserInfo u;
177 const char *test_account_name;
179 uint32_t user_extra_flags = 0;
180 if (base_acct_flags == ACB_NORMAL) {
181 /* Don't know what this is, but it is always here for users - you can't get rid of it */
182 user_extra_flags = 0x20000;
185 s.in.user_handle = handle;
188 s2.in.user_handle = handle;
191 q.in.user_handle = handle;
195 #define TESTCALL(call, r) \
196 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
197 if (!NT_STATUS_IS_OK(status)) { \
198 printf(#call " level %u failed - %s (%s)\n", \
199 r.in.level, nt_errstr(status), __location__); \
204 #define STRING_EQUAL(s1, s2, field) \
205 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
206 printf("Failed to set %s to '%s' (%s)\n", \
207 #field, s2, __location__); \
212 #define INT_EQUAL(i1, i2, field) \
214 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
215 #field, i2, i1, __location__); \
220 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
221 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
223 TESTCALL(QueryUserInfo, q) \
225 s2.in.level = lvl1; \
228 ZERO_STRUCT(u.info21); \
229 u.info21.fields_present = fpval; \
231 init_lsa_String(&u.info ## lvl1.field1, value); \
232 TESTCALL(SetUserInfo, s) \
233 TESTCALL(SetUserInfo2, s2) \
234 init_lsa_String(&u.info ## lvl1.field1, ""); \
235 TESTCALL(QueryUserInfo, q); \
237 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
239 TESTCALL(QueryUserInfo, q) \
241 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
244 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
245 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
247 TESTCALL(QueryUserInfo, q) \
249 s2.in.level = lvl1; \
252 uint8_t *bits = u.info21.logon_hours.bits; \
253 ZERO_STRUCT(u.info21); \
254 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
255 u.info21.logon_hours.units_per_week = 168; \
256 u.info21.logon_hours.bits = bits; \
258 u.info21.fields_present = fpval; \
260 u.info ## lvl1.field1 = value; \
261 TESTCALL(SetUserInfo, s) \
262 TESTCALL(SetUserInfo2, s2) \
263 u.info ## lvl1.field1 = 0; \
264 TESTCALL(QueryUserInfo, q); \
266 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
268 TESTCALL(QueryUserInfo, q) \
270 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
273 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
274 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
278 do { TESTCALL(QueryUserInfo, q0) } while (0);
280 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
281 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
282 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
285 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
286 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
287 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
288 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
289 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
290 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
291 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
292 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
293 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
294 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
295 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
296 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
297 test_account_name = base_account_name;
298 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
299 SAMR_FIELD_ACCOUNT_NAME);
301 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
302 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
303 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
304 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
305 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
306 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
307 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
308 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
309 SAMR_FIELD_FULL_NAME);
311 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
312 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
313 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
314 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
315 SAMR_FIELD_LOGON_SCRIPT);
317 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
318 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
319 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
320 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
321 SAMR_FIELD_PROFILE_PATH);
323 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
324 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
325 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
326 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
327 SAMR_FIELD_DESCRIPTION);
329 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
330 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
331 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
332 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
333 SAMR_FIELD_WORKSTATIONS);
335 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
336 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
337 SAMR_FIELD_PARAMETERS);
339 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
340 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
341 SAMR_FIELD_COUNTRY_CODE);
343 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
344 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
345 SAMR_FIELD_CODE_PAGE);
347 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
348 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
349 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
350 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
351 SAMR_FIELD_LOGON_HOURS);
353 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
354 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
355 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
357 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
358 (base_acct_flags | ACB_DISABLED),
359 (base_acct_flags | ACB_DISABLED | user_extra_flags),
362 /* Setting PWNOEXP clears the magic 0x20000 flag */
363 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
364 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
365 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
367 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
368 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
369 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
372 /* The 'autolock' flag doesn't stick - check this */
373 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
374 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
375 (base_acct_flags | ACB_DISABLED | user_extra_flags),
377 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
378 (base_acct_flags | ACB_DISABLED),
379 (base_acct_flags | ACB_DISABLED | user_extra_flags),
380 SAMR_FIELD_ACCT_FLAGS);
383 /* these fail with win2003 - it appears you can't set the primary gid?
384 the set succeeds, but the gid isn't changed. Very weird! */
385 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
386 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
387 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
388 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
395 generate a random password for password change tests
397 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
399 size_t len = MAX(8, min_len) + (random() % 6);
400 char *s = generate_random_str(mem_ctx, len);
401 printf("Generated password '%s'\n", s);
405 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
406 struct policy_handle *handle, char **password)
409 struct samr_SetUserInfo s;
410 union samr_UserInfo u;
412 DATA_BLOB session_key;
414 struct samr_GetUserPwInfo pwp;
415 int policy_min_pw_len = 0;
416 pwp.in.user_handle = handle;
418 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
419 if (NT_STATUS_IS_OK(status)) {
420 policy_min_pw_len = pwp.out.info.min_password_length;
422 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
424 s.in.user_handle = handle;
428 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
429 /* w2k3 ignores this length */
430 u.info24.pw_len = strlen_m(newpass) * 2;
432 status = dcerpc_fetch_session_key(p, &session_key);
433 if (!NT_STATUS_IS_OK(status)) {
434 printf("SetUserInfo level %u - no session key - %s\n",
435 s.in.level, nt_errstr(status));
439 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
441 printf("Testing SetUserInfo level 24 (set password)\n");
443 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
444 if (!NT_STATUS_IS_OK(status)) {
445 printf("SetUserInfo level %u failed - %s\n",
446 s.in.level, nt_errstr(status));
456 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
457 struct policy_handle *handle, uint32_t fields_present,
461 struct samr_SetUserInfo s;
462 union samr_UserInfo u;
464 DATA_BLOB session_key;
466 struct samr_GetUserPwInfo pwp;
467 int policy_min_pw_len = 0;
468 pwp.in.user_handle = handle;
470 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
471 if (NT_STATUS_IS_OK(status)) {
472 policy_min_pw_len = pwp.out.info.min_password_length;
474 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
476 s.in.user_handle = handle;
482 u.info23.info.fields_present = fields_present;
484 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
486 status = dcerpc_fetch_session_key(p, &session_key);
487 if (!NT_STATUS_IS_OK(status)) {
488 printf("SetUserInfo level %u - no session key - %s\n",
489 s.in.level, nt_errstr(status));
493 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
495 printf("Testing SetUserInfo level 23 (set password)\n");
497 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
498 if (!NT_STATUS_IS_OK(status)) {
499 printf("SetUserInfo level %u failed - %s\n",
500 s.in.level, nt_errstr(status));
510 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
511 struct policy_handle *handle, char **password)
514 struct samr_SetUserInfo s;
515 union samr_UserInfo u;
517 DATA_BLOB session_key;
518 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
519 uint8_t confounder[16];
521 struct MD5Context ctx;
522 struct samr_GetUserPwInfo pwp;
523 int policy_min_pw_len = 0;
524 pwp.in.user_handle = handle;
526 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
527 if (NT_STATUS_IS_OK(status)) {
528 policy_min_pw_len = pwp.out.info.min_password_length;
530 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
532 s.in.user_handle = handle;
536 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
537 u.info26.pw_len = strlen(newpass);
539 status = dcerpc_fetch_session_key(p, &session_key);
540 if (!NT_STATUS_IS_OK(status)) {
541 printf("SetUserInfo level %u - no session key - %s\n",
542 s.in.level, nt_errstr(status));
546 generate_random_buffer((uint8_t *)confounder, 16);
549 MD5Update(&ctx, confounder, 16);
550 MD5Update(&ctx, session_key.data, session_key.length);
551 MD5Final(confounded_session_key.data, &ctx);
553 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
554 memcpy(&u.info26.password.data[516], confounder, 16);
556 printf("Testing SetUserInfo level 26 (set password ex)\n");
558 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
559 if (!NT_STATUS_IS_OK(status)) {
560 printf("SetUserInfo level %u failed - %s\n",
561 s.in.level, nt_errstr(status));
570 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
571 struct policy_handle *handle, uint32_t fields_present,
575 struct samr_SetUserInfo s;
576 union samr_UserInfo u;
578 DATA_BLOB session_key;
579 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
580 struct MD5Context ctx;
581 uint8_t confounder[16];
583 struct samr_GetUserPwInfo pwp;
584 int policy_min_pw_len = 0;
585 pwp.in.user_handle = handle;
587 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
588 if (NT_STATUS_IS_OK(status)) {
589 policy_min_pw_len = pwp.out.info.min_password_length;
591 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
593 s.in.user_handle = handle;
599 u.info25.info.fields_present = fields_present;
601 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
603 status = dcerpc_fetch_session_key(p, &session_key);
604 if (!NT_STATUS_IS_OK(status)) {
605 printf("SetUserInfo level %u - no session key - %s\n",
606 s.in.level, nt_errstr(status));
610 generate_random_buffer((uint8_t *)confounder, 16);
613 MD5Update(&ctx, confounder, 16);
614 MD5Update(&ctx, session_key.data, session_key.length);
615 MD5Final(confounded_session_key.data, &ctx);
617 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
618 memcpy(&u.info25.password.data[516], confounder, 16);
620 printf("Testing SetUserInfo level 25 (set password ex)\n");
622 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
623 if (!NT_STATUS_IS_OK(status)) {
624 printf("SetUserInfo level %u failed - %s\n",
625 s.in.level, nt_errstr(status));
634 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
635 struct policy_handle *handle)
638 struct samr_SetAliasInfo r;
639 struct samr_QueryAliasInfo q;
640 uint16_t levels[] = {2, 3};
644 /* Ignoring switch level 1, as that includes the number of members for the alias
645 * and setting this to a wrong value might have negative consequences
648 for (i=0;i<ARRAY_SIZE(levels);i++) {
649 printf("Testing SetAliasInfo level %u\n", levels[i]);
651 r.in.alias_handle = handle;
652 r.in.level = levels[i];
653 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
654 switch (r.in.level) {
655 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
656 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
657 "Test Description, should test I18N as well"); break;
660 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
661 if (!NT_STATUS_IS_OK(status)) {
662 printf("SetAliasInfo level %u failed - %s\n",
663 levels[i], nt_errstr(status));
667 q.in.alias_handle = handle;
668 q.in.level = levels[i];
670 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
671 if (!NT_STATUS_IS_OK(status)) {
672 printf("QueryAliasInfo level %u failed - %s\n",
673 levels[i], nt_errstr(status));
681 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
682 struct policy_handle *user_handle)
684 struct samr_GetGroupsForUser r;
688 printf("testing GetGroupsForUser\n");
690 r.in.user_handle = user_handle;
692 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
693 if (!NT_STATUS_IS_OK(status)) {
694 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
702 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
703 struct lsa_String *domain_name)
706 struct samr_GetDomPwInfo r;
709 r.in.domain_name = domain_name;
710 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
712 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
713 if (!NT_STATUS_IS_OK(status)) {
714 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
718 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
719 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
721 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
722 if (!NT_STATUS_IS_OK(status)) {
723 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
727 r.in.domain_name->string = "\\\\__NONAME__";
728 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
730 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
731 if (!NT_STATUS_IS_OK(status)) {
732 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
736 r.in.domain_name->string = "\\\\Builtin";
737 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
739 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
749 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
750 struct policy_handle *handle)
753 struct samr_GetUserPwInfo r;
756 printf("Testing GetUserPwInfo\n");
758 r.in.user_handle = handle;
760 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
761 if (!NT_STATUS_IS_OK(status)) {
762 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
769 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
770 struct policy_handle *domain_handle, const char *name,
774 struct samr_LookupNames n;
775 struct lsa_String sname[2];
777 init_lsa_String(&sname[0], name);
779 n.in.domain_handle = domain_handle;
782 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
783 if (NT_STATUS_IS_OK(status)) {
784 *rid = n.out.rids.ids[0];
789 init_lsa_String(&sname[1], "xxNONAMExx");
791 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
792 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
793 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
797 init_lsa_String(&sname[1], "xxNONAMExx");
799 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
800 if (!NT_STATUS_IS_OK(status)) {
801 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
807 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
808 struct policy_handle *domain_handle,
809 const char *name, struct policy_handle *user_handle)
812 struct samr_OpenUser r;
815 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
816 if (!NT_STATUS_IS_OK(status)) {
820 r.in.domain_handle = domain_handle;
821 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
823 r.out.user_handle = user_handle;
824 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
825 if (!NT_STATUS_IS_OK(status)) {
826 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
833 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
834 struct policy_handle *handle)
837 struct samr_ChangePasswordUser r;
839 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
840 struct policy_handle user_handle;
841 char *oldpass = "test";
842 char *newpass = "test2";
843 uint8_t old_nt_hash[16], new_nt_hash[16];
844 uint8_t old_lm_hash[16], new_lm_hash[16];
846 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
847 if (!NT_STATUS_IS_OK(status)) {
851 printf("Testing ChangePasswordUser for user 'testuser'\n");
853 printf("old password: %s\n", oldpass);
854 printf("new password: %s\n", newpass);
856 E_md4hash(oldpass, old_nt_hash);
857 E_md4hash(newpass, new_nt_hash);
858 E_deshash(oldpass, old_lm_hash);
859 E_deshash(newpass, new_lm_hash);
861 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
862 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
863 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
864 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
865 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
866 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
868 r.in.handle = &user_handle;
870 r.in.old_lm_crypted = &hash1;
871 r.in.new_lm_crypted = &hash2;
873 r.in.old_nt_crypted = &hash3;
874 r.in.new_nt_crypted = &hash4;
875 r.in.cross1_present = 1;
876 r.in.nt_cross = &hash5;
877 r.in.cross2_present = 1;
878 r.in.lm_cross = &hash6;
880 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
881 if (!NT_STATUS_IS_OK(status)) {
882 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
886 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
894 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
895 struct policy_handle *handle, char **password)
898 struct samr_ChangePasswordUser r;
900 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
901 struct policy_handle user_handle;
902 char *oldpass = *password;
903 uint8_t old_nt_hash[16], new_nt_hash[16];
904 uint8_t old_lm_hash[16], new_lm_hash[16];
907 struct samr_GetUserPwInfo pwp;
908 int policy_min_pw_len = 0;
910 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
911 if (!NT_STATUS_IS_OK(status)) {
914 pwp.in.user_handle = &user_handle;
916 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
917 if (NT_STATUS_IS_OK(status)) {
918 policy_min_pw_len = pwp.out.info.min_password_length;
920 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
922 printf("Testing ChangePasswordUser\n");
924 E_md4hash(oldpass, old_nt_hash);
925 E_md4hash(newpass, new_nt_hash);
926 E_deshash(oldpass, old_lm_hash);
927 E_deshash(newpass, new_lm_hash);
929 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
930 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
931 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
932 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
933 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
934 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
936 r.in.user_handle = &user_handle;
938 r.in.old_lm_crypted = &hash1;
939 r.in.new_lm_crypted = &hash2;
941 r.in.old_nt_crypted = &hash3;
942 r.in.new_nt_crypted = &hash4;
943 r.in.cross1_present = 1;
944 r.in.nt_cross = &hash5;
945 r.in.cross2_present = 1;
946 r.in.lm_cross = &hash6;
948 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
949 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
950 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
951 } else if (!NT_STATUS_IS_OK(status)) {
952 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
958 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
966 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
967 struct policy_handle *handle, char **password)
970 struct samr_OemChangePasswordUser2 r;
972 struct samr_Password lm_verifier;
973 struct samr_CryptPassword lm_pass;
974 struct lsa_AsciiString server, account, account_bad;
975 char *oldpass = *password;
977 uint8_t old_lm_hash[16], new_lm_hash[16];
979 struct samr_GetDomPwInfo dom_pw_info;
980 int policy_min_pw_len = 0;
982 struct lsa_String domain_name;
983 domain_name.string = "";
984 dom_pw_info.in.domain_name = &domain_name;
986 printf("Testing OemChangePasswordUser2\n");
988 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
989 if (NT_STATUS_IS_OK(status)) {
990 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
993 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
995 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
996 account.string = TEST_ACCOUNT_NAME;
998 E_deshash(oldpass, old_lm_hash);
999 E_deshash(newpass, new_lm_hash);
1001 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1002 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1003 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1005 r.in.server = &server;
1006 r.in.account = &account;
1007 r.in.password = &lm_pass;
1008 r.in.hash = &lm_verifier;
1010 /* Break the verification */
1011 lm_verifier.hash[0]++;
1013 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1015 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1016 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1017 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1022 /* This shouldn't be a valid name */
1023 account_bad.string = TEST_ACCOUNT_NAME "XX";
1024 r.in.account = &account_bad;
1026 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1028 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1029 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1034 E_deshash(oldpass, old_lm_hash);
1035 E_deshash(newpass, new_lm_hash);
1037 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1038 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1039 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1041 r.in.server = &server;
1042 r.in.account = &account;
1043 r.in.password = &lm_pass;
1044 r.in.hash = &lm_verifier;
1046 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1047 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1048 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1049 } else if (!NT_STATUS_IS_OK(status)) {
1050 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1053 *password = newpass;
1060 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1061 struct policy_handle *handle, char **password)
1064 struct samr_ChangePasswordUser2 r;
1066 struct lsa_String server, account;
1067 struct samr_CryptPassword nt_pass, lm_pass;
1068 struct samr_Password nt_verifier, lm_verifier;
1069 char *oldpass = *password;
1071 uint8_t old_nt_hash[16], new_nt_hash[16];
1072 uint8_t old_lm_hash[16], new_lm_hash[16];
1074 struct samr_GetDomPwInfo dom_pw_info;
1075 int policy_min_pw_len = 0;
1077 struct lsa_String domain_name;
1078 domain_name.string = "";
1079 dom_pw_info.in.domain_name = &domain_name;
1081 printf("Testing ChangePasswordUser2\n");
1083 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1084 if (NT_STATUS_IS_OK(status)) {
1085 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1088 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1090 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1091 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1093 E_md4hash(oldpass, old_nt_hash);
1094 E_md4hash(newpass, new_nt_hash);
1096 E_deshash(oldpass, old_lm_hash);
1097 E_deshash(newpass, new_lm_hash);
1099 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1100 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1101 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1103 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1104 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1105 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1107 r.in.server = &server;
1108 r.in.account = &account;
1109 r.in.nt_password = &nt_pass;
1110 r.in.nt_verifier = &nt_verifier;
1112 r.in.lm_password = &lm_pass;
1113 r.in.lm_verifier = &lm_verifier;
1115 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1116 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1117 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1118 } else if (!NT_STATUS_IS_OK(status)) {
1119 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1122 *password = newpass;
1129 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1130 const char *account_string,
1131 int policy_min_pw_len,
1135 struct samr_ChangePasswordUser3 r;
1137 struct lsa_String server, account, account_bad;
1138 struct samr_CryptPassword nt_pass, lm_pass;
1139 struct samr_Password nt_verifier, lm_verifier;
1140 char *oldpass = *password;
1141 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1142 uint8_t old_nt_hash[16], new_nt_hash[16];
1143 uint8_t old_lm_hash[16], new_lm_hash[16];
1145 printf("Testing ChangePasswordUser3\n");
1147 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1148 init_lsa_String(&account, account_string);
1150 E_md4hash(oldpass, old_nt_hash);
1151 E_md4hash(newpass, new_nt_hash);
1153 E_deshash(oldpass, old_lm_hash);
1154 E_deshash(newpass, new_lm_hash);
1156 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1157 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1158 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1160 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1161 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1162 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1164 /* Break the verification */
1165 nt_verifier.hash[0]++;
1167 r.in.server = &server;
1168 r.in.account = &account;
1169 r.in.nt_password = &nt_pass;
1170 r.in.nt_verifier = &nt_verifier;
1172 r.in.lm_password = &lm_pass;
1173 r.in.lm_verifier = &lm_verifier;
1174 r.in.password3 = NULL;
1176 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1177 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1178 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1179 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1184 /* This shouldn't be a valid name */
1185 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1187 r.in.account = &account_bad;
1188 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1189 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1190 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1195 E_md4hash(oldpass, old_nt_hash);
1196 E_md4hash(newpass, new_nt_hash);
1198 E_deshash(oldpass, old_lm_hash);
1199 E_deshash(newpass, new_lm_hash);
1201 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1202 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1203 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1205 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1206 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1207 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1209 r.in.server = &server;
1210 r.in.account = &account;
1211 r.in.nt_password = &nt_pass;
1212 r.in.nt_verifier = &nt_verifier;
1214 r.in.lm_password = &lm_pass;
1215 r.in.lm_verifier = &lm_verifier;
1216 r.in.password3 = NULL;
1218 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1219 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1220 && !policy_min_pw_len) {
1221 if (r.out.dominfo) {
1222 policy_min_pw_len = r.out.dominfo->min_password_length;
1224 if (policy_min_pw_len) /* try again with the right min password length */ {
1225 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1227 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1230 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1231 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1232 } else if (!NT_STATUS_IS_OK(status)) {
1233 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1236 *password = newpass;
1243 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1244 struct policy_handle *alias_handle)
1246 struct samr_GetMembersInAlias r;
1247 struct lsa_SidArray sids;
1251 printf("Testing GetMembersInAlias\n");
1253 r.in.alias_handle = alias_handle;
1256 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1257 if (!NT_STATUS_IS_OK(status)) {
1258 printf("GetMembersInAlias failed - %s\n",
1266 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1267 struct policy_handle *alias_handle,
1268 const struct dom_sid *domain_sid)
1270 struct samr_AddAliasMember r;
1271 struct samr_DeleteAliasMember d;
1274 struct dom_sid *sid;
1276 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1278 printf("testing AddAliasMember\n");
1279 r.in.alias_handle = alias_handle;
1282 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1288 d.in.alias_handle = alias_handle;
1291 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1292 if (!NT_STATUS_IS_OK(status)) {
1293 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1300 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1301 struct policy_handle *alias_handle)
1303 struct samr_AddMultipleMembersToAlias a;
1304 struct samr_RemoveMultipleMembersFromAlias r;
1307 struct lsa_SidArray sids;
1309 printf("testing AddMultipleMembersToAlias\n");
1310 a.in.alias_handle = alias_handle;
1314 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1316 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1317 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1318 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1320 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1321 if (!NT_STATUS_IS_OK(status)) {
1322 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1327 printf("testing RemoveMultipleMembersFromAlias\n");
1328 r.in.alias_handle = alias_handle;
1331 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1337 /* strange! removing twice doesn't give any error */
1338 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1344 /* but removing an alias that isn't there does */
1345 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1347 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1348 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1349 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1356 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1357 struct policy_handle *user_handle)
1359 struct samr_TestPrivateFunctionsUser r;
1363 printf("Testing TestPrivateFunctionsUser\n");
1365 r.in.user_handle = user_handle;
1367 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1368 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1369 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1377 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1378 struct policy_handle *handle, uint32_t base_acct_flags,
1379 const char *base_acct_name)
1383 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1387 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1391 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1395 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1400 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1404 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1411 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1412 struct policy_handle *alias_handle,
1413 const struct dom_sid *domain_sid)
1417 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1421 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1425 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1429 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1433 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1441 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1442 struct policy_handle *handle, const char *name)
1445 struct samr_DeleteUser d;
1446 struct policy_handle user_handle;
1449 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1450 if (!NT_STATUS_IS_OK(status)) {
1454 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1455 if (!NT_STATUS_IS_OK(status)) {
1459 d.in.user_handle = &user_handle;
1460 d.out.user_handle = &user_handle;
1461 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1462 if (!NT_STATUS_IS_OK(status)) {
1469 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1474 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1475 struct policy_handle *handle, const char *name)
1478 struct samr_OpenGroup r;
1479 struct samr_DeleteDomainGroup d;
1480 struct policy_handle group_handle;
1483 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1484 if (!NT_STATUS_IS_OK(status)) {
1488 r.in.domain_handle = handle;
1489 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1491 r.out.group_handle = &group_handle;
1492 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1493 if (!NT_STATUS_IS_OK(status)) {
1497 d.in.group_handle = &group_handle;
1498 d.out.group_handle = &group_handle;
1499 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1500 if (!NT_STATUS_IS_OK(status)) {
1507 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1512 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1513 struct policy_handle *domain_handle, const char *name)
1516 struct samr_OpenAlias r;
1517 struct samr_DeleteDomAlias d;
1518 struct policy_handle alias_handle;
1521 printf("testing DeleteAlias_byname\n");
1523 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1524 if (!NT_STATUS_IS_OK(status)) {
1528 r.in.domain_handle = domain_handle;
1529 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1531 r.out.alias_handle = &alias_handle;
1532 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1533 if (!NT_STATUS_IS_OK(status)) {
1537 d.in.alias_handle = &alias_handle;
1538 d.out.alias_handle = &alias_handle;
1539 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1540 if (!NT_STATUS_IS_OK(status)) {
1547 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1551 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1552 struct policy_handle *alias_handle)
1554 struct samr_DeleteDomAlias d;
1557 printf("Testing DeleteAlias\n");
1559 d.in.alias_handle = alias_handle;
1560 d.out.alias_handle = alias_handle;
1562 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1563 if (!NT_STATUS_IS_OK(status)) {
1564 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1571 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1572 struct policy_handle *domain_handle,
1573 struct policy_handle *alias_handle,
1574 const struct dom_sid *domain_sid)
1577 struct samr_CreateDomAlias r;
1578 struct lsa_String name;
1582 init_lsa_String(&name, TEST_ALIASNAME);
1583 r.in.domain_handle = domain_handle;
1584 r.in.alias_name = &name;
1585 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1586 r.out.alias_handle = alias_handle;
1589 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1591 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1593 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1594 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1598 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1599 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1602 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1605 if (!NT_STATUS_IS_OK(status)) {
1606 printf("CreateAlias failed - %s\n", nt_errstr(status));
1610 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1617 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1618 struct policy_handle *domain_handle, char **password)
1626 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1630 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1634 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1638 /* we change passwords twice - this has the effect of verifying
1639 they were changed correctly for the final call */
1640 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1644 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1651 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1652 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1655 struct samr_CreateUser r;
1656 struct samr_QueryUserInfo q;
1658 char *password = NULL;
1661 const uint32_t password_fields[] = {
1662 SAMR_FIELD_PASSWORD,
1663 SAMR_FIELD_PASSWORD2,
1664 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1668 TALLOC_CTX *user_ctx;
1670 /* This call creates a 'normal' account - check that it really does */
1671 const uint32_t acct_flags = ACB_NORMAL;
1672 struct lsa_String name;
1675 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1676 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1678 r.in.domain_handle = domain_handle;
1679 r.in.account_name = &name;
1680 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1681 r.out.user_handle = user_handle;
1684 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1686 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1688 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1689 printf("Server refused create of '%s'\n", r.in.account_name->string);
1690 ZERO_STRUCTP(user_handle);
1691 talloc_free(user_ctx);
1695 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1696 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1697 talloc_free(user_ctx);
1700 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1702 if (!NT_STATUS_IS_OK(status)) {
1703 talloc_free(user_ctx);
1704 printf("CreateUser failed - %s\n", nt_errstr(status));
1708 q.in.user_handle = user_handle;
1711 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1712 if (!NT_STATUS_IS_OK(status)) {
1713 printf("QueryUserInfo level %u failed - %s\n",
1714 q.in.level, nt_errstr(status));
1717 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1718 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1719 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1720 acct_flags, acct_flags);
1725 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1729 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1733 for (i = 0; password_fields[i]; i++) {
1734 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1738 /* check it was set right */
1739 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1744 for (i = 0; password_fields[i]; i++) {
1745 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1749 /* check it was set right */
1750 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1755 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1759 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1763 talloc_free(user_ctx);
1769 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1770 struct policy_handle *user_handle)
1772 struct samr_DeleteUser d;
1776 printf("Testing DeleteUser\n");
1778 d.in.user_handle = user_handle;
1779 d.out.user_handle = user_handle;
1781 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1782 if (!NT_STATUS_IS_OK(status)) {
1783 printf("DeleteUser failed - %s\n", nt_errstr(status));
1790 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1791 struct policy_handle *handle)
1794 struct samr_CreateUser2 r;
1795 struct samr_QueryUserInfo q;
1796 struct samr_DeleteUser d;
1797 struct policy_handle user_handle;
1799 struct lsa_String name;
1804 uint32_t acct_flags;
1805 const char *account_name;
1807 } account_types[] = {
1808 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1809 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1810 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1811 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1812 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1813 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1814 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1815 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1816 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1817 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1818 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1819 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1820 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1821 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1822 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1825 for (i = 0; account_types[i].account_name; i++) {
1826 TALLOC_CTX *user_ctx;
1827 uint32_t acct_flags = account_types[i].acct_flags;
1828 uint32_t access_granted;
1829 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1830 init_lsa_String(&name, account_types[i].account_name);
1832 r.in.domain_handle = handle;
1833 r.in.account_name = &name;
1834 r.in.acct_flags = acct_flags;
1835 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1836 r.out.user_handle = &user_handle;
1837 r.out.access_granted = &access_granted;
1840 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1842 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1844 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1845 talloc_free(user_ctx);
1846 printf("Server refused create of '%s'\n", r.in.account_name->string);
1849 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1850 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1851 talloc_free(user_ctx);
1855 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1858 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1859 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1860 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1864 if (NT_STATUS_IS_OK(status)) {
1865 q.in.user_handle = &user_handle;
1868 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1869 if (!NT_STATUS_IS_OK(status)) {
1870 printf("QueryUserInfo level %u failed - %s\n",
1871 q.in.level, nt_errstr(status));
1874 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1875 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1876 q.out.info->info16.acct_flags,
1882 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1886 printf("Testing DeleteUser (createuser2 test)\n");
1888 d.in.user_handle = &user_handle;
1889 d.out.user_handle = &user_handle;
1891 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1892 if (!NT_STATUS_IS_OK(status)) {
1893 printf("DeleteUser failed - %s\n", nt_errstr(status));
1897 talloc_free(user_ctx);
1903 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1904 struct policy_handle *handle)
1907 struct samr_QueryAliasInfo r;
1908 uint16_t levels[] = {1, 2, 3};
1912 for (i=0;i<ARRAY_SIZE(levels);i++) {
1913 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1915 r.in.alias_handle = handle;
1916 r.in.level = levels[i];
1918 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1919 if (!NT_STATUS_IS_OK(status)) {
1920 printf("QueryAliasInfo level %u failed - %s\n",
1921 levels[i], nt_errstr(status));
1929 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1930 struct policy_handle *handle)
1933 struct samr_QueryGroupInfo r;
1934 uint16_t levels[] = {1, 2, 3, 4, 5};
1938 for (i=0;i<ARRAY_SIZE(levels);i++) {
1939 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1941 r.in.group_handle = handle;
1942 r.in.level = levels[i];
1944 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1945 if (!NT_STATUS_IS_OK(status)) {
1946 printf("QueryGroupInfo level %u failed - %s\n",
1947 levels[i], nt_errstr(status));
1955 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1956 struct policy_handle *handle)
1959 struct samr_QueryGroupMember r;
1962 printf("Testing QueryGroupMember\n");
1964 r.in.group_handle = handle;
1966 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1967 if (!NT_STATUS_IS_OK(status)) {
1968 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1976 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1977 struct policy_handle *handle)
1980 struct samr_QueryGroupInfo r;
1981 struct samr_SetGroupInfo s;
1982 uint16_t levels[] = {1, 2, 3, 4};
1983 uint16_t set_ok[] = {0, 1, 1, 1};
1987 for (i=0;i<ARRAY_SIZE(levels);i++) {
1988 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1990 r.in.group_handle = handle;
1991 r.in.level = levels[i];
1993 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1994 if (!NT_STATUS_IS_OK(status)) {
1995 printf("QueryGroupInfo level %u failed - %s\n",
1996 levels[i], nt_errstr(status));
2000 printf("Testing SetGroupInfo level %u\n", levels[i]);
2002 s.in.group_handle = handle;
2003 s.in.level = levels[i];
2004 s.in.info = r.out.info;
2007 /* disabled this, as it changes the name only from the point of view of samr,
2008 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2009 the name is still reserved, so creating the old name fails, but deleting by the old name
2011 if (s.in.level == 2) {
2012 init_lsa_String(&s.in.info->string, "NewName");
2016 if (s.in.level == 4) {
2017 init_lsa_String(&s.in.info->description, "test description");
2020 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2022 if (!NT_STATUS_IS_OK(status)) {
2023 printf("SetGroupInfo level %u failed - %s\n",
2024 r.in.level, nt_errstr(status));
2029 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2030 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2031 r.in.level, nt_errstr(status));
2041 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2042 struct policy_handle *handle)
2045 struct samr_QueryUserInfo r;
2046 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2047 11, 12, 13, 14, 16, 17, 20, 21};
2051 for (i=0;i<ARRAY_SIZE(levels);i++) {
2052 printf("Testing QueryUserInfo level %u\n", levels[i]);
2054 r.in.user_handle = handle;
2055 r.in.level = levels[i];
2057 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2058 if (!NT_STATUS_IS_OK(status)) {
2059 printf("QueryUserInfo level %u failed - %s\n",
2060 levels[i], nt_errstr(status));
2068 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2069 struct policy_handle *handle)
2072 struct samr_QueryUserInfo2 r;
2073 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2074 11, 12, 13, 14, 16, 17, 20, 21};
2078 for (i=0;i<ARRAY_SIZE(levels);i++) {
2079 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2081 r.in.user_handle = handle;
2082 r.in.level = levels[i];
2084 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2085 if (!NT_STATUS_IS_OK(status)) {
2086 printf("QueryUserInfo2 level %u failed - %s\n",
2087 levels[i], nt_errstr(status));
2095 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2096 struct policy_handle *handle, uint32_t rid)
2099 struct samr_OpenUser r;
2100 struct policy_handle user_handle;
2103 printf("Testing OpenUser(%u)\n", rid);
2105 r.in.domain_handle = handle;
2106 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2108 r.out.user_handle = &user_handle;
2110 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2111 if (!NT_STATUS_IS_OK(status)) {
2112 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2116 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2120 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2124 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2128 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2132 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2136 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2143 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2144 struct policy_handle *handle, uint32_t rid)
2147 struct samr_OpenGroup r;
2148 struct policy_handle group_handle;
2151 printf("Testing OpenGroup(%u)\n", rid);
2153 r.in.domain_handle = handle;
2154 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2156 r.out.group_handle = &group_handle;
2158 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2159 if (!NT_STATUS_IS_OK(status)) {
2160 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2164 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2168 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2172 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2176 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2183 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2184 struct policy_handle *handle, uint32_t rid)
2187 struct samr_OpenAlias r;
2188 struct policy_handle alias_handle;
2191 printf("Testing OpenAlias(%u)\n", rid);
2193 r.in.domain_handle = handle;
2194 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2196 r.out.alias_handle = &alias_handle;
2198 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2199 if (!NT_STATUS_IS_OK(status)) {
2200 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2204 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2208 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2212 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2216 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2223 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2224 struct policy_handle *handle)
2227 struct samr_EnumDomainUsers r;
2228 uint32_t resume_handle=0;
2231 struct samr_LookupNames n;
2232 struct samr_LookupRids lr ;
2234 printf("Testing EnumDomainUsers\n");
2236 r.in.domain_handle = handle;
2237 r.in.resume_handle = &resume_handle;
2238 r.in.acct_flags = 0;
2239 r.in.max_size = (uint32_t)-1;
2240 r.out.resume_handle = &resume_handle;
2242 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2243 if (!NT_STATUS_IS_OK(status)) {
2244 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2252 if (r.out.sam->count == 0) {
2256 for (i=0;i<r.out.sam->count;i++) {
2257 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2262 printf("Testing LookupNames\n");
2263 n.in.domain_handle = handle;
2264 n.in.num_names = r.out.sam->count;
2265 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2266 for (i=0;i<r.out.sam->count;i++) {
2267 n.in.names[i].string = r.out.sam->entries[i].name.string;
2269 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2270 if (!NT_STATUS_IS_OK(status)) {
2271 printf("LookupNames failed - %s\n", nt_errstr(status));
2276 printf("Testing LookupRids\n");
2277 lr.in.domain_handle = handle;
2278 lr.in.num_rids = r.out.sam->count;
2279 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2280 for (i=0;i<r.out.sam->count;i++) {
2281 lr.in.rids[i] = r.out.sam->entries[i].idx;
2283 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2284 if (!NT_STATUS_IS_OK(status)) {
2285 printf("LookupRids failed - %s\n", nt_errstr(status));
2293 try blasting the server with a bunch of sync requests
2295 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2296 struct policy_handle *handle)
2299 struct samr_EnumDomainUsers r;
2300 uint32_t resume_handle=0;
2302 #define ASYNC_COUNT 100
2303 struct rpc_request *req[ASYNC_COUNT];
2305 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2306 printf("samr async test disabled - enable dangerous tests to use\n");
2310 printf("Testing EnumDomainUsers_async\n");
2312 r.in.domain_handle = handle;
2313 r.in.resume_handle = &resume_handle;
2314 r.in.acct_flags = 0;
2315 r.in.max_size = (uint32_t)-1;
2316 r.out.resume_handle = &resume_handle;
2318 for (i=0;i<ASYNC_COUNT;i++) {
2319 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2322 for (i=0;i<ASYNC_COUNT;i++) {
2323 status = dcerpc_ndr_request_recv(req[i]);
2324 if (!NT_STATUS_IS_OK(status)) {
2325 printf("EnumDomainUsers[%d] failed - %s\n",
2326 i, nt_errstr(status));
2331 printf("%d async requests OK\n", i);
2336 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2337 struct policy_handle *handle)
2340 struct samr_EnumDomainGroups r;
2341 uint32_t resume_handle=0;
2345 printf("Testing EnumDomainGroups\n");
2347 r.in.domain_handle = handle;
2348 r.in.resume_handle = &resume_handle;
2349 r.in.max_size = (uint32_t)-1;
2350 r.out.resume_handle = &resume_handle;
2352 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2353 if (!NT_STATUS_IS_OK(status)) {
2354 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2362 for (i=0;i<r.out.sam->count;i++) {
2363 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2371 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2372 struct policy_handle *handle)
2375 struct samr_EnumDomainAliases r;
2376 uint32_t resume_handle=0;
2380 printf("Testing EnumDomainAliases\n");
2382 r.in.domain_handle = handle;
2383 r.in.resume_handle = &resume_handle;
2384 r.in.acct_flags = (uint32_t)-1;
2385 r.out.resume_handle = &resume_handle;
2387 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2388 if (!NT_STATUS_IS_OK(status)) {
2389 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2397 for (i=0;i<r.out.sam->count;i++) {
2398 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2406 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2407 struct policy_handle *handle)
2410 struct samr_GetDisplayEnumerationIndex r;
2412 uint16_t levels[] = {1, 2, 3, 4, 5};
2413 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2416 for (i=0;i<ARRAY_SIZE(levels);i++) {
2417 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2419 r.in.domain_handle = handle;
2420 r.in.level = levels[i];
2421 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2423 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2426 !NT_STATUS_IS_OK(status) &&
2427 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2428 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2429 levels[i], nt_errstr(status));
2433 init_lsa_String(&r.in.name, "zzzzzzzz");
2435 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2437 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2438 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2439 levels[i], nt_errstr(status));
2447 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2448 struct policy_handle *handle)
2451 struct samr_GetDisplayEnumerationIndex2 r;
2453 uint16_t levels[] = {1, 2, 3, 4, 5};
2454 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2457 for (i=0;i<ARRAY_SIZE(levels);i++) {
2458 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2460 r.in.domain_handle = handle;
2461 r.in.level = levels[i];
2462 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2464 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2466 !NT_STATUS_IS_OK(status) &&
2467 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2468 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2469 levels[i], nt_errstr(status));
2473 init_lsa_String(&r.in.name, "zzzzzzzz");
2475 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2476 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2477 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2478 levels[i], nt_errstr(status));
2486 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2487 struct policy_handle *handle)
2490 struct samr_QueryDisplayInfo r;
2492 uint16_t levels[] = {1, 2, 3, 4, 5};
2495 for (i=0;i<ARRAY_SIZE(levels);i++) {
2496 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2498 r.in.domain_handle = handle;
2499 r.in.level = levels[i];
2501 r.in.max_entries = 1000;
2502 r.in.buf_size = (uint32_t)-1;
2504 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2505 if (!NT_STATUS_IS_OK(status)) {
2506 printf("QueryDisplayInfo level %u failed - %s\n",
2507 levels[i], nt_errstr(status));
2515 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2516 struct policy_handle *handle)
2519 struct samr_QueryDisplayInfo2 r;
2521 uint16_t levels[] = {1, 2, 3, 4, 5};
2524 for (i=0;i<ARRAY_SIZE(levels);i++) {
2525 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2527 r.in.domain_handle = handle;
2528 r.in.level = levels[i];
2530 r.in.max_entries = 1000;
2531 r.in.buf_size = (uint32_t)-1;
2533 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2534 if (!NT_STATUS_IS_OK(status)) {
2535 printf("QueryDisplayInfo2 level %u failed - %s\n",
2536 levels[i], nt_errstr(status));
2544 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2545 struct policy_handle *handle)
2548 struct samr_QueryDisplayInfo3 r;
2550 uint16_t levels[] = {1, 2, 3, 4, 5};
2553 for (i=0;i<ARRAY_SIZE(levels);i++) {
2554 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2556 r.in.domain_handle = handle;
2557 r.in.level = levels[i];
2559 r.in.max_entries = 1000;
2560 r.in.buf_size = (uint32_t)-1;
2562 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2563 if (!NT_STATUS_IS_OK(status)) {
2564 printf("QueryDisplayInfo3 level %u failed - %s\n",
2565 levels[i], nt_errstr(status));
2574 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2575 struct policy_handle *handle)
2578 struct samr_QueryDisplayInfo r;
2581 printf("Testing QueryDisplayInfo continuation\n");
2583 r.in.domain_handle = handle;
2586 r.in.max_entries = 1;
2587 r.in.buf_size = (uint32_t)-1;
2590 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2591 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2592 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2593 printf("failed: expected idx %d but got %d\n",
2595 r.out.info.info1.entries[0].idx);
2600 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2601 !NT_STATUS_IS_OK(status)) {
2602 printf("QueryDisplayInfo level %u failed - %s\n",
2603 r.in.level, nt_errstr(status));
2608 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2609 NT_STATUS_IS_OK(status)) &&
2610 r.out.returned_size != 0);
2615 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2616 struct policy_handle *handle)
2619 struct samr_QueryDomainInfo r;
2620 struct samr_SetDomainInfo s;
2621 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2622 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2626 for (i=0;i<ARRAY_SIZE(levels);i++) {
2627 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2629 r.in.domain_handle = handle;
2630 r.in.level = levels[i];
2632 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2633 if (!NT_STATUS_IS_OK(status)) {
2634 printf("QueryDomainInfo level %u failed - %s\n",
2635 r.in.level, nt_errstr(status));
2640 printf("Testing SetDomainInfo level %u\n", levels[i]);
2642 s.in.domain_handle = handle;
2643 s.in.level = levels[i];
2644 s.in.info = r.out.info;
2646 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2648 if (!NT_STATUS_IS_OK(status)) {
2649 printf("SetDomainInfo level %u failed - %s\n",
2650 r.in.level, nt_errstr(status));
2655 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2656 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2657 r.in.level, nt_errstr(status));
2663 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2664 if (!NT_STATUS_IS_OK(status)) {
2665 printf("QueryDomainInfo level %u failed - %s\n",
2666 r.in.level, nt_errstr(status));
2676 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2677 struct policy_handle *handle)
2680 struct samr_QueryDomainInfo2 r;
2681 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2685 for (i=0;i<ARRAY_SIZE(levels);i++) {
2686 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2688 r.in.domain_handle = handle;
2689 r.in.level = levels[i];
2691 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2692 if (!NT_STATUS_IS_OK(status)) {
2693 printf("QueryDomainInfo2 level %u failed - %s\n",
2694 r.in.level, nt_errstr(status));
2703 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2704 set of group names. */
2705 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2706 struct policy_handle *handle)
2708 struct samr_EnumDomainGroups q1;
2709 struct samr_QueryDisplayInfo q2;
2711 uint32_t resume_handle=0;
2716 const char **names = NULL;
2718 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2720 q1.in.domain_handle = handle;
2721 q1.in.resume_handle = &resume_handle;
2723 q1.out.resume_handle = &resume_handle;
2725 status = STATUS_MORE_ENTRIES;
2726 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2727 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2729 if (!NT_STATUS_IS_OK(status) &&
2730 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2733 for (i=0; i<q1.out.num_entries; i++) {
2734 add_string_to_array(mem_ctx,
2735 q1.out.sam->entries[i].name.string,
2736 &names, &num_names);
2740 if (!NT_STATUS_IS_OK(status)) {
2741 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2749 q2.in.domain_handle = handle;
2751 q2.in.start_idx = 0;
2752 q2.in.max_entries = 5;
2753 q2.in.buf_size = (uint32_t)-1;
2755 status = STATUS_MORE_ENTRIES;
2756 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2757 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2759 if (!NT_STATUS_IS_OK(status) &&
2760 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2763 for (i=0; i<q2.out.info.info5.count; i++) {
2765 const char *name = q2.out.info.info5.entries[i].account_name.string;
2767 for (j=0; j<num_names; j++) {
2768 if (names[j] == NULL)
2770 /* Hmm. No strequal in samba4 */
2771 if (strequal(names[j], name)) {
2779 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2784 q2.in.start_idx += q2.out.info.info5.count;
2787 if (!NT_STATUS_IS_OK(status)) {
2788 printf("QueryDisplayInfo level 5 failed - %s\n",
2793 for (i=0; i<num_names; i++) {
2794 if (names[i] != NULL) {
2795 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2804 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2805 struct policy_handle *group_handle)
2807 struct samr_DeleteDomainGroup d;
2811 printf("Testing DeleteDomainGroup\n");
2813 d.in.group_handle = group_handle;
2814 d.out.group_handle = group_handle;
2816 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2825 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2826 struct policy_handle *domain_handle)
2828 struct samr_TestPrivateFunctionsDomain r;
2832 printf("Testing TestPrivateFunctionsDomain\n");
2834 r.in.domain_handle = domain_handle;
2836 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2837 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2838 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2845 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2846 struct dom_sid *domain_sid,
2847 struct policy_handle *domain_handle)
2849 struct samr_RidToSid r;
2852 struct dom_sid *calc_sid;
2853 int rids[] = { 0, 42, 512, 10200 };
2856 for (i=0;i<ARRAY_SIZE(rids);i++) {
2858 printf("Testing RidToSid\n");
2860 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2861 r.in.domain_handle = domain_handle;
2864 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2865 if (!NT_STATUS_IS_OK(status)) {
2866 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2869 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2871 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2872 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2873 dom_sid_string(mem_ctx, r.out.sid),
2874 dom_sid_string(mem_ctx, calc_sid));
2883 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2884 struct policy_handle *domain_handle)
2886 struct samr_GetBootKeyInformation r;
2890 printf("Testing GetBootKeyInformation\n");
2892 r.in.domain_handle = domain_handle;
2894 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2895 if (!NT_STATUS_IS_OK(status)) {
2896 /* w2k3 seems to fail this sometimes and pass it sometimes */
2897 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2903 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2904 struct policy_handle *domain_handle,
2905 struct policy_handle *group_handle)
2908 struct samr_AddGroupMember r;
2909 struct samr_DeleteGroupMember d;
2910 struct samr_QueryGroupMember q;
2911 struct samr_SetMemberAttributesOfGroup s;
2915 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2916 if (!NT_STATUS_IS_OK(status)) {
2920 r.in.group_handle = group_handle;
2922 r.in.flags = 0; /* ??? */
2924 printf("Testing AddGroupMember and DeleteGroupMember\n");
2926 d.in.group_handle = group_handle;
2929 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2930 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2931 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2936 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2937 if (!NT_STATUS_IS_OK(status)) {
2938 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2942 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2943 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2944 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2949 /* this one is quite strange. I am using random inputs in the
2950 hope of triggering an error that might give us a clue */
2951 s.in.group_handle = group_handle;
2952 s.in.unknown1 = random();
2953 s.in.unknown2 = random();
2955 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2956 if (!NT_STATUS_IS_OK(status)) {
2957 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2961 q.in.group_handle = group_handle;
2963 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2964 if (!NT_STATUS_IS_OK(status)) {
2965 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2969 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2970 if (!NT_STATUS_IS_OK(status)) {
2971 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2975 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2976 if (!NT_STATUS_IS_OK(status)) {
2977 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2985 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2986 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2989 struct samr_CreateDomainGroup r;
2991 struct lsa_String name;
2994 init_lsa_String(&name, TEST_GROUPNAME);
2996 r.in.domain_handle = domain_handle;
2998 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2999 r.out.group_handle = group_handle;
3002 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3004 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3006 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3007 printf("Server refused create of '%s'\n", r.in.name->string);
3008 ZERO_STRUCTP(group_handle);
3012 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3013 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3014 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3017 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3019 if (!NT_STATUS_IS_OK(status)) {
3020 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3024 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3028 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3037 its not totally clear what this does. It seems to accept any sid you like.
3039 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3040 TALLOC_CTX *mem_ctx,
3041 struct policy_handle *domain_handle)
3044 struct samr_RemoveMemberFromForeignDomain r;
3046 r.in.domain_handle = domain_handle;
3047 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3049 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3050 if (!NT_STATUS_IS_OK(status)) {
3051 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3060 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3061 struct policy_handle *handle);
3063 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3064 struct policy_handle *handle, struct dom_sid *sid)
3067 struct samr_OpenDomain r;
3068 struct policy_handle domain_handle;
3069 struct policy_handle user_handle;
3070 struct policy_handle alias_handle;
3071 struct policy_handle group_handle;
3074 ZERO_STRUCT(user_handle);
3075 ZERO_STRUCT(alias_handle);
3076 ZERO_STRUCT(group_handle);
3077 ZERO_STRUCT(domain_handle);
3079 printf("Testing OpenDomain\n");
3081 r.in.connect_handle = handle;
3082 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3084 r.out.domain_handle = &domain_handle;
3086 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 printf("OpenDomain failed - %s\n", nt_errstr(status));
3092 /* run the domain tests with the main handle closed - this tests
3093 the servers reference counting */
3094 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3096 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3097 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3098 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3099 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3100 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3101 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3102 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3103 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3104 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3105 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3106 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3107 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3108 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3109 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3110 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3111 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3112 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3113 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3114 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3115 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3116 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3117 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3119 if (!policy_handle_empty(&user_handle) &&
3120 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3124 if (!policy_handle_empty(&alias_handle) &&
3125 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3129 if (!policy_handle_empty(&group_handle) &&
3130 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3134 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3136 /* reconnect the main handle */
3137 ret &= test_Connect(p, mem_ctx, handle);
3142 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3143 struct policy_handle *handle, struct lsa_String *domain)
3146 struct samr_LookupDomain r;
3147 struct lsa_String n2;
3150 printf("Testing LookupDomain(%s)\n", domain->string);
3152 /* check for correct error codes */
3153 r.in.connect_handle = handle;
3154 r.in.domain_name = &n2;
3157 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3158 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3159 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3163 n2.string = "xxNODOMAINxx";
3165 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3166 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3167 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3171 r.in.connect_handle = handle;
3172 r.in.domain_name = domain;
3174 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3175 if (!NT_STATUS_IS_OK(status)) {
3176 printf("LookupDomain failed - %s\n", nt_errstr(status));
3180 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3184 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3192 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3193 struct policy_handle *handle)
3196 struct samr_EnumDomains r;
3197 uint32_t resume_handle = 0;
3201 r.in.connect_handle = handle;
3202 r.in.resume_handle = &resume_handle;
3203 r.in.buf_size = (uint32_t)-1;
3204 r.out.resume_handle = &resume_handle;
3206 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3207 if (!NT_STATUS_IS_OK(status)) {
3208 printf("EnumDomains failed - %s\n", nt_errstr(status));
3216 for (i=0;i<r.out.sam->count;i++) {
3217 if (!test_LookupDomain(p, mem_ctx, handle,
3218 &r.out.sam->entries[i].name)) {
3223 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3224 if (!NT_STATUS_IS_OK(status)) {
3225 printf("EnumDomains failed - %s\n", nt_errstr(status));
3233 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3234 struct policy_handle *handle)
3237 struct samr_Connect r;
3238 struct samr_Connect2 r2;
3239 struct samr_Connect3 r3;
3240 struct samr_Connect4 r4;
3241 struct samr_Connect5 r5;
3242 union samr_ConnectInfo info;
3243 struct policy_handle h;
3244 BOOL ret = True, got_handle = False;
3246 printf("testing samr_Connect\n");
3248 r.in.system_name = 0;
3249 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3250 r.out.connect_handle = &h;
3252 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3253 if (!NT_STATUS_IS_OK(status)) {
3254 printf("Connect failed - %s\n", nt_errstr(status));
3261 printf("testing samr_Connect2\n");
3263 r2.in.system_name = NULL;
3264 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3265 r2.out.connect_handle = &h;
3267 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3268 if (!NT_STATUS_IS_OK(status)) {
3269 printf("Connect2 failed - %s\n", nt_errstr(status));
3273 test_samr_handle_Close(p, mem_ctx, handle);
3279 printf("testing samr_Connect3\n");
3281 r3.in.system_name = NULL;
3283 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3284 r3.out.connect_handle = &h;
3286 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3287 if (!NT_STATUS_IS_OK(status)) {
3288 printf("Connect3 failed - %s\n", nt_errstr(status));
3292 test_samr_handle_Close(p, mem_ctx, handle);
3298 printf("testing samr_Connect4\n");
3300 r4.in.system_name = "";
3302 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3303 r4.out.connect_handle = &h;
3305 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3306 if (!NT_STATUS_IS_OK(status)) {
3307 printf("Connect4 failed - %s\n", nt_errstr(status));
3311 test_samr_handle_Close(p, mem_ctx, handle);
3317 printf("testing samr_Connect5\n");
3319 info.info1.unknown1 = 0;
3320 info.info1.unknown2 = 0;
3322 r5.in.system_name = "";
3323 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3326 r5.out.info = &info;
3327 r5.out.connect_handle = &h;
3329 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3330 if (!NT_STATUS_IS_OK(status)) {
3331 printf("Connect5 failed - %s\n", nt_errstr(status));
3335 test_samr_handle_Close(p, mem_ctx, handle);
3345 BOOL torture_rpc_samr(void)
3348 struct dcerpc_pipe *p;
3349 TALLOC_CTX *mem_ctx;
3351 struct policy_handle handle;
3353 mem_ctx = talloc_init("torture_rpc_samr");
3355 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3356 if (!NT_STATUS_IS_OK(status)) {
3357 talloc_free(mem_ctx);
3361 if (!test_Connect(p, mem_ctx, &handle)) {
3365 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3369 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3373 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3377 if (!test_Shutdown(p, mem_ctx, &handle)) {
3381 if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3385 talloc_free(mem_ctx);