r2552: Character set conversion and string handling updates.
[Samba/gebeck_regimport.git] / source4 / torture / rpc / samr.c
blob5a9462a92a408cd7265703c627f07d7538ec2615
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for samr rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 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.
23 #include "includes.h"
25 #define TEST_ACCOUNT_NAME "samrtorturetest"
26 #define TEST_ALIASNAME "samrtorturetestalias"
27 #define TEST_GROUPNAME "samrtorturetestgroup"
28 #define TEST_MACHINENAME "samrtorturetestmach$"
29 #define TEST_DOMAINNAME "samrtorturetestdom$"
32 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
33 struct policy_handle *handle);
35 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
36 struct policy_handle *handle);
38 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
39 struct policy_handle *handle);
41 static void init_samr_Name(struct samr_Name *name, const char *s)
43 name->name = s;
46 static BOOL test_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
47 struct policy_handle *handle)
49 NTSTATUS status;
50 struct samr_Close r;
52 r.in.handle = handle;
53 r.out.handle = handle;
55 status = dcerpc_samr_Close(p, mem_ctx, &r);
56 if (!NT_STATUS_IS_OK(status)) {
57 printf("Close handle failed - %s\n", nt_errstr(status));
58 return False;
61 return True;
64 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
65 struct policy_handle *handle)
67 NTSTATUS status;
68 struct samr_Shutdown r;
70 if (lp_parm_int(-1, "torture", "dangerous") != 1) {
71 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
72 return True;
75 r.in.connect_handle = handle;
77 printf("testing samr_Shutdown\n");
79 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
80 if (!NT_STATUS_IS_OK(status)) {
81 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
82 return False;
85 return True;
88 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
89 struct policy_handle *handle)
91 NTSTATUS status;
92 struct samr_SetDsrmPassword r;
93 struct samr_Name name;
94 struct samr_Password hash;
96 if (lp_parm_int(-1, "torture", "dangerous") != 1) {
97 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
98 return True;
101 E_md4hash("TeSTDSRM123", hash.hash);
103 init_samr_Name(&name, "Administrator");
105 r.in.name = &name;
106 r.in.unknown = 0;
107 r.in.hash = &hash;
109 printf("testing samr_SetDsrmPassword\n");
111 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
112 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
113 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
114 return False;
117 return True;
121 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
122 struct policy_handle *handle)
124 NTSTATUS status;
125 struct samr_QuerySecurity r;
126 struct samr_SetSecurity s;
128 r.in.handle = handle;
129 r.in.sec_info = 7;
131 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
132 if (!NT_STATUS_IS_OK(status)) {
133 printf("QuerySecurity failed - %s\n", nt_errstr(status));
134 return False;
137 if (r.out.sdbuf == NULL) {
138 return False;
141 s.in.handle = handle;
142 s.in.sec_info = 7;
143 s.in.sdbuf = r.out.sdbuf;
145 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
146 if (!NT_STATUS_IS_OK(status)) {
147 printf("SetSecurity failed - %s\n", nt_errstr(status));
148 return False;
151 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
152 if (!NT_STATUS_IS_OK(status)) {
153 printf("QuerySecurity failed - %s\n", nt_errstr(status));
154 return False;
157 return True;
161 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
162 struct policy_handle *handle)
164 NTSTATUS status;
165 struct samr_SetUserInfo s;
166 struct samr_SetUserInfo2 s2;
167 struct samr_QueryUserInfo q;
168 struct samr_QueryUserInfo q0;
169 union samr_UserInfo u;
170 BOOL ret = True;
172 s.in.user_handle = handle;
173 s.in.info = &u;
175 s2.in.user_handle = handle;
176 s2.in.info = &u;
178 q.in.user_handle = handle;
179 q.out.info = &u;
180 q0 = q;
182 #define TESTCALL(call, r) \
183 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
184 if (!NT_STATUS_IS_OK(status)) { \
185 printf(#call " level %u failed - %s (line %d)\n", \
186 r.in.level, nt_errstr(status), __LINE__); \
187 ret = False; \
188 break; \
191 #define STRING_EQUAL(s1, s2, field) \
192 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
193 printf("Failed to set %s to '%s' (line %d)\n", \
194 #field, s2, __LINE__); \
195 ret = False; \
196 break; \
199 #define INT_EQUAL(i1, i2, field) \
200 if (i1 != i2) { \
201 printf("Failed to set %s to %u (line %d)\n", \
202 #field, i2, __LINE__); \
203 ret = False; \
204 break; \
207 #define TEST_USERINFO_NAME(lvl1, field1, lvl2, field2, value, fpval) do { \
208 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
209 q.in.level = lvl1; \
210 TESTCALL(QueryUserInfo, q) \
211 s.in.level = lvl1; \
212 s2.in.level = lvl1; \
213 u = *q.out.info; \
214 if (lvl1 == 21) { \
215 ZERO_STRUCT(u.info21); \
216 u.info21.fields_present = fpval; \
218 init_samr_Name(&u.info ## lvl1.field1, value); \
219 TESTCALL(SetUserInfo, s) \
220 TESTCALL(SetUserInfo2, s2) \
221 init_samr_Name(&u.info ## lvl1.field1, ""); \
222 TESTCALL(QueryUserInfo, q); \
223 u = *q.out.info; \
224 STRING_EQUAL(u.info ## lvl1.field1.name, value, field1); \
225 q.in.level = lvl2; \
226 TESTCALL(QueryUserInfo, q) \
227 u = *q.out.info; \
228 STRING_EQUAL(u.info ## lvl2.field2.name, value, field2); \
229 } while (0)
231 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
232 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
233 q.in.level = lvl1; \
234 TESTCALL(QueryUserInfo, q) \
235 s.in.level = lvl1; \
236 s2.in.level = lvl1; \
237 u = *q.out.info; \
238 if (lvl1 == 21) { \
239 uint8_t *bitmap = u.info21.logon_hours.bitmap; \
240 ZERO_STRUCT(u.info21); \
241 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
242 u.info21.logon_hours.units_per_week = 168; \
243 u.info21.logon_hours.bitmap = bitmap; \
245 u.info21.fields_present = fpval; \
247 u.info ## lvl1.field1 = value; \
248 TESTCALL(SetUserInfo, s) \
249 TESTCALL(SetUserInfo2, s2) \
250 u.info ## lvl1.field1 = 0; \
251 TESTCALL(QueryUserInfo, q); \
252 u = *q.out.info; \
253 INT_EQUAL(u.info ## lvl1.field1, value, field1); \
254 q.in.level = lvl2; \
255 TESTCALL(QueryUserInfo, q) \
256 u = *q.out.info; \
257 INT_EQUAL(u.info ## lvl2.field2, value, field1); \
258 } while (0)
260 q0.in.level = 12;
261 do { TESTCALL(QueryUserInfo, q0) } while (0);
263 TEST_USERINFO_NAME(2, comment, 1, comment, "xx2-1 comment", 0);
264 TEST_USERINFO_NAME(2, comment, 21, comment, "xx2-21 comment", 0);
265 TEST_USERINFO_NAME(21, comment, 21, comment, "xx21-21 comment",
266 SAMR_FIELD_COMMENT);
268 TEST_USERINFO_NAME(6, full_name, 1, full_name, "xx6-1 full_name", 0);
269 TEST_USERINFO_NAME(6, full_name, 3, full_name, "xx6-3 full_name", 0);
270 TEST_USERINFO_NAME(6, full_name, 5, full_name, "xx6-5 full_name", 0);
271 TEST_USERINFO_NAME(6, full_name, 6, full_name, "xx6-6 full_name", 0);
272 TEST_USERINFO_NAME(6, full_name, 8, full_name, "xx6-8 full_name", 0);
273 TEST_USERINFO_NAME(6, full_name, 21, full_name, "xx6-21 full_name", 0);
274 TEST_USERINFO_NAME(8, full_name, 21, full_name, "xx8-21 full_name", 0);
275 TEST_USERINFO_NAME(21, full_name, 21, full_name, "xx21-21 full_name",
276 SAMR_FIELD_NAME);
278 TEST_USERINFO_NAME(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
279 TEST_USERINFO_NAME(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
280 TEST_USERINFO_NAME(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
281 TEST_USERINFO_NAME(21, logon_script, 21, logon_script, "xx21-21 logon_script",
282 SAMR_FIELD_LOGON_SCRIPT);
284 TEST_USERINFO_NAME(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
285 TEST_USERINFO_NAME(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
286 TEST_USERINFO_NAME(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
287 TEST_USERINFO_NAME(21, profile_path, 21, profile_path, "xx21-21 profile_path",
288 SAMR_FIELD_PROFILE_PATH);
290 TEST_USERINFO_NAME(13, description, 1, description, "xx13-1 description", 0);
291 TEST_USERINFO_NAME(13, description, 5, description, "xx13-5 description", 0);
292 TEST_USERINFO_NAME(13, description, 21, description, "xx13-21 description", 0);
293 TEST_USERINFO_NAME(21, description, 21, description, "xx21-21 description",
294 SAMR_FIELD_DESCRIPTION);
296 TEST_USERINFO_NAME(14, workstations, 3, workstations, "14workstation3", 0);
297 TEST_USERINFO_NAME(14, workstations, 5, workstations, "14workstation4", 0);
298 TEST_USERINFO_NAME(14, workstations, 21, workstations, "14workstation21", 0);
299 TEST_USERINFO_NAME(21, workstations, 21, workstations, "21workstation21",
300 SAMR_FIELD_WORKSTATION);
302 TEST_USERINFO_NAME(20, callback, 21, callback, "xx20-21 callback", 0);
303 TEST_USERINFO_NAME(21, callback, 21, callback, "xx21-21 callback",
304 SAMR_FIELD_CALLBACK);
306 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
307 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
308 SAMR_FIELD_COUNTRY_CODE);
310 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
311 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
312 SAMR_FIELD_CODE_PAGE);
314 TEST_USERINFO_INT(4, logon_hours.bitmap[3], 3, logon_hours.bitmap[3], 1, 0);
315 TEST_USERINFO_INT(4, logon_hours.bitmap[3], 5, logon_hours.bitmap[3], 2, 0);
316 TEST_USERINFO_INT(4, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], 3, 0);
317 TEST_USERINFO_INT(21, logon_hours.bitmap[3], 21, logon_hours.bitmap[3], 4,
318 SAMR_FIELD_LOGON_HOURS);
320 #if 0
321 /* these fail with win2003 - it appears you can't set the primary gid?
322 the set succeeds, but the gid isn't changed. Very weird! */
323 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
324 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
325 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
326 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
327 #endif
328 return ret;
332 generate a random password for password change tests
334 static char *samr_rand_pass(TALLOC_CTX *mem_ctx)
336 size_t len = 8 + (random() % 6);
337 char *s = generate_random_str(mem_ctx, len);
338 printf("Generated password '%s'\n", s);
339 return s;
342 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
343 struct policy_handle *handle, char **password)
345 NTSTATUS status;
346 struct samr_SetUserInfo s;
347 union samr_UserInfo u;
348 BOOL ret = True;
349 DATA_BLOB session_key;
350 char *newpass = samr_rand_pass(mem_ctx);
352 s.in.user_handle = handle;
353 s.in.info = &u;
354 s.in.level = 24;
356 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
357 /* w2k3 ignores this length */
358 u.info24.pw_len = strlen_m(newpass) * 2;
360 status = dcerpc_fetch_session_key(p, &session_key);
361 if (!NT_STATUS_IS_OK(status)) {
362 printf("SetUserInfo level %u - no session key - %s\n",
363 s.in.level, nt_errstr(status));
364 return False;
367 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
369 printf("Testing SetUserInfo level 24 (set password)\n");
371 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
372 if (!NT_STATUS_IS_OK(status)) {
373 printf("SetUserInfo level %u failed - %s\n",
374 s.in.level, nt_errstr(status));
375 ret = False;
376 } else {
377 *password = newpass;
380 return ret;
384 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
385 struct policy_handle *handle, char **password)
387 NTSTATUS status;
388 struct samr_SetUserInfo s;
389 union samr_UserInfo u;
390 BOOL ret = True;
391 DATA_BLOB session_key;
392 char *newpass = samr_rand_pass(mem_ctx);
394 s.in.user_handle = handle;
395 s.in.info = &u;
396 s.in.level = 23;
398 ZERO_STRUCT(u);
400 u.info23.info.fields_present = SAMR_FIELD_PASSWORD;
402 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
404 status = dcerpc_fetch_session_key(p, &session_key);
405 if (!NT_STATUS_IS_OK(status)) {
406 printf("SetUserInfo level %u - no session key - %s\n",
407 s.in.level, nt_errstr(status));
408 return False;
411 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
413 printf("Testing SetUserInfo level 23 (set password)\n");
415 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
416 if (!NT_STATUS_IS_OK(status)) {
417 printf("SetUserInfo level %u failed - %s\n",
418 s.in.level, nt_errstr(status));
419 ret = False;
420 } else {
421 *password = newpass;
424 return ret;
428 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
429 struct policy_handle *handle, char **password)
431 NTSTATUS status;
432 struct samr_SetUserInfo s;
433 union samr_UserInfo u;
434 BOOL ret = True;
435 DATA_BLOB session_key;
436 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
437 uint8_t confounder[16];
438 char *newpass = samr_rand_pass(mem_ctx);
439 struct MD5Context ctx;
441 s.in.user_handle = handle;
442 s.in.info = &u;
443 s.in.level = 26;
445 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
446 u.info26.pw_len = strlen(newpass);
448 status = dcerpc_fetch_session_key(p, &session_key);
449 if (!NT_STATUS_IS_OK(status)) {
450 printf("SetUserInfo level %u - no session key - %s\n",
451 s.in.level, nt_errstr(status));
452 return False;
455 generate_random_buffer((uint8_t *)confounder, 16);
457 MD5Init(&ctx);
458 MD5Update(&ctx, confounder, 16);
459 MD5Update(&ctx, session_key.data, session_key.length);
460 MD5Final(confounded_session_key.data, &ctx);
462 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
463 memcpy(&u.info26.password.data[516], confounder, 16);
465 printf("Testing SetUserInfo level 26 (set password ex)\n");
467 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
468 if (!NT_STATUS_IS_OK(status)) {
469 printf("SetUserInfo level %u failed - %s\n",
470 s.in.level, nt_errstr(status));
471 ret = False;
472 } else {
473 *password = newpass;
476 return ret;
479 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
480 struct policy_handle *handle, char **password)
482 NTSTATUS status;
483 struct samr_SetUserInfo s;
484 union samr_UserInfo u;
485 BOOL ret = True;
486 DATA_BLOB session_key;
487 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
488 uint8_t confounder[16];
489 char *newpass = samr_rand_pass(mem_ctx);
490 struct MD5Context ctx;
492 s.in.user_handle = handle;
493 s.in.info = &u;
494 s.in.level = 25;
496 ZERO_STRUCT(u);
498 u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
500 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
502 status = dcerpc_fetch_session_key(p, &session_key);
503 if (!NT_STATUS_IS_OK(status)) {
504 printf("SetUserInfo level %u - no session key - %s\n",
505 s.in.level, nt_errstr(status));
506 return False;
509 generate_random_buffer((uint8_t *)confounder, 16);
511 MD5Init(&ctx);
512 MD5Update(&ctx, confounder, 16);
513 MD5Update(&ctx, session_key.data, session_key.length);
514 MD5Final(confounded_session_key.data, &ctx);
516 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
517 memcpy(&u.info25.password.data[516], confounder, 16);
519 printf("Testing SetUserInfo level 25 (set password ex)\n");
521 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
522 if (!NT_STATUS_IS_OK(status)) {
523 printf("SetUserInfo level %u failed - %s\n",
524 s.in.level, nt_errstr(status));
525 ret = False;
526 } else {
527 *password = newpass;
530 return ret;
533 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
534 struct policy_handle *handle)
536 NTSTATUS status;
537 struct samr_SetAliasInfo r;
538 struct samr_QueryAliasInfo q;
539 uint16_t levels[] = {2, 3};
540 int i;
541 BOOL ret = True;
543 /* Ignoring switch level 1, as that includes the number of members for the alias
544 * and setting this to a wrong value might have negative consequences
547 for (i=0;i<ARRAY_SIZE(levels);i++) {
548 printf("Testing SetAliasInfo level %u\n", levels[i]);
550 r.in.alias_handle = handle;
551 r.in.level = levels[i];
552 switch (r.in.level) {
553 case 2 : init_samr_Name(&r.in.info.name,TEST_ALIASNAME); break;
554 case 3 : init_samr_Name(&r.in.info.description,
555 "Test Description, should test I18N as well"); break;
558 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
559 if (!NT_STATUS_IS_OK(status)) {
560 printf("SetAliasInfo level %u failed - %s\n",
561 levels[i], nt_errstr(status));
562 ret = False;
565 q.in.alias_handle = handle;
566 q.in.level = levels[i];
568 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
569 if (!NT_STATUS_IS_OK(status)) {
570 printf("QueryAliasInfo level %u failed - %s\n",
571 levels[i], nt_errstr(status));
572 ret = False;
576 return ret;
579 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
580 struct policy_handle *user_handle)
582 struct samr_GetGroupsForUser r;
583 NTSTATUS status;
584 BOOL ret = True;
586 printf("testing GetGroupsForUser\n");
588 r.in.user_handle = user_handle;
590 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
591 if (!NT_STATUS_IS_OK(status)) {
592 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
593 ret = False;
596 return ret;
600 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
601 struct samr_Name *domain_name)
603 NTSTATUS status;
604 struct samr_GetDomPwInfo r;
605 BOOL ret = True;
607 r.in.name = domain_name;
608 printf("Testing GetDomPwInfo with name %s\n", r.in.name->name);
610 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
611 if (!NT_STATUS_IS_OK(status)) {
612 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
613 ret = False;
616 r.in.name->name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
617 printf("Testing GetDomPwInfo with name %s\n", r.in.name->name);
619 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
620 if (!NT_STATUS_IS_OK(status)) {
621 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
622 ret = False;
625 r.in.name->name = "\\\\__NONAME__";
626 printf("Testing GetDomPwInfo with name %s\n", r.in.name->name);
628 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
629 if (!NT_STATUS_IS_OK(status)) {
630 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
631 ret = False;
634 r.in.name->name = "\\\\Builtin";
635 printf("Testing GetDomPwInfo with name %s\n", r.in.name->name);
637 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
638 if (!NT_STATUS_IS_OK(status)) {
639 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
640 ret = False;
644 return ret;
647 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
648 struct policy_handle *handle)
650 NTSTATUS status;
651 struct samr_GetUserPwInfo r;
652 BOOL ret = True;
654 printf("Testing GetUserPwInfo\n");
656 r.in.user_handle = handle;
658 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
659 if (!NT_STATUS_IS_OK(status)) {
660 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
661 ret = False;
664 return ret;
667 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
668 struct policy_handle *domain_handle, const char *name,
669 uint32_t *rid)
671 NTSTATUS status;
672 struct samr_LookupNames n;
673 struct samr_Name sname[2];
675 init_samr_Name(&sname[0], name);
677 n.in.domain_handle = domain_handle;
678 n.in.num_names = 1;
679 n.in.names = sname;
680 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
681 if (NT_STATUS_IS_OK(status)) {
682 *rid = n.out.rids.ids[0];
683 } else {
684 return status;
687 init_samr_Name(&sname[1], "xxNONAMExx");
688 n.in.num_names = 2;
689 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
690 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
691 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
692 return status;
695 init_samr_Name(&sname[1], "xxNONAMExx");
696 n.in.num_names = 0;
697 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
698 if (!NT_STATUS_IS_OK(status)) {
699 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
702 return status;
705 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
706 struct policy_handle *domain_handle,
707 const char *name, struct policy_handle *user_handle)
709 NTSTATUS status;
710 struct samr_OpenUser r;
711 uint32_t rid;
713 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
714 if (!NT_STATUS_IS_OK(status)) {
715 return status;
718 r.in.domain_handle = domain_handle;
719 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
720 r.in.rid = rid;
721 r.out.user_handle = user_handle;
722 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
723 if (!NT_STATUS_IS_OK(status)) {
724 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
727 return status;
730 #if 0
731 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
732 struct policy_handle *handle)
734 NTSTATUS status;
735 struct samr_ChangePasswordUser r;
736 BOOL ret = True;
737 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
738 struct policy_handle user_handle;
739 char *oldpass = "test";
740 char *newpass = "test2";
741 uint8_t old_nt_hash[16], new_nt_hash[16];
742 uint8_t old_lm_hash[16], new_lm_hash[16];
744 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
745 if (!NT_STATUS_IS_OK(status)) {
746 return False;
749 printf("Testing ChangePasswordUser for user 'testuser'\n");
751 printf("old password: %s\n", oldpass);
752 printf("new password: %s\n", newpass);
754 E_md4hash(oldpass, old_nt_hash);
755 E_md4hash(newpass, new_nt_hash);
756 E_deshash(oldpass, old_lm_hash);
757 E_deshash(newpass, new_lm_hash);
759 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
760 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
761 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
762 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
763 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
764 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
766 r.in.handle = &user_handle;
767 r.in.lm_present = 1;
768 r.in.old_lm_crypted = &hash1;
769 r.in.new_lm_crypted = &hash2;
770 r.in.nt_present = 1;
771 r.in.old_nt_crypted = &hash3;
772 r.in.new_nt_crypted = &hash4;
773 r.in.cross1_present = 1;
774 r.in.nt_cross = &hash5;
775 r.in.cross2_present = 1;
776 r.in.lm_cross = &hash6;
778 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
779 if (!NT_STATUS_IS_OK(status)) {
780 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
781 ret = False;
784 if (!test_Close(p, mem_ctx, &user_handle)) {
785 ret = False;
788 return ret;
790 #endif
792 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
793 struct policy_handle *handle, char **password)
795 NTSTATUS status;
796 struct samr_ChangePasswordUser r;
797 BOOL ret = True;
798 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
799 struct policy_handle user_handle;
800 char *oldpass = *password;
801 char *newpass = samr_rand_pass(mem_ctx);
802 uint8_t old_nt_hash[16], new_nt_hash[16];
803 uint8_t old_lm_hash[16], new_lm_hash[16];
805 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
806 if (!NT_STATUS_IS_OK(status)) {
807 return False;
810 printf("Testing ChangePasswordUser\n");
812 E_md4hash(oldpass, old_nt_hash);
813 E_md4hash(newpass, new_nt_hash);
814 E_deshash(oldpass, old_lm_hash);
815 E_deshash(newpass, new_lm_hash);
817 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
818 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
819 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
820 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
821 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
822 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
824 r.in.user_handle = &user_handle;
825 r.in.lm_present = 1;
826 r.in.old_lm_crypted = &hash1;
827 r.in.new_lm_crypted = &hash2;
828 r.in.nt_present = 1;
829 r.in.old_nt_crypted = &hash3;
830 r.in.new_nt_crypted = &hash4;
831 r.in.cross1_present = 1;
832 r.in.nt_cross = &hash5;
833 r.in.cross2_present = 1;
834 r.in.lm_cross = &hash6;
836 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
837 if (!NT_STATUS_IS_OK(status)) {
838 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
839 ret = False;
840 } else {
841 *password = newpass;
844 if (!test_Close(p, mem_ctx, &user_handle)) {
845 ret = False;
848 return ret;
852 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
853 struct policy_handle *handle, char **password)
855 NTSTATUS status;
856 struct samr_OemChangePasswordUser2 r;
857 BOOL ret = True;
858 struct samr_Password lm_verifier;
859 struct samr_CryptPassword lm_pass;
860 struct samr_AsciiName server, account;
861 char *oldpass = *password;
862 char *newpass = samr_rand_pass(mem_ctx);
863 uint8_t old_lm_hash[16], new_lm_hash[16];
865 printf("Testing OemChangePasswordUser2\n");
867 server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
868 account.name = TEST_ACCOUNT_NAME;
870 E_deshash(oldpass, old_lm_hash);
871 E_deshash(newpass, new_lm_hash);
873 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
874 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
875 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
877 r.in.server = &server;
878 r.in.account = &account;
879 r.in.password = &lm_pass;
880 r.in.hash = &lm_verifier;
882 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
883 if (!NT_STATUS_IS_OK(status)) {
884 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
885 ret = False;
886 } else {
887 *password = newpass;
890 return ret;
894 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
895 struct policy_handle *handle, char **password)
897 NTSTATUS status;
898 struct samr_ChangePasswordUser2 r;
899 BOOL ret = True;
900 struct samr_Name server, account;
901 struct samr_CryptPassword nt_pass, lm_pass;
902 struct samr_Password nt_verifier, lm_verifier;
903 char *oldpass = *password;
904 char *newpass = samr_rand_pass(mem_ctx);
905 uint8_t old_nt_hash[16], new_nt_hash[16];
906 uint8_t old_lm_hash[16], new_lm_hash[16];
908 printf("Testing ChangePasswordUser2\n");
910 server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
911 init_samr_Name(&account, TEST_ACCOUNT_NAME);
913 E_md4hash(oldpass, old_nt_hash);
914 E_md4hash(newpass, new_nt_hash);
916 E_deshash(oldpass, old_lm_hash);
917 E_deshash(newpass, new_lm_hash);
919 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
920 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
921 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
923 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
924 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
925 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
927 r.in.server = &server;
928 r.in.account = &account;
929 r.in.nt_password = &nt_pass;
930 r.in.nt_verifier = &nt_verifier;
931 r.in.lm_change = 1;
932 r.in.lm_password = &lm_pass;
933 r.in.lm_verifier = &lm_verifier;
935 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
936 if (!NT_STATUS_IS_OK(status)) {
937 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
938 ret = False;
939 } else {
940 *password = newpass;
943 return ret;
947 static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
948 struct policy_handle *handle, char **password)
950 NTSTATUS status;
951 struct samr_ChangePasswordUser3 r;
952 BOOL ret = True;
953 struct samr_Name server, account;
954 struct samr_CryptPassword nt_pass, lm_pass;
955 struct samr_Password nt_verifier, lm_verifier;
956 char *oldpass = *password;
957 char *newpass = samr_rand_pass(mem_ctx);
958 uint8_t old_nt_hash[16], new_nt_hash[16];
959 uint8_t old_lm_hash[16], new_lm_hash[16];
961 printf("Testing ChangePasswordUser3\n");
963 server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
964 init_samr_Name(&account, TEST_ACCOUNT_NAME);
966 E_md4hash(oldpass, old_nt_hash);
967 E_md4hash(newpass, new_nt_hash);
969 E_deshash(oldpass, old_lm_hash);
970 E_deshash(newpass, new_lm_hash);
972 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
973 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
974 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
976 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
977 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
978 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
980 r.in.server = &server;
981 r.in.account = &account;
982 r.in.nt_password = &nt_pass;
983 r.in.nt_verifier = &nt_verifier;
984 r.in.lm_change = 1;
985 r.in.lm_password = &lm_pass;
986 r.in.lm_verifier = &lm_verifier;
987 r.in.password3 = NULL;
989 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
990 if (!NT_STATUS_IS_OK(status)) {
991 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
992 ret = False;
993 } else {
994 *password = newpass;
997 return ret;
1001 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1002 struct policy_handle *alias_handle)
1004 struct samr_GetMembersInAlias r;
1005 struct lsa_SidArray sids;
1006 NTSTATUS status;
1007 BOOL ret = True;
1009 printf("Testing GetMembersInAlias\n");
1011 r.in.alias_handle = alias_handle;
1012 r.out.sids = &sids;
1014 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1015 if (!NT_STATUS_IS_OK(status)) {
1016 printf("GetMembersInAlias failed - %s\n",
1017 nt_errstr(status));
1018 ret = False;
1021 return ret;
1024 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1025 struct policy_handle *alias_handle,
1026 const struct dom_sid *domain_sid)
1028 struct samr_AddAliasMember r;
1029 struct samr_DeleteAliasMember d;
1030 NTSTATUS status;
1031 BOOL ret = True;
1032 struct dom_sid *sid;
1034 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1036 printf("testing AddAliasMember\n");
1037 r.in.alias_handle = alias_handle;
1038 r.in.sid = sid;
1040 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1043 ret = False;
1046 d.in.alias_handle = alias_handle;
1047 d.in.sid = sid;
1049 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1050 if (!NT_STATUS_IS_OK(status)) {
1051 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1052 ret = False;
1055 return ret;
1058 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1059 struct policy_handle *alias_handle)
1061 struct samr_AddMultipleMembersToAlias a;
1062 struct samr_RemoveMultipleMembersFromAlias r;
1063 NTSTATUS status;
1064 BOOL ret = True;
1065 struct lsa_SidArray sids;
1067 printf("testing AddMultipleMembersToAlias\n");
1068 a.in.alias_handle = alias_handle;
1069 a.in.sids = &sids;
1071 sids.num_sids = 3;
1072 sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr, 3);
1074 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1075 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1076 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1078 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1079 if (!NT_STATUS_IS_OK(status)) {
1080 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1081 ret = False;
1085 printf("testing RemoveMultipleMembersFromAlias\n");
1086 r.in.alias_handle = alias_handle;
1087 r.in.sids = &sids;
1089 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1090 if (!NT_STATUS_IS_OK(status)) {
1091 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1092 ret = False;
1095 /* strange! removing twice doesn't give any error */
1096 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1099 ret = False;
1102 /* but removing an alias that isn't there does */
1103 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1105 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1106 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1107 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1108 ret = False;
1111 return ret;
1114 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1115 struct policy_handle *user_handle)
1117 struct samr_TestPrivateFunctionsUser r;
1118 NTSTATUS status;
1119 BOOL ret = True;
1121 printf("Testing TestPrivateFunctionsUser\n");
1123 r.in.user_handle = user_handle;
1125 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1126 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1127 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1128 ret = False;
1131 return ret;
1135 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1136 struct policy_handle *handle)
1138 BOOL ret = True;
1140 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1141 ret = False;
1144 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1145 ret = False;
1148 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1149 ret = False;
1152 if (!test_SetUserInfo(p, mem_ctx, handle)) {
1153 ret = False;
1156 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1157 ret = False;
1160 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1161 ret = False;
1164 return ret;
1167 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1168 struct policy_handle *alias_handle,
1169 const struct dom_sid *domain_sid)
1171 BOOL ret = True;
1173 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1174 ret = False;
1177 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1178 ret = False;
1181 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1182 ret = False;
1185 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1186 ret = False;
1189 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1190 ret = False;
1193 return ret;
1197 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1198 struct policy_handle *handle, const char *name)
1200 NTSTATUS status;
1201 struct samr_DeleteUser d;
1202 struct policy_handle user_handle;
1203 uint32_t rid;
1205 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1206 if (!NT_STATUS_IS_OK(status)) {
1207 goto failed;
1210 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 goto failed;
1215 d.in.user_handle = &user_handle;
1216 d.out.user_handle = &user_handle;
1217 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1218 if (!NT_STATUS_IS_OK(status)) {
1219 goto failed;
1222 return True;
1224 failed:
1225 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1226 return False;
1230 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1231 struct policy_handle *handle, const char *name)
1233 NTSTATUS status;
1234 struct samr_OpenGroup r;
1235 struct samr_DeleteDomainGroup d;
1236 struct policy_handle group_handle;
1237 uint32_t rid;
1239 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1240 if (!NT_STATUS_IS_OK(status)) {
1241 goto failed;
1244 r.in.domain_handle = handle;
1245 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1246 r.in.rid = rid;
1247 r.out.group_handle = &group_handle;
1248 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1249 if (!NT_STATUS_IS_OK(status)) {
1250 goto failed;
1253 d.in.group_handle = &group_handle;
1254 d.out.group_handle = &group_handle;
1255 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1256 if (!NT_STATUS_IS_OK(status)) {
1257 goto failed;
1260 return True;
1262 failed:
1263 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1264 return False;
1268 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1269 struct policy_handle *domain_handle, const char *name)
1271 NTSTATUS status;
1272 struct samr_OpenAlias r;
1273 struct samr_DeleteDomAlias d;
1274 struct policy_handle alias_handle;
1275 uint32_t rid;
1277 printf("testing DeleteAlias_byname\n");
1279 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1280 if (!NT_STATUS_IS_OK(status)) {
1281 goto failed;
1284 r.in.domain_handle = domain_handle;
1285 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1286 r.in.rid = rid;
1287 r.out.alias_handle = &alias_handle;
1288 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 goto failed;
1293 d.in.alias_handle = &alias_handle;
1294 d.out.alias_handle = &alias_handle;
1295 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1296 if (!NT_STATUS_IS_OK(status)) {
1297 goto failed;
1300 return True;
1302 failed:
1303 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1304 return False;
1307 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1308 struct policy_handle *alias_handle)
1310 struct samr_DeleteDomAlias d;
1311 NTSTATUS status;
1312 BOOL ret = True;
1313 printf("Testing DeleteAlias\n");
1315 d.in.alias_handle = alias_handle;
1316 d.out.alias_handle = alias_handle;
1318 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1319 if (!NT_STATUS_IS_OK(status)) {
1320 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1321 ret = False;
1324 return ret;
1327 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1328 struct policy_handle *domain_handle,
1329 struct policy_handle *alias_handle,
1330 const struct dom_sid *domain_sid)
1332 NTSTATUS status;
1333 struct samr_CreateDomAlias r;
1334 struct samr_Name name;
1335 uint32_t rid;
1336 BOOL ret = True;
1338 init_samr_Name(&name, TEST_ALIASNAME);
1339 r.in.domain_handle = domain_handle;
1340 r.in.aliasname = &name;
1341 r.in.access_mask = SEC_RIGHT_MAXIMUM_ALLOWED;
1342 r.out.alias_handle = alias_handle;
1343 r.out.rid = &rid;
1345 printf("Testing CreateAlias (%s)\n", r.in.aliasname->name);
1347 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1349 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1350 printf("Server refused create of '%s'\n", r.in.aliasname->name);
1351 return True;
1354 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1355 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.aliasname->name)) {
1356 return False;
1358 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1361 if (!NT_STATUS_IS_OK(status)) {
1362 printf("CreateAlias failed - %s\n", nt_errstr(status));
1363 return False;
1366 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1367 ret = False;
1370 return ret;
1373 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1374 struct policy_handle *domain_handle, char **password)
1376 BOOL ret = True;
1378 if (!*password) {
1379 return False;
1382 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1383 ret = False;
1386 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1387 ret = False;
1390 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1391 ret = False;
1394 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, password)) {
1395 ret = False;
1398 return ret;
1401 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1402 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1404 NTSTATUS status;
1405 struct samr_CreateUser r;
1406 struct samr_QueryUserInfo q;
1407 uint32_t rid;
1408 char *password = NULL;
1410 /* This call creates a 'normal' account - check that it really does */
1411 const uint32_t acct_flags = ACB_NORMAL;
1412 struct samr_Name name;
1413 BOOL ret = True;
1415 init_samr_Name(&name, TEST_ACCOUNT_NAME);
1417 r.in.domain_handle = domain_handle;
1418 r.in.account_name = &name;
1419 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1420 r.out.user_handle = user_handle;
1421 r.out.rid = &rid;
1423 printf("Testing CreateUser(%s)\n", r.in.account_name->name);
1425 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1427 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1428 printf("Server refused create of '%s'\n", r.in.account_name->name);
1429 ZERO_STRUCTP(user_handle);
1430 return True;
1433 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1434 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.account_name->name)) {
1435 return False;
1437 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1439 if (!NT_STATUS_IS_OK(status)) {
1440 printf("CreateUser failed - %s\n", nt_errstr(status));
1441 return False;
1444 q.in.user_handle = user_handle;
1445 q.in.level = 16;
1447 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1448 if (!NT_STATUS_IS_OK(status)) {
1449 printf("QueryUserInfo level %u failed - %s\n",
1450 q.in.level, nt_errstr(status));
1451 ret = False;
1452 } else {
1453 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1454 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1455 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1456 acct_flags, acct_flags);
1457 ret = False;
1461 if (!test_user_ops(p, mem_ctx, user_handle)) {
1462 ret = False;
1465 if (!test_SetUserPass(p, mem_ctx, user_handle, &password)) {
1466 ret = False;
1469 if (!test_SetUserPass_23(p, mem_ctx, user_handle, &password)) {
1470 ret = False;
1473 if (!test_SetUserPassEx(p, mem_ctx, user_handle, &password)) {
1474 ret = False;
1477 if (!test_SetUserPass_25(p, mem_ctx, user_handle, &password)) {
1478 ret = False;
1481 /* we change passwords twice - this has the effect of verifying
1482 they were changed correctly */
1483 if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1484 ret = False;
1487 if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1488 ret = False;
1492 return ret;
1496 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1497 struct policy_handle *user_handle)
1499 struct samr_DeleteUser d;
1500 NTSTATUS status;
1501 BOOL ret = True;
1503 printf("Testing DeleteUser\n");
1505 d.in.user_handle = user_handle;
1506 d.out.user_handle = user_handle;
1508 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1509 if (!NT_STATUS_IS_OK(status)) {
1510 printf("DeleteUser failed - %s\n", nt_errstr(status));
1511 ret = False;
1514 return ret;
1517 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1518 struct policy_handle *handle)
1520 NTSTATUS status;
1521 struct samr_CreateUser2 r;
1522 struct samr_QueryUserInfo q;
1523 struct samr_DeleteUser d;
1524 struct policy_handle user_handle;
1525 uint32_t rid;
1526 struct samr_Name name;
1527 BOOL ret = True;
1528 int i;
1530 struct {
1531 uint32_t acct_flags;
1532 const char *account_name;
1533 NTSTATUS nt_status;
1534 } account_types[] = {
1535 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1536 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1537 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1538 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1539 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1540 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1541 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1542 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1543 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1544 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1545 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1546 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1547 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1548 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1549 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1552 for (i = 0; account_types[i].account_name; i++) {
1553 uint32_t acct_flags = account_types[i].acct_flags;
1554 uint32_t access_granted;
1556 init_samr_Name(&name, account_types[i].account_name);
1558 r.in.domain_handle = handle;
1559 r.in.account_name = &name;
1560 r.in.acct_flags = acct_flags;
1561 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1562 r.out.user_handle = &user_handle;
1563 r.out.access_granted = &access_granted;
1564 r.out.rid = &rid;
1566 printf("Testing CreateUser2(%s)\n", r.in.account_name->name);
1568 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1570 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1571 printf("Server refused create of '%s'\n", r.in.account_name->name);
1572 continue;
1574 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1575 if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.account_name->name)) {
1576 return False;
1578 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1581 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1582 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1583 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1584 ret = False;
1587 if (NT_STATUS_IS_OK(status)) {
1588 q.in.user_handle = &user_handle;
1589 q.in.level = 16;
1591 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1592 if (!NT_STATUS_IS_OK(status)) {
1593 printf("QueryUserInfo level %u failed - %s\n",
1594 q.in.level, nt_errstr(status));
1595 ret = False;
1596 } else {
1597 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1598 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1599 q.out.info->info16.acct_flags,
1600 acct_flags);
1601 ret = False;
1605 if (!test_user_ops(p, mem_ctx, &user_handle)) {
1606 ret = False;
1609 printf("Testing DeleteUser (createuser2 test)\n");
1611 d.in.user_handle = &user_handle;
1612 d.out.user_handle = &user_handle;
1614 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1615 if (!NT_STATUS_IS_OK(status)) {
1616 printf("DeleteUser failed - %s\n", nt_errstr(status));
1617 ret = False;
1622 return ret;
1625 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1626 struct policy_handle *handle)
1628 NTSTATUS status;
1629 struct samr_QueryAliasInfo r;
1630 uint16_t levels[] = {1, 2, 3};
1631 int i;
1632 BOOL ret = True;
1634 for (i=0;i<ARRAY_SIZE(levels);i++) {
1635 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1637 r.in.alias_handle = handle;
1638 r.in.level = levels[i];
1640 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1641 if (!NT_STATUS_IS_OK(status)) {
1642 printf("QueryAliasInfo level %u failed - %s\n",
1643 levels[i], nt_errstr(status));
1644 ret = False;
1648 return ret;
1651 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1652 struct policy_handle *handle)
1654 NTSTATUS status;
1655 struct samr_QueryGroupInfo r;
1656 uint16_t levels[] = {1, 2, 3, 4};
1657 int i;
1658 BOOL ret = True;
1660 for (i=0;i<ARRAY_SIZE(levels);i++) {
1661 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1663 r.in.group_handle = handle;
1664 r.in.level = levels[i];
1666 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1667 if (!NT_STATUS_IS_OK(status)) {
1668 printf("QueryGroupInfo level %u failed - %s\n",
1669 levels[i], nt_errstr(status));
1670 ret = False;
1674 return ret;
1678 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1679 struct policy_handle *handle)
1681 NTSTATUS status;
1682 struct samr_QueryGroupInfo r;
1683 struct samr_SetGroupInfo s;
1684 uint16_t levels[] = {1, 2, 3, 4};
1685 uint16_t set_ok[] = {0, 1, 1, 1};
1686 int i;
1687 BOOL ret = True;
1689 for (i=0;i<ARRAY_SIZE(levels);i++) {
1690 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1692 r.in.group_handle = handle;
1693 r.in.level = levels[i];
1695 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1696 if (!NT_STATUS_IS_OK(status)) {
1697 printf("QueryGroupInfo level %u failed - %s\n",
1698 levels[i], nt_errstr(status));
1699 ret = False;
1702 printf("Testing SetGroupInfo level %u\n", levels[i]);
1704 s.in.group_handle = handle;
1705 s.in.level = levels[i];
1706 s.in.info = r.out.info;
1708 #if 0
1709 /* disabled this, as it changes the name only from the point of view of samr,
1710 but leaves the name from the point of view of w2k3 internals (and ldap). This means
1711 the name is still reserved, so creating the old name fails, but deleting by the old name
1712 also fails */
1713 if (s.in.level == 2) {
1714 init_samr_Name(&s.in.info->name, "NewName");
1716 #endif
1718 if (s.in.level == 4) {
1719 init_samr_Name(&s.in.info->description, "test description");
1722 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1723 if (set_ok[i]) {
1724 if (!NT_STATUS_IS_OK(status)) {
1725 printf("SetGroupInfo level %u failed - %s\n",
1726 r.in.level, nt_errstr(status));
1727 ret = False;
1728 continue;
1730 } else {
1731 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1732 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
1733 r.in.level, nt_errstr(status));
1734 ret = False;
1735 continue;
1740 return ret;
1743 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1744 struct policy_handle *handle)
1746 NTSTATUS status;
1747 struct samr_QueryUserInfo r;
1748 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1749 11, 12, 13, 14, 16, 17, 20, 21};
1750 int i;
1751 BOOL ret = True;
1753 for (i=0;i<ARRAY_SIZE(levels);i++) {
1754 printf("Testing QueryUserInfo level %u\n", levels[i]);
1756 r.in.user_handle = handle;
1757 r.in.level = levels[i];
1759 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1760 if (!NT_STATUS_IS_OK(status)) {
1761 printf("QueryUserInfo level %u failed - %s\n",
1762 levels[i], nt_errstr(status));
1763 ret = False;
1767 return ret;
1770 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1771 struct policy_handle *handle)
1773 NTSTATUS status;
1774 struct samr_QueryUserInfo2 r;
1775 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1776 11, 12, 13, 14, 16, 17, 20, 21};
1777 int i;
1778 BOOL ret = True;
1780 for (i=0;i<ARRAY_SIZE(levels);i++) {
1781 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1783 r.in.user_handle = handle;
1784 r.in.level = levels[i];
1786 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1787 if (!NT_STATUS_IS_OK(status)) {
1788 printf("QueryUserInfo2 level %u failed - %s\n",
1789 levels[i], nt_errstr(status));
1790 ret = False;
1794 return ret;
1797 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1798 struct policy_handle *handle, uint32_t rid)
1800 NTSTATUS status;
1801 struct samr_OpenUser r;
1802 struct policy_handle user_handle;
1803 BOOL ret = True;
1805 printf("Testing OpenUser(%u)\n", rid);
1807 r.in.domain_handle = handle;
1808 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1809 r.in.rid = rid;
1810 r.out.user_handle = &user_handle;
1812 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1813 if (!NT_STATUS_IS_OK(status)) {
1814 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
1815 return False;
1818 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
1819 ret = False;
1822 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
1823 ret = False;
1826 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
1827 ret = False;
1830 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
1831 ret = False;
1834 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
1835 ret = False;
1838 if (!test_Close(p, mem_ctx, &user_handle)) {
1839 ret = False;
1842 return ret;
1845 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1846 struct policy_handle *handle, uint32_t rid)
1848 NTSTATUS status;
1849 struct samr_OpenGroup r;
1850 struct policy_handle group_handle;
1851 BOOL ret = True;
1853 printf("Testing OpenGroup(%u)\n", rid);
1855 r.in.domain_handle = handle;
1856 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1857 r.in.rid = rid;
1858 r.out.group_handle = &group_handle;
1860 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1861 if (!NT_STATUS_IS_OK(status)) {
1862 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
1863 return False;
1866 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
1867 ret = False;
1870 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
1871 ret = False;
1874 if (!test_Close(p, mem_ctx, &group_handle)) {
1875 ret = False;
1878 return ret;
1881 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1882 struct policy_handle *handle, uint32_t rid)
1884 NTSTATUS status;
1885 struct samr_OpenAlias r;
1886 struct policy_handle alias_handle;
1887 BOOL ret = True;
1889 printf("Testing OpenAlias(%u)\n", rid);
1891 r.in.domain_handle = handle;
1892 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1893 r.in.rid = rid;
1894 r.out.alias_handle = &alias_handle;
1896 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
1899 return False;
1902 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
1903 ret = False;
1906 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
1907 ret = False;
1910 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
1911 ret = False;
1914 if (!test_Close(p, mem_ctx, &alias_handle)) {
1915 ret = False;
1918 return ret;
1921 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1922 struct policy_handle *handle)
1924 NTSTATUS status;
1925 struct samr_EnumDomainUsers r;
1926 uint32_t resume_handle=0;
1927 int i;
1928 BOOL ret = True;
1929 struct samr_LookupNames n;
1930 struct samr_LookupRids lr ;
1932 printf("Testing EnumDomainUsers\n");
1934 r.in.domain_handle = handle;
1935 r.in.resume_handle = &resume_handle;
1936 r.in.acct_flags = 0;
1937 r.in.max_size = (uint32_t)-1;
1938 r.out.resume_handle = &resume_handle;
1940 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
1941 if (!NT_STATUS_IS_OK(status)) {
1942 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
1943 return False;
1946 if (!r.out.sam) {
1947 return False;
1950 if (r.out.sam->count == 0) {
1951 return True;
1954 for (i=0;i<r.out.sam->count;i++) {
1955 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1956 ret = False;
1960 printf("Testing LookupNames\n");
1961 n.in.domain_handle = handle;
1962 n.in.num_names = r.out.sam->count;
1963 n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
1964 for (i=0;i<r.out.sam->count;i++) {
1965 n.in.names[i] = r.out.sam->entries[i].name;
1967 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
1968 if (!NT_STATUS_IS_OK(status)) {
1969 printf("LookupNames failed - %s\n", nt_errstr(status));
1970 ret = False;
1974 printf("Testing LookupRids\n");
1975 lr.in.domain_handle = handle;
1976 lr.in.num_rids = r.out.sam->count;
1977 lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32_t));
1978 for (i=0;i<r.out.sam->count;i++) {
1979 lr.in.rids[i] = r.out.sam->entries[i].idx;
1981 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
1982 if (!NT_STATUS_IS_OK(status)) {
1983 printf("LookupRids failed - %s\n", nt_errstr(status));
1984 ret = False;
1987 return ret;
1991 try blasting the server with a bunch of sync requests
1993 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1994 struct policy_handle *handle)
1996 NTSTATUS status;
1997 struct samr_EnumDomainUsers r;
1998 uint32_t resume_handle=0;
1999 int i;
2000 #define ASYNC_COUNT 100
2001 struct rpc_request *req[ASYNC_COUNT];
2003 if (lp_parm_int(-1, "torture", "dangerous") != 1) {
2004 printf("samr async test disabled - enable dangerous tests to use\n");
2005 return True;
2008 printf("Testing EnumDomainUsers_async\n");
2010 r.in.domain_handle = handle;
2011 r.in.resume_handle = &resume_handle;
2012 r.in.acct_flags = 0;
2013 r.in.max_size = (uint32_t)-1;
2014 r.out.resume_handle = &resume_handle;
2016 for (i=0;i<ASYNC_COUNT;i++) {
2017 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2020 for (i=0;i<ASYNC_COUNT;i++) {
2021 status = dcerpc_ndr_request_recv(req[i]);
2022 if (!NT_STATUS_IS_OK(status)) {
2023 printf("EnumDomainUsers[%d] failed - %s\n",
2024 i, nt_errstr(status));
2025 return False;
2029 printf("%d async requests OK\n", i);
2031 return True;
2034 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2035 struct policy_handle *handle)
2037 NTSTATUS status;
2038 struct samr_EnumDomainGroups r;
2039 uint32_t resume_handle=0;
2040 int i;
2041 BOOL ret = True;
2043 printf("Testing EnumDomainGroups\n");
2045 r.in.domain_handle = handle;
2046 r.in.resume_handle = &resume_handle;
2047 r.in.max_size = (uint32_t)-1;
2048 r.out.resume_handle = &resume_handle;
2050 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2051 if (!NT_STATUS_IS_OK(status)) {
2052 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2053 return False;
2056 if (!r.out.sam) {
2057 return False;
2060 for (i=0;i<r.out.sam->count;i++) {
2061 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2062 ret = False;
2066 return ret;
2069 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2070 struct policy_handle *handle)
2072 NTSTATUS status;
2073 struct samr_EnumDomainAliases r;
2074 uint32_t resume_handle=0;
2075 int i;
2076 BOOL ret = True;
2078 printf("Testing EnumDomainAliases\n");
2080 r.in.domain_handle = handle;
2081 r.in.resume_handle = &resume_handle;
2082 r.in.acct_flags = (uint32_t)-1;
2083 r.out.resume_handle = &resume_handle;
2085 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2086 if (!NT_STATUS_IS_OK(status)) {
2087 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2088 return False;
2091 if (!r.out.sam) {
2092 return False;
2095 for (i=0;i<r.out.sam->count;i++) {
2096 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2097 ret = False;
2101 return ret;
2104 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2105 struct policy_handle *handle)
2107 NTSTATUS status;
2108 struct samr_GetDisplayEnumerationIndex r;
2109 BOOL ret = True;
2110 uint16_t levels[] = {1, 2, 3, 4, 5};
2111 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2112 int i;
2114 for (i=0;i<ARRAY_SIZE(levels);i++) {
2115 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2117 r.in.domain_handle = handle;
2118 r.in.level = levels[i];
2119 init_samr_Name(&r.in.name, TEST_ACCOUNT_NAME);
2121 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2123 if (ok_lvl[i] &&
2124 !NT_STATUS_IS_OK(status) &&
2125 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2126 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2127 levels[i], nt_errstr(status));
2128 ret = False;
2131 init_samr_Name(&r.in.name, "zzzzzzzz");
2133 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2135 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2136 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2137 levels[i], nt_errstr(status));
2138 ret = False;
2142 return ret;
2145 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2146 struct policy_handle *handle)
2148 NTSTATUS status;
2149 struct samr_GetDisplayEnumerationIndex2 r;
2150 BOOL ret = True;
2151 uint16_t levels[] = {1, 2, 3, 4, 5};
2152 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2153 int i;
2155 for (i=0;i<ARRAY_SIZE(levels);i++) {
2156 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2158 r.in.domain_handle = handle;
2159 r.in.level = levels[i];
2160 init_samr_Name(&r.in.name, TEST_ACCOUNT_NAME);
2162 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2163 if (ok_lvl[i] &&
2164 !NT_STATUS_IS_OK(status) &&
2165 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2166 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2167 levels[i], nt_errstr(status));
2168 ret = False;
2171 init_samr_Name(&r.in.name, "zzzzzzzz");
2173 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2174 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2175 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2176 levels[i], nt_errstr(status));
2177 ret = False;
2181 return ret;
2184 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2185 struct policy_handle *handle)
2187 NTSTATUS status;
2188 struct samr_QueryDisplayInfo r;
2189 BOOL ret = True;
2190 uint16_t levels[] = {1, 2, 3, 4, 5};
2191 int i;
2193 for (i=0;i<ARRAY_SIZE(levels);i++) {
2194 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2196 r.in.domain_handle = handle;
2197 r.in.level = levels[i];
2198 r.in.start_idx = 0;
2199 r.in.max_entries = 1000;
2200 r.in.buf_size = (uint32_t)-1;
2202 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2203 if (!NT_STATUS_IS_OK(status)) {
2204 printf("QueryDisplayInfo level %u failed - %s\n",
2205 levels[i], nt_errstr(status));
2206 ret = False;
2210 return ret;
2213 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2214 struct policy_handle *handle)
2216 NTSTATUS status;
2217 struct samr_QueryDisplayInfo2 r;
2218 BOOL ret = True;
2219 uint16_t levels[] = {1, 2, 3, 4, 5};
2220 int i;
2222 for (i=0;i<ARRAY_SIZE(levels);i++) {
2223 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2225 r.in.domain_handle = handle;
2226 r.in.level = levels[i];
2227 r.in.start_idx = 0;
2228 r.in.max_entries = 1000;
2229 r.in.buf_size = (uint32_t)-1;
2231 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2232 if (!NT_STATUS_IS_OK(status)) {
2233 printf("QueryDisplayInfo2 level %u failed - %s\n",
2234 levels[i], nt_errstr(status));
2235 ret = False;
2239 return ret;
2242 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2243 struct policy_handle *handle)
2245 NTSTATUS status;
2246 struct samr_QueryDisplayInfo3 r;
2247 BOOL ret = True;
2248 uint16_t levels[] = {1, 2, 3, 4, 5};
2249 int i;
2251 for (i=0;i<ARRAY_SIZE(levels);i++) {
2252 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2254 r.in.domain_handle = handle;
2255 r.in.level = levels[i];
2256 r.in.start_idx = 0;
2257 r.in.max_entries = 1000;
2258 r.in.buf_size = (uint32_t)-1;
2260 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2261 if (!NT_STATUS_IS_OK(status)) {
2262 printf("QueryDisplayInfo3 level %u failed - %s\n",
2263 levels[i], nt_errstr(status));
2264 ret = False;
2268 return ret;
2271 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2272 struct policy_handle *handle)
2274 NTSTATUS status;
2275 struct samr_QueryDomainInfo r;
2276 struct samr_SetDomainInfo s;
2277 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2278 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2279 int i;
2280 BOOL ret = True;
2282 for (i=0;i<ARRAY_SIZE(levels);i++) {
2283 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2285 r.in.domain_handle = handle;
2286 r.in.level = levels[i];
2288 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2289 if (!NT_STATUS_IS_OK(status)) {
2290 printf("QueryDomainInfo level %u failed - %s\n",
2291 r.in.level, nt_errstr(status));
2292 ret = False;
2293 continue;
2296 printf("Testing SetDomainInfo level %u\n", levels[i]);
2298 s.in.domain_handle = handle;
2299 s.in.level = levels[i];
2300 s.in.info = r.out.info;
2302 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2303 if (set_ok[i]) {
2304 if (!NT_STATUS_IS_OK(status)) {
2305 printf("SetDomainInfo level %u failed - %s\n",
2306 r.in.level, nt_errstr(status));
2307 ret = False;
2308 continue;
2310 } else {
2311 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2312 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2313 r.in.level, nt_errstr(status));
2314 ret = False;
2315 continue;
2319 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2320 if (!NT_STATUS_IS_OK(status)) {
2321 printf("QueryDomainInfo level %u failed - %s\n",
2322 r.in.level, nt_errstr(status));
2323 ret = False;
2324 continue;
2328 return True;
2332 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2333 struct policy_handle *handle)
2335 NTSTATUS status;
2336 struct samr_QueryDomainInfo2 r;
2337 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2338 int i;
2339 BOOL ret = True;
2341 for (i=0;i<ARRAY_SIZE(levels);i++) {
2342 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2344 r.in.domain_handle = handle;
2345 r.in.level = levels[i];
2347 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2348 if (!NT_STATUS_IS_OK(status)) {
2349 printf("QueryDomainInfo2 level %u failed - %s\n",
2350 r.in.level, nt_errstr(status));
2351 ret = False;
2352 continue;
2356 return True;
2359 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2360 set of group names. */
2361 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2362 struct policy_handle *handle)
2364 struct samr_EnumDomainGroups q1;
2365 struct samr_QueryDisplayInfo q2;
2366 NTSTATUS status;
2367 uint32_t resume_handle=0;
2368 int i;
2369 BOOL ret = True;
2371 int num_names = 0;
2372 const char **names = NULL;
2374 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2376 q1.in.domain_handle = handle;
2377 q1.in.resume_handle = &resume_handle;
2378 q1.in.max_size = 5;
2379 q1.out.resume_handle = &resume_handle;
2381 status = STATUS_MORE_ENTRIES;
2382 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2383 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2385 if (!NT_STATUS_IS_OK(status) &&
2386 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2387 break;
2389 for (i=0; i<q1.out.sam->count; i++) {
2390 add_string_to_array(mem_ctx,
2391 q1.out.sam->entries[i].name.name,
2392 &names, &num_names);
2396 if (!NT_STATUS_IS_OK(status)) {
2397 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2398 return False;
2401 if (!q1.out.sam) {
2402 return False;
2405 q2.in.domain_handle = handle;
2406 q2.in.level = 5;
2407 q2.in.start_idx = 0;
2408 q2.in.max_entries = 5;
2409 q2.in.buf_size = (uint32_t)-1;
2411 status = STATUS_MORE_ENTRIES;
2412 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2413 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2415 if (!NT_STATUS_IS_OK(status) &&
2416 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2417 break;
2419 for (i=0; i<q2.out.info.info5.count; i++) {
2420 char *name;
2421 size_t namelen;
2422 int j;
2423 BOOL found = False;
2425 /* Querydisplayinfo returns ascii -- convert */
2427 namelen = convert_string_talloc(mem_ctx, CH_DISPLAY, CH_UNIX,
2428 q2.out.info.info5.entries[i].account_name.name,
2429 q2.out.info.info5.entries[i].account_name.name_len,
2430 (void **)&name);
2432 for (j=0; j<num_names; j++) {
2433 if (names[j] == NULL)
2434 continue;
2435 /* Hmm. No strequal in samba4 */
2436 if (strequal(names[j], name)) {
2437 names[j] = NULL;
2438 found = True;
2439 break;
2443 if (!found) {
2444 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2445 name);
2446 ret = False;
2449 q2.in.start_idx += q2.out.info.info5.count;
2452 if (!NT_STATUS_IS_OK(status)) {
2453 printf("QueryDisplayInfo level 5 failed - %s\n",
2454 nt_errstr(status));
2455 ret = False;
2458 for (i=0; i<num_names; i++) {
2459 if (names[i] != NULL) {
2460 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2461 names[i]);
2462 ret = False;
2466 return ret;
2469 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2470 struct policy_handle *group_handle)
2472 struct samr_DeleteDomainGroup d;
2473 NTSTATUS status;
2474 BOOL ret = True;
2476 printf("Testing DeleteDomainGroup\n");
2478 d.in.group_handle = group_handle;
2479 d.out.group_handle = group_handle;
2481 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2482 if (!NT_STATUS_IS_OK(status)) {
2483 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2484 ret = False;
2487 return ret;
2490 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2491 struct policy_handle *domain_handle)
2493 struct samr_TestPrivateFunctionsDomain r;
2494 NTSTATUS status;
2495 BOOL ret = True;
2497 printf("Testing TestPrivateFunctionsDomain\n");
2499 r.in.domain_handle = domain_handle;
2501 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2502 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2503 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2504 ret = False;
2507 return ret;
2510 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2511 struct policy_handle *domain_handle)
2513 struct samr_RidToSid r;
2514 NTSTATUS status;
2515 BOOL ret = True;
2517 printf("Testing RidToSid\n");
2519 r.in.domain_handle = domain_handle;
2520 r.in.rid = 512;
2522 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2523 if (!NT_STATUS_IS_OK(status)) {
2524 printf("RidToSid failed - %s\n", nt_errstr(status));
2525 ret = False;
2528 return ret;
2531 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2532 struct policy_handle *domain_handle)
2534 struct samr_GetBootKeyInformation r;
2535 NTSTATUS status;
2536 BOOL ret = True;
2538 printf("Testing GetBootKeyInformation\n");
2540 r.in.domain_handle = domain_handle;
2542 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2543 if (!NT_STATUS_IS_OK(status)) {
2544 /* w2k3 seems to fail this sometimes and pass it sometimes */
2545 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2548 return ret;
2551 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2552 struct policy_handle *domain_handle,
2553 struct policy_handle *group_handle)
2555 NTSTATUS status;
2556 struct samr_AddGroupMember r;
2557 struct samr_DeleteGroupMember d;
2558 struct samr_QueryGroupMember q;
2559 struct samr_SetMemberAttributesOfGroup s;
2560 BOOL ret = True;
2561 uint32_t rid;
2563 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2564 if (!NT_STATUS_IS_OK(status)) {
2565 return False;
2568 r.in.group_handle = group_handle;
2569 r.in.rid = rid;
2570 r.in.flags = 0; /* ??? */
2572 printf("Testing AddGroupMember and DeleteGroupMember\n");
2574 d.in.group_handle = group_handle;
2575 d.in.rid = rid;
2577 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2578 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2579 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
2580 nt_errstr(status));
2581 return False;
2584 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2585 if (!NT_STATUS_IS_OK(status)) {
2586 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2587 return False;
2590 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2591 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2592 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
2593 nt_errstr(status));
2594 return False;
2597 /* this one is quite strange. I am using random inputs in the
2598 hope of triggering an error that might give us a clue */
2599 s.in.group_handle = group_handle;
2600 s.in.unknown1 = random();
2601 s.in.unknown2 = random();
2603 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2604 if (!NT_STATUS_IS_OK(status)) {
2605 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2606 return False;
2609 q.in.group_handle = group_handle;
2611 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2612 if (!NT_STATUS_IS_OK(status)) {
2613 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2614 return False;
2617 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2618 if (!NT_STATUS_IS_OK(status)) {
2619 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2620 return False;
2623 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2624 if (!NT_STATUS_IS_OK(status)) {
2625 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2626 return False;
2629 return ret;
2633 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2634 struct policy_handle *domain_handle, struct policy_handle *group_handle)
2636 NTSTATUS status;
2637 struct samr_CreateDomainGroup r;
2638 uint32_t rid;
2639 struct samr_Name name;
2640 BOOL ret = True;
2642 init_samr_Name(&name, TEST_GROUPNAME);
2644 r.in.domain_handle = domain_handle;
2645 r.in.name = &name;
2646 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2647 r.out.group_handle = group_handle;
2648 r.out.rid = &rid;
2650 printf("Testing CreateDomainGroup(%s)\n", r.in.name->name);
2652 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2654 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2655 printf("Server refused create of '%s'\n", r.in.name->name);
2656 ZERO_STRUCTP(group_handle);
2657 return True;
2660 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
2661 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2662 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->name)) {
2663 return False;
2665 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2667 if (!NT_STATUS_IS_OK(status)) {
2668 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
2669 return False;
2672 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
2673 ret = False;
2676 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
2677 ret = False;
2680 return ret;
2685 its not totally clear what this does. It seems to accept any sid you like.
2687 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
2688 TALLOC_CTX *mem_ctx,
2689 struct policy_handle *domain_handle)
2691 NTSTATUS status;
2692 struct samr_RemoveMemberFromForeignDomain r;
2694 r.in.domain_handle = domain_handle;
2695 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78-9");
2697 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
2698 if (!NT_STATUS_IS_OK(status)) {
2699 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
2700 return False;
2703 return True;
2709 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2710 struct policy_handle *handle, struct dom_sid *sid)
2712 NTSTATUS status;
2713 struct samr_OpenDomain r;
2714 struct policy_handle domain_handle;
2715 struct policy_handle user_handle;
2716 struct policy_handle alias_handle;
2717 struct policy_handle group_handle;
2718 BOOL ret = True;
2720 ZERO_STRUCT(user_handle);
2721 ZERO_STRUCT(alias_handle);
2722 ZERO_STRUCT(group_handle);
2723 ZERO_STRUCT(domain_handle);
2725 printf("Testing OpenDomain\n");
2727 r.in.connect_handle = handle;
2728 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2729 r.in.sid = sid;
2730 r.out.domain_handle = &domain_handle;
2732 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2733 if (!NT_STATUS_IS_OK(status)) {
2734 printf("OpenDomain failed - %s\n", nt_errstr(status));
2735 return False;
2738 if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
2739 ret = False;
2742 if (!test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle)) {
2743 ret = False;
2746 if (!test_CreateUser2(p, mem_ctx, &domain_handle)) {
2747 ret = False;
2750 if (!test_CreateUser(p, mem_ctx, &domain_handle, &user_handle)) {
2751 ret = False;
2754 if (!test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid)) {
2755 ret = False;
2758 if (!test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle)) {
2759 ret = False;
2762 if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
2763 ret = False;
2766 if (!test_QueryDomainInfo2(p, mem_ctx, &domain_handle)) {
2767 ret = False;
2770 if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
2771 ret = False;
2774 if (!test_EnumDomainUsers_async(p, mem_ctx, &domain_handle)) {
2775 ret = False;
2778 if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
2779 ret = False;
2782 if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
2783 ret = False;
2786 if (!test_QueryDisplayInfo(p, mem_ctx, &domain_handle)) {
2787 ret = False;
2790 if (!test_QueryDisplayInfo2(p, mem_ctx, &domain_handle)) {
2791 ret = False;
2794 if (!test_QueryDisplayInfo3(p, mem_ctx, &domain_handle)) {
2795 ret = False;
2798 if (!test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle)) {
2799 ret = False;
2802 if (!test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle)) {
2803 ret = False;
2806 if (!test_GroupList(p, mem_ctx, &domain_handle)) {
2807 ret = False;
2810 if (!test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle)) {
2811 ret = False;
2814 if (!test_RidToSid(p, mem_ctx, &domain_handle)) {
2815 ret = False;
2818 if (!test_GetBootKeyInformation(p, mem_ctx, &domain_handle)) {
2819 ret = False;
2822 if (!policy_handle_empty(&user_handle) &&
2823 !test_DeleteUser(p, mem_ctx, &user_handle)) {
2824 ret = False;
2827 if (!policy_handle_empty(&alias_handle) &&
2828 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
2829 ret = False;
2832 if (!policy_handle_empty(&group_handle) &&
2833 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
2834 ret = False;
2837 if (!test_Close(p, mem_ctx, &domain_handle)) {
2838 ret = False;
2841 return ret;
2844 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2845 struct policy_handle *handle, struct samr_Name *domain)
2847 NTSTATUS status;
2848 struct samr_LookupDomain r;
2849 struct samr_Name n2;
2850 BOOL ret = True;
2852 printf("Testing LookupDomain(%s)\n", domain->name);
2854 /* check for correct error codes */
2855 r.in.connect_handle = handle;
2856 r.in.domain = &n2;
2857 n2.name = NULL;
2859 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2860 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
2861 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
2862 ret = False;
2865 n2.name = "xxNODOMAINxx";
2867 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2868 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
2869 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
2870 ret = False;
2873 r.in.connect_handle = handle;
2874 r.in.domain = domain;
2876 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2877 if (!NT_STATUS_IS_OK(status)) {
2878 printf("LookupDomain failed - %s\n", nt_errstr(status));
2879 ret = False;
2882 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
2883 ret = False;
2886 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
2887 ret = False;
2890 return ret;
2894 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2895 struct policy_handle *handle)
2897 NTSTATUS status;
2898 struct samr_EnumDomains r;
2899 uint32_t resume_handle = 0;
2900 int i;
2901 BOOL ret = True;
2903 r.in.connect_handle = handle;
2904 r.in.resume_handle = &resume_handle;
2905 r.in.buf_size = (uint32_t)-1;
2906 r.out.resume_handle = &resume_handle;
2908 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2909 if (!NT_STATUS_IS_OK(status)) {
2910 printf("EnumDomains failed - %s\n", nt_errstr(status));
2911 return False;
2914 if (!r.out.sam) {
2915 return False;
2918 for (i=0;i<r.out.sam->count;i++) {
2919 if (!test_LookupDomain(p, mem_ctx, handle,
2920 &r.out.sam->entries[i].name)) {
2921 ret = False;
2925 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2926 if (!NT_STATUS_IS_OK(status)) {
2927 printf("EnumDomains failed - %s\n", nt_errstr(status));
2928 return False;
2931 return ret;
2935 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2936 struct policy_handle *handle)
2938 NTSTATUS status;
2939 struct samr_Connect r;
2940 struct samr_Connect2 r2;
2941 struct samr_Connect3 r3;
2942 struct samr_Connect4 r4;
2943 struct samr_Connect5 r5;
2944 union samr_ConnectInfo info;
2945 BOOL ret = True;
2947 printf("testing samr_Connect\n");
2949 r.in.system_name = 0;
2950 r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2951 r.out.connect_handle = handle;
2953 status = dcerpc_samr_Connect(p, mem_ctx, &r);
2954 if (!NT_STATUS_IS_OK(status)) {
2955 printf("Connect failed - %s\n", nt_errstr(status));
2956 ret = False;
2959 printf("testing samr_Connect2\n");
2961 r2.in.system_name = NULL;
2962 r2.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2963 r2.out.connect_handle = handle;
2965 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
2966 if (!NT_STATUS_IS_OK(status)) {
2967 printf("Connect2 failed - %s\n", nt_errstr(status));
2968 ret = False;
2971 printf("testing samr_Connect3\n");
2973 r3.in.system_name = NULL;
2974 r3.in.unknown = 0;
2975 r3.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2976 r3.out.connect_handle = handle;
2978 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
2979 if (!NT_STATUS_IS_OK(status)) {
2980 printf("Connect3 failed - %s\n", nt_errstr(status));
2981 ret = False;
2984 printf("testing samr_Connect4\n");
2986 r4.in.system_name = "";
2987 r4.in.unknown = 0;
2988 r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2989 r4.out.connect_handle = handle;
2991 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
2992 if (!NT_STATUS_IS_OK(status)) {
2993 printf("Connect4 failed - %s\n", nt_errstr(status));
2994 ret = False;
2997 printf("testing samr_Connect5\n");
2999 info.info1.unknown1 = 0;
3000 info.info1.unknown2 = 0;
3002 r5.in.system_name = "";
3003 r5.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
3004 r5.in.level = 1;
3005 r5.in.info = &info;
3006 r5.out.info = &info;
3007 r5.out.connect_handle = handle;
3009 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3010 if (!NT_STATUS_IS_OK(status)) {
3011 printf("Connect5 failed - %s\n", nt_errstr(status));
3012 ret = False;
3015 return ret;
3019 BOOL torture_rpc_samr(int dummy)
3021 NTSTATUS status;
3022 struct dcerpc_pipe *p;
3023 TALLOC_CTX *mem_ctx;
3024 BOOL ret = True;
3025 struct policy_handle handle;
3027 mem_ctx = talloc_init("torture_rpc_samr");
3029 status = torture_rpc_connection(&p,
3030 DCERPC_SAMR_NAME,
3031 DCERPC_SAMR_UUID,
3032 DCERPC_SAMR_VERSION);
3033 if (!NT_STATUS_IS_OK(status)) {
3034 return False;
3037 if (!test_Connect(p, mem_ctx, &handle)) {
3038 ret = False;
3041 if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3042 ret = False;
3045 if (!test_EnumDomains(p, mem_ctx, &handle)) {
3046 ret = False;
3049 if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3050 ret = False;
3053 if (!test_Shutdown(p, mem_ctx, &handle)) {
3054 ret = False;
3057 if (!test_Close(p, mem_ctx, &handle)) {
3058 ret = False;
3061 talloc_destroy(mem_ctx);
3063 torture_rpc_close(p);
3065 return ret;