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 "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
34 #define TEST_ACCOUNT_NAME "samrtorturetest"
35 #define TEST_ALIASNAME "samrtorturetestalias"
36 #define TEST_GROUPNAME "samrtorturetestgroup"
37 #define TEST_MACHINENAME "samrtestmach$"
38 #define TEST_DOMAINNAME "samrtestdom$"
41 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
42 struct policy_handle *handle);
44 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
45 struct policy_handle *handle);
47 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48 struct policy_handle *handle);
50 static void init_lsa_String(struct lsa_String *string, const char *s)
55 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
56 struct policy_handle *handle)
62 r.out.handle = handle;
64 status = dcerpc_samr_Close(p, mem_ctx, &r);
65 if (!NT_STATUS_IS_OK(status)) {
66 printf("Close handle failed - %s\n", nt_errstr(status));
73 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
74 struct policy_handle *handle)
77 struct samr_Shutdown r;
79 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
80 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
84 r.in.connect_handle = handle;
86 printf("testing samr_Shutdown\n");
88 status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
89 if (!NT_STATUS_IS_OK(status)) {
90 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
97 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
98 struct policy_handle *handle)
101 struct samr_SetDsrmPassword r;
102 struct lsa_String string;
103 struct samr_Password hash;
105 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
106 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
110 E_md4hash("TeSTDSRM123", hash.hash);
112 init_lsa_String(&string, "Administrator");
118 printf("testing samr_SetDsrmPassword\n");
120 status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
121 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
122 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
130 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
131 struct policy_handle *handle)
134 struct samr_QuerySecurity r;
135 struct samr_SetSecurity s;
137 r.in.handle = handle;
140 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
141 if (!NT_STATUS_IS_OK(status)) {
142 printf("QuerySecurity failed - %s\n", nt_errstr(status));
146 if (r.out.sdbuf == NULL) {
150 s.in.handle = handle;
152 s.in.sdbuf = r.out.sdbuf;
154 if (lp_parm_bool(-1, "target", "samba4", False)) {
155 printf("skipping SetSecurity test against Samba4\n");
159 status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
160 if (!NT_STATUS_IS_OK(status)) {
161 printf("SetSecurity failed - %s\n", nt_errstr(status));
165 status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
166 if (!NT_STATUS_IS_OK(status)) {
167 printf("QuerySecurity failed - %s\n", nt_errstr(status));
175 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
176 struct policy_handle *handle, uint32_t base_acct_flags,
177 const char *base_account_name)
180 struct samr_SetUserInfo s;
181 struct samr_SetUserInfo2 s2;
182 struct samr_QueryUserInfo q;
183 struct samr_QueryUserInfo q0;
184 union samr_UserInfo u;
186 const char *test_account_name;
188 uint32_t user_extra_flags = 0;
189 if (base_acct_flags == ACB_NORMAL) {
190 /* When created, accounts are expired by default */
191 user_extra_flags = ACB_PW_EXPIRED;
194 s.in.user_handle = handle;
197 s2.in.user_handle = handle;
200 q.in.user_handle = handle;
204 #define TESTCALL(call, r) \
205 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
206 if (!NT_STATUS_IS_OK(status)) { \
207 printf(#call " level %u failed - %s (%s)\n", \
208 r.in.level, nt_errstr(status), __location__); \
213 #define STRING_EQUAL(s1, s2, field) \
214 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
215 printf("Failed to set %s to '%s' (%s)\n", \
216 #field, s2, __location__); \
221 #define INT_EQUAL(i1, i2, field) \
223 printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
224 #field, i2, i1, __location__); \
229 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
230 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
232 TESTCALL(QueryUserInfo, q) \
234 s2.in.level = lvl1; \
237 ZERO_STRUCT(u.info21); \
238 u.info21.fields_present = fpval; \
240 init_lsa_String(&u.info ## lvl1.field1, value); \
241 TESTCALL(SetUserInfo, s) \
242 TESTCALL(SetUserInfo2, s2) \
243 init_lsa_String(&u.info ## lvl1.field1, ""); \
244 TESTCALL(QueryUserInfo, q); \
246 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
248 TESTCALL(QueryUserInfo, q) \
250 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
253 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
254 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
256 TESTCALL(QueryUserInfo, q) \
258 s2.in.level = lvl1; \
261 uint8_t *bits = u.info21.logon_hours.bits; \
262 ZERO_STRUCT(u.info21); \
263 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
264 u.info21.logon_hours.units_per_week = 168; \
265 u.info21.logon_hours.bits = bits; \
267 u.info21.fields_present = fpval; \
269 u.info ## lvl1.field1 = value; \
270 TESTCALL(SetUserInfo, s) \
271 TESTCALL(SetUserInfo2, s2) \
272 u.info ## lvl1.field1 = 0; \
273 TESTCALL(QueryUserInfo, q); \
275 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
277 TESTCALL(QueryUserInfo, q) \
279 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
282 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
283 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
287 do { TESTCALL(QueryUserInfo, q0) } while (0);
289 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
290 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
291 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
294 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
295 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
296 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
297 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
298 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
299 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
300 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
301 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
302 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
303 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
304 test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
305 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
306 test_account_name = base_account_name;
307 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
308 SAMR_FIELD_ACCOUNT_NAME);
310 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
311 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
312 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
313 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
314 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
315 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
316 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
317 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
318 SAMR_FIELD_FULL_NAME);
320 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
321 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
322 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
323 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
324 SAMR_FIELD_LOGON_SCRIPT);
326 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
327 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
328 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
329 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
330 SAMR_FIELD_PROFILE_PATH);
332 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
333 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
334 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
335 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
336 SAMR_FIELD_DESCRIPTION);
338 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
339 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
340 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
341 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
342 SAMR_FIELD_WORKSTATIONS);
344 TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
345 TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
346 SAMR_FIELD_PARAMETERS);
348 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
349 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
350 SAMR_FIELD_COUNTRY_CODE);
352 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
353 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
354 SAMR_FIELD_CODE_PAGE);
356 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
357 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
358 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
359 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
360 SAMR_FIELD_LOGON_HOURS);
362 if (lp_parm_bool(-1, "target", "samba4", False)) {
363 printf("skipping Set Account Flag tests against Samba4\n");
367 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
368 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
369 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
371 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
372 (base_acct_flags | ACB_DISABLED),
373 (base_acct_flags | ACB_DISABLED | user_extra_flags),
376 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
377 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
378 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
379 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
381 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
382 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
383 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
387 /* The 'autolock' flag doesn't stick - check this */
388 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
389 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
390 (base_acct_flags | ACB_DISABLED | user_extra_flags),
393 /* Removing the 'disabled' flag doesn't stick - check this */
394 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
396 (base_acct_flags | ACB_DISABLED | user_extra_flags),
399 /* The 'store plaintext' flag does stick */
400 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
401 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
402 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
404 /* The 'use DES' flag does stick */
405 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
406 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
407 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
409 /* The 'don't require kerberos pre-authentication flag does stick */
410 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
411 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
412 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
414 /* The 'no kerberos PAC required' flag sticks */
415 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
416 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
417 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
420 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
421 (base_acct_flags | ACB_DISABLED),
422 (base_acct_flags | ACB_DISABLED | user_extra_flags),
423 SAMR_FIELD_ACCT_FLAGS);
426 /* these fail with win2003 - it appears you can't set the primary gid?
427 the set succeeds, but the gid isn't changed. Very weird! */
428 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
429 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
430 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
431 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
438 generate a random password for password change tests
440 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
442 size_t len = MAX(8, min_len) + (random() % 6);
443 char *s = generate_random_str(mem_ctx, len);
444 printf("Generated password '%s'\n", s);
448 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
449 struct policy_handle *handle, char **password)
452 struct samr_SetUserInfo s;
453 union samr_UserInfo u;
455 DATA_BLOB session_key;
457 struct samr_GetUserPwInfo pwp;
458 int policy_min_pw_len = 0;
459 pwp.in.user_handle = handle;
461 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
462 if (NT_STATUS_IS_OK(status)) {
463 policy_min_pw_len = pwp.out.info.min_password_length;
465 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
467 s.in.user_handle = handle;
471 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
472 /* w2k3 ignores this length */
473 u.info24.pw_len = strlen_m(newpass) * 2;
475 status = dcerpc_fetch_session_key(p, &session_key);
476 if (!NT_STATUS_IS_OK(status)) {
477 printf("SetUserInfo level %u - no session key - %s\n",
478 s.in.level, nt_errstr(status));
482 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
484 printf("Testing SetUserInfo level 24 (set password)\n");
486 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
487 if (!NT_STATUS_IS_OK(status)) {
488 printf("SetUserInfo level %u failed - %s\n",
489 s.in.level, nt_errstr(status));
499 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
500 struct policy_handle *handle, uint32_t fields_present,
504 struct samr_SetUserInfo s;
505 union samr_UserInfo u;
507 DATA_BLOB session_key;
509 struct samr_GetUserPwInfo pwp;
510 int policy_min_pw_len = 0;
511 pwp.in.user_handle = handle;
513 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
514 if (NT_STATUS_IS_OK(status)) {
515 policy_min_pw_len = pwp.out.info.min_password_length;
517 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
519 s.in.user_handle = handle;
525 u.info23.info.fields_present = fields_present;
527 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
529 status = dcerpc_fetch_session_key(p, &session_key);
530 if (!NT_STATUS_IS_OK(status)) {
531 printf("SetUserInfo level %u - no session key - %s\n",
532 s.in.level, nt_errstr(status));
536 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
538 printf("Testing SetUserInfo level 23 (set password)\n");
540 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
541 if (!NT_STATUS_IS_OK(status)) {
542 printf("SetUserInfo level %u failed - %s\n",
543 s.in.level, nt_errstr(status));
553 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
554 struct policy_handle *handle, char **password)
557 struct samr_SetUserInfo s;
558 union samr_UserInfo u;
560 DATA_BLOB session_key;
561 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
562 uint8_t confounder[16];
564 struct MD5Context ctx;
565 struct samr_GetUserPwInfo pwp;
566 int policy_min_pw_len = 0;
567 pwp.in.user_handle = handle;
569 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
570 if (NT_STATUS_IS_OK(status)) {
571 policy_min_pw_len = pwp.out.info.min_password_length;
573 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
575 s.in.user_handle = handle;
579 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
580 u.info26.pw_len = strlen(newpass);
582 status = dcerpc_fetch_session_key(p, &session_key);
583 if (!NT_STATUS_IS_OK(status)) {
584 printf("SetUserInfo level %u - no session key - %s\n",
585 s.in.level, nt_errstr(status));
589 generate_random_buffer((uint8_t *)confounder, 16);
592 MD5Update(&ctx, confounder, 16);
593 MD5Update(&ctx, session_key.data, session_key.length);
594 MD5Final(confounded_session_key.data, &ctx);
596 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
597 memcpy(&u.info26.password.data[516], confounder, 16);
599 printf("Testing SetUserInfo level 26 (set password ex)\n");
601 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
602 if (!NT_STATUS_IS_OK(status)) {
603 printf("SetUserInfo level %u failed - %s\n",
604 s.in.level, nt_errstr(status));
613 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
614 struct policy_handle *handle, uint32_t fields_present,
618 struct samr_SetUserInfo s;
619 union samr_UserInfo u;
621 DATA_BLOB session_key;
622 DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
623 struct MD5Context ctx;
624 uint8_t confounder[16];
626 struct samr_GetUserPwInfo pwp;
627 int policy_min_pw_len = 0;
628 pwp.in.user_handle = handle;
630 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
631 if (NT_STATUS_IS_OK(status)) {
632 policy_min_pw_len = pwp.out.info.min_password_length;
634 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
636 s.in.user_handle = handle;
642 u.info25.info.fields_present = fields_present;
644 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
646 status = dcerpc_fetch_session_key(p, &session_key);
647 if (!NT_STATUS_IS_OK(status)) {
648 printf("SetUserInfo level %u - no session key - %s\n",
649 s.in.level, nt_errstr(status));
653 generate_random_buffer((uint8_t *)confounder, 16);
656 MD5Update(&ctx, confounder, 16);
657 MD5Update(&ctx, session_key.data, session_key.length);
658 MD5Final(confounded_session_key.data, &ctx);
660 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
661 memcpy(&u.info25.password.data[516], confounder, 16);
663 printf("Testing SetUserInfo level 25 (set password ex)\n");
665 status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
666 if (!NT_STATUS_IS_OK(status)) {
667 printf("SetUserInfo level %u failed - %s\n",
668 s.in.level, nt_errstr(status));
677 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
678 struct policy_handle *handle)
681 struct samr_SetAliasInfo r;
682 struct samr_QueryAliasInfo q;
683 uint16_t levels[] = {2, 3};
687 /* Ignoring switch level 1, as that includes the number of members for the alias
688 * and setting this to a wrong value might have negative consequences
691 for (i=0;i<ARRAY_SIZE(levels);i++) {
692 printf("Testing SetAliasInfo level %u\n", levels[i]);
694 r.in.alias_handle = handle;
695 r.in.level = levels[i];
696 r.in.info = talloc(mem_ctx, union samr_AliasInfo);
697 switch (r.in.level) {
698 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
699 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
700 "Test Description, should test I18N as well"); break;
703 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
704 if (!NT_STATUS_IS_OK(status)) {
705 printf("SetAliasInfo level %u failed - %s\n",
706 levels[i], nt_errstr(status));
710 q.in.alias_handle = handle;
711 q.in.level = levels[i];
713 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
714 if (!NT_STATUS_IS_OK(status)) {
715 printf("QueryAliasInfo level %u failed - %s\n",
716 levels[i], nt_errstr(status));
724 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
725 struct policy_handle *user_handle)
727 struct samr_GetGroupsForUser r;
731 printf("testing GetGroupsForUser\n");
733 r.in.user_handle = user_handle;
735 status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
736 if (!NT_STATUS_IS_OK(status)) {
737 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
745 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
746 struct lsa_String *domain_name)
749 struct samr_GetDomPwInfo r;
752 r.in.domain_name = domain_name;
753 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
755 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
756 if (!NT_STATUS_IS_OK(status)) {
757 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
761 r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
762 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
764 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
765 if (!NT_STATUS_IS_OK(status)) {
766 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
770 r.in.domain_name->string = "\\\\__NONAME__";
771 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
773 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
774 if (!NT_STATUS_IS_OK(status)) {
775 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
779 r.in.domain_name->string = "\\\\Builtin";
780 printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
782 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
783 if (!NT_STATUS_IS_OK(status)) {
784 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
792 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
793 struct policy_handle *handle)
796 struct samr_GetUserPwInfo r;
799 printf("Testing GetUserPwInfo\n");
801 r.in.user_handle = handle;
803 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
804 if (!NT_STATUS_IS_OK(status)) {
805 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
812 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
813 struct policy_handle *domain_handle, const char *name,
817 struct samr_LookupNames n;
818 struct lsa_String sname[2];
820 init_lsa_String(&sname[0], name);
822 n.in.domain_handle = domain_handle;
825 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
826 if (NT_STATUS_IS_OK(status)) {
827 *rid = n.out.rids.ids[0];
832 init_lsa_String(&sname[1], "xxNONAMExx");
834 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
835 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
836 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
840 init_lsa_String(&sname[1], "xxNONAMExx");
842 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
843 if (!NT_STATUS_IS_OK(status)) {
844 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
850 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
851 struct policy_handle *domain_handle,
852 const char *name, struct policy_handle *user_handle)
855 struct samr_OpenUser r;
858 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
859 if (!NT_STATUS_IS_OK(status)) {
863 r.in.domain_handle = domain_handle;
864 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
866 r.out.user_handle = user_handle;
867 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
868 if (!NT_STATUS_IS_OK(status)) {
869 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
876 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
877 struct policy_handle *handle)
880 struct samr_ChangePasswordUser r;
882 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
883 struct policy_handle user_handle;
884 char *oldpass = "test";
885 char *newpass = "test2";
886 uint8_t old_nt_hash[16], new_nt_hash[16];
887 uint8_t old_lm_hash[16], new_lm_hash[16];
889 status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
890 if (!NT_STATUS_IS_OK(status)) {
894 printf("Testing ChangePasswordUser for user 'testuser'\n");
896 printf("old password: %s\n", oldpass);
897 printf("new password: %s\n", newpass);
899 E_md4hash(oldpass, old_nt_hash);
900 E_md4hash(newpass, new_nt_hash);
901 E_deshash(oldpass, old_lm_hash);
902 E_deshash(newpass, new_lm_hash);
904 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
905 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
906 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
907 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
908 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
909 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
911 r.in.handle = &user_handle;
913 r.in.old_lm_crypted = &hash1;
914 r.in.new_lm_crypted = &hash2;
916 r.in.old_nt_crypted = &hash3;
917 r.in.new_nt_crypted = &hash4;
918 r.in.cross1_present = 1;
919 r.in.nt_cross = &hash5;
920 r.in.cross2_present = 1;
921 r.in.lm_cross = &hash6;
923 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
924 if (!NT_STATUS_IS_OK(status)) {
925 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
929 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
937 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
938 struct policy_handle *handle, char **password)
941 struct samr_ChangePasswordUser r;
943 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
944 struct policy_handle user_handle;
945 char *oldpass = *password;
946 uint8_t old_nt_hash[16], new_nt_hash[16];
947 uint8_t old_lm_hash[16], new_lm_hash[16];
950 struct samr_GetUserPwInfo pwp;
951 int policy_min_pw_len = 0;
953 status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
954 if (!NT_STATUS_IS_OK(status)) {
957 pwp.in.user_handle = &user_handle;
959 status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
960 if (NT_STATUS_IS_OK(status)) {
961 policy_min_pw_len = pwp.out.info.min_password_length;
963 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
965 printf("Testing ChangePasswordUser\n");
967 E_md4hash(oldpass, old_nt_hash);
968 E_md4hash(newpass, new_nt_hash);
969 E_deshash(oldpass, old_lm_hash);
970 E_deshash(newpass, new_lm_hash);
972 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
973 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
974 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
975 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
976 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
977 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
979 r.in.user_handle = &user_handle;
981 r.in.old_lm_crypted = &hash1;
982 r.in.new_lm_crypted = &hash2;
984 r.in.old_nt_crypted = &hash3;
985 r.in.new_nt_crypted = &hash4;
986 r.in.cross1_present = 1;
987 r.in.nt_cross = &hash5;
988 r.in.cross2_present = 1;
989 r.in.lm_cross = &hash6;
991 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
992 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
993 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
994 } else if (!NT_STATUS_IS_OK(status)) {
995 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1001 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1009 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1010 struct policy_handle *handle, char **password)
1013 struct samr_OemChangePasswordUser2 r;
1015 struct samr_Password lm_verifier;
1016 struct samr_CryptPassword lm_pass;
1017 struct lsa_AsciiString server, account, account_bad;
1018 char *oldpass = *password;
1020 uint8_t old_lm_hash[16], new_lm_hash[16];
1022 struct samr_GetDomPwInfo dom_pw_info;
1023 int policy_min_pw_len = 0;
1025 struct lsa_String domain_name;
1026 domain_name.string = "";
1027 dom_pw_info.in.domain_name = &domain_name;
1029 printf("Testing OemChangePasswordUser2\n");
1031 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1032 if (NT_STATUS_IS_OK(status)) {
1033 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1036 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1038 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1039 account.string = TEST_ACCOUNT_NAME;
1041 E_deshash(oldpass, old_lm_hash);
1042 E_deshash(newpass, new_lm_hash);
1044 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1045 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1046 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1048 r.in.server = &server;
1049 r.in.account = &account;
1050 r.in.password = &lm_pass;
1051 r.in.hash = &lm_verifier;
1053 /* Break the verification */
1054 lm_verifier.hash[0]++;
1056 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1058 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1059 && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1060 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1065 /* This shouldn't be a valid name */
1066 account_bad.string = TEST_ACCOUNT_NAME "XX";
1067 r.in.account = &account_bad;
1069 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1071 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1072 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1077 E_deshash(oldpass, old_lm_hash);
1078 E_deshash(newpass, new_lm_hash);
1080 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1081 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1082 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1084 r.in.server = &server;
1085 r.in.account = &account;
1086 r.in.password = &lm_pass;
1087 r.in.hash = &lm_verifier;
1089 status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1090 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1091 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1092 } else if (!NT_STATUS_IS_OK(status)) {
1093 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1096 *password = newpass;
1103 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1104 struct policy_handle *handle, char **password)
1107 struct samr_ChangePasswordUser2 r;
1109 struct lsa_String server, account;
1110 struct samr_CryptPassword nt_pass, lm_pass;
1111 struct samr_Password nt_verifier, lm_verifier;
1112 char *oldpass = *password;
1114 uint8_t old_nt_hash[16], new_nt_hash[16];
1115 uint8_t old_lm_hash[16], new_lm_hash[16];
1117 struct samr_GetDomPwInfo dom_pw_info;
1118 int policy_min_pw_len = 0;
1120 struct lsa_String domain_name;
1121 domain_name.string = "";
1122 dom_pw_info.in.domain_name = &domain_name;
1124 printf("Testing ChangePasswordUser2\n");
1126 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1127 if (NT_STATUS_IS_OK(status)) {
1128 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1131 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1133 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1134 init_lsa_String(&account, TEST_ACCOUNT_NAME);
1136 E_md4hash(oldpass, old_nt_hash);
1137 E_md4hash(newpass, new_nt_hash);
1139 E_deshash(oldpass, old_lm_hash);
1140 E_deshash(newpass, new_lm_hash);
1142 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1143 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1144 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1146 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1147 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1148 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1150 r.in.server = &server;
1151 r.in.account = &account;
1152 r.in.nt_password = &nt_pass;
1153 r.in.nt_verifier = &nt_verifier;
1155 r.in.lm_password = &lm_pass;
1156 r.in.lm_verifier = &lm_verifier;
1158 status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1159 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1160 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1161 } else if (!NT_STATUS_IS_OK(status)) {
1162 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1165 *password = newpass;
1172 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1173 const char *account_string,
1174 int policy_min_pw_len,
1178 struct samr_ChangePasswordUser3 r;
1180 struct lsa_String server, account, account_bad;
1181 struct samr_CryptPassword nt_pass, lm_pass;
1182 struct samr_Password nt_verifier, lm_verifier;
1183 char *oldpass = *password;
1184 char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1185 uint8_t old_nt_hash[16], new_nt_hash[16];
1186 uint8_t old_lm_hash[16], new_lm_hash[16];
1188 printf("Testing ChangePasswordUser3\n");
1190 server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1191 init_lsa_String(&account, account_string);
1193 E_md4hash(oldpass, old_nt_hash);
1194 E_md4hash(newpass, new_nt_hash);
1196 E_deshash(oldpass, old_lm_hash);
1197 E_deshash(newpass, new_lm_hash);
1199 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1200 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1201 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1203 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1204 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1205 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1207 /* Break the verification */
1208 nt_verifier.hash[0]++;
1210 r.in.server = &server;
1211 r.in.account = &account;
1212 r.in.nt_password = &nt_pass;
1213 r.in.nt_verifier = &nt_verifier;
1215 r.in.lm_password = &lm_pass;
1216 r.in.lm_verifier = &lm_verifier;
1217 r.in.password3 = NULL;
1219 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1220 if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1221 (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1222 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1227 /* This shouldn't be a valid name */
1228 init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1230 r.in.account = &account_bad;
1231 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1232 if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1233 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1238 E_md4hash(oldpass, old_nt_hash);
1239 E_md4hash(newpass, new_nt_hash);
1241 E_deshash(oldpass, old_lm_hash);
1242 E_deshash(newpass, new_lm_hash);
1244 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1245 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1246 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1248 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1249 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1250 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1252 r.in.server = &server;
1253 r.in.account = &account;
1254 r.in.nt_password = &nt_pass;
1255 r.in.nt_verifier = &nt_verifier;
1257 r.in.lm_password = &lm_pass;
1258 r.in.lm_verifier = &lm_verifier;
1259 r.in.password3 = NULL;
1261 status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1262 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1263 && !policy_min_pw_len) {
1264 if (r.out.dominfo) {
1265 policy_min_pw_len = r.out.dominfo->min_password_length;
1267 if (policy_min_pw_len) /* try again with the right min password length */ {
1268 ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1270 printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1273 } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1274 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1275 } else if (!NT_STATUS_IS_OK(status)) {
1276 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1279 *password = newpass;
1286 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1287 struct policy_handle *alias_handle)
1289 struct samr_GetMembersInAlias r;
1290 struct lsa_SidArray sids;
1294 printf("Testing GetMembersInAlias\n");
1296 r.in.alias_handle = alias_handle;
1299 status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 printf("GetMembersInAlias failed - %s\n",
1309 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1310 struct policy_handle *alias_handle,
1311 const struct dom_sid *domain_sid)
1313 struct samr_AddAliasMember r;
1314 struct samr_DeleteAliasMember d;
1317 struct dom_sid *sid;
1319 sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1321 printf("testing AddAliasMember\n");
1322 r.in.alias_handle = alias_handle;
1325 status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1331 d.in.alias_handle = alias_handle;
1334 status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1335 if (!NT_STATUS_IS_OK(status)) {
1336 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1343 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1344 struct policy_handle *alias_handle)
1346 struct samr_AddMultipleMembersToAlias a;
1347 struct samr_RemoveMultipleMembersFromAlias r;
1350 struct lsa_SidArray sids;
1352 printf("testing AddMultipleMembersToAlias\n");
1353 a.in.alias_handle = alias_handle;
1357 sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1359 sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1360 sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1361 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1363 status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1364 if (!NT_STATUS_IS_OK(status)) {
1365 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1370 printf("testing RemoveMultipleMembersFromAlias\n");
1371 r.in.alias_handle = alias_handle;
1374 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1375 if (!NT_STATUS_IS_OK(status)) {
1376 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1380 /* strange! removing twice doesn't give any error */
1381 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1382 if (!NT_STATUS_IS_OK(status)) {
1383 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1387 /* but removing an alias that isn't there does */
1388 sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1390 status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1391 if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1392 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1399 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1400 struct policy_handle *user_handle)
1402 struct samr_TestPrivateFunctionsUser r;
1406 printf("Testing TestPrivateFunctionsUser\n");
1408 r.in.user_handle = user_handle;
1410 status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1411 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1412 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1420 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1421 struct policy_handle *handle, uint32_t base_acct_flags,
1422 const char *base_acct_name)
1426 if (!test_QuerySecurity(p, mem_ctx, handle)) {
1430 if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1434 if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1438 if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1443 if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1447 if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1454 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1455 struct policy_handle *alias_handle,
1456 const struct dom_sid *domain_sid)
1460 if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1464 if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1468 if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1472 if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1476 if (lp_parm_bool(-1, "target", "samba4", False)) {
1477 printf("skipping MultipleMembers Alias tests against Samba4\n");
1481 if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1489 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1490 struct policy_handle *handle, const char *name)
1493 struct samr_DeleteUser d;
1494 struct policy_handle user_handle;
1497 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1498 if (!NT_STATUS_IS_OK(status)) {
1502 status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1503 if (!NT_STATUS_IS_OK(status)) {
1507 d.in.user_handle = &user_handle;
1508 d.out.user_handle = &user_handle;
1509 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1510 if (!NT_STATUS_IS_OK(status)) {
1517 printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1522 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1523 struct policy_handle *handle, const char *name)
1526 struct samr_OpenGroup r;
1527 struct samr_DeleteDomainGroup d;
1528 struct policy_handle group_handle;
1531 status = test_LookupName(p, mem_ctx, handle, name, &rid);
1532 if (!NT_STATUS_IS_OK(status)) {
1536 r.in.domain_handle = handle;
1537 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1539 r.out.group_handle = &group_handle;
1540 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1541 if (!NT_STATUS_IS_OK(status)) {
1545 d.in.group_handle = &group_handle;
1546 d.out.group_handle = &group_handle;
1547 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1548 if (!NT_STATUS_IS_OK(status)) {
1555 printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1560 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1561 struct policy_handle *domain_handle, const char *name)
1564 struct samr_OpenAlias r;
1565 struct samr_DeleteDomAlias d;
1566 struct policy_handle alias_handle;
1569 printf("testing DeleteAlias_byname\n");
1571 status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1572 if (!NT_STATUS_IS_OK(status)) {
1576 r.in.domain_handle = domain_handle;
1577 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1579 r.out.alias_handle = &alias_handle;
1580 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1581 if (!NT_STATUS_IS_OK(status)) {
1585 d.in.alias_handle = &alias_handle;
1586 d.out.alias_handle = &alias_handle;
1587 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1588 if (!NT_STATUS_IS_OK(status)) {
1595 printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
1599 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1600 struct policy_handle *alias_handle)
1602 struct samr_DeleteDomAlias d;
1605 printf("Testing DeleteAlias\n");
1607 d.in.alias_handle = alias_handle;
1608 d.out.alias_handle = alias_handle;
1610 status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1611 if (!NT_STATUS_IS_OK(status)) {
1612 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1619 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1620 struct policy_handle *domain_handle,
1621 struct policy_handle *alias_handle,
1622 const struct dom_sid *domain_sid)
1625 struct samr_CreateDomAlias r;
1626 struct lsa_String name;
1630 init_lsa_String(&name, TEST_ALIASNAME);
1631 r.in.domain_handle = domain_handle;
1632 r.in.alias_name = &name;
1633 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1634 r.out.alias_handle = alias_handle;
1637 printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1639 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1641 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1642 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1646 if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1647 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1650 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1653 if (!NT_STATUS_IS_OK(status)) {
1654 printf("CreateAlias failed - %s\n", nt_errstr(status));
1658 if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1665 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1666 struct policy_handle *domain_handle, char **password)
1674 if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1678 if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1682 if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1686 /* we change passwords twice - this has the effect of verifying
1687 they were changed correctly for the final call */
1688 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1692 if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1699 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1700 struct policy_handle *domain_handle, struct policy_handle *user_handle)
1703 struct samr_CreateUser r;
1704 struct samr_QueryUserInfo q;
1706 char *password = NULL;
1709 const uint32_t password_fields[] = {
1710 SAMR_FIELD_PASSWORD,
1711 SAMR_FIELD_PASSWORD2,
1712 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1716 TALLOC_CTX *user_ctx;
1718 /* This call creates a 'normal' account - check that it really does */
1719 const uint32_t acct_flags = ACB_NORMAL;
1720 struct lsa_String name;
1723 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1724 init_lsa_String(&name, TEST_ACCOUNT_NAME);
1726 r.in.domain_handle = domain_handle;
1727 r.in.account_name = &name;
1728 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1729 r.out.user_handle = user_handle;
1732 printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1734 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1736 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1737 printf("Server refused create of '%s'\n", r.in.account_name->string);
1738 ZERO_STRUCTP(user_handle);
1739 talloc_free(user_ctx);
1743 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1744 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1745 talloc_free(user_ctx);
1748 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1750 if (!NT_STATUS_IS_OK(status)) {
1751 talloc_free(user_ctx);
1752 printf("CreateUser failed - %s\n", nt_errstr(status));
1756 q.in.user_handle = user_handle;
1759 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1760 if (!NT_STATUS_IS_OK(status)) {
1761 printf("QueryUserInfo level %u failed - %s\n",
1762 q.in.level, nt_errstr(status));
1765 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1766 printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1767 q.out.info->info16.acct_flags, q.out.info->info16.acct_flags,
1768 acct_flags, acct_flags);
1773 if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1777 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1781 for (i = 0; password_fields[i]; i++) {
1782 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1786 /* check it was set right */
1787 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1792 for (i = 0; password_fields[i]; i++) {
1793 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1797 /* check it was set right */
1798 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1803 if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1807 if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1811 talloc_free(user_ctx);
1817 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1818 struct policy_handle *user_handle)
1820 struct samr_DeleteUser d;
1824 printf("Testing DeleteUser\n");
1826 d.in.user_handle = user_handle;
1827 d.out.user_handle = user_handle;
1829 status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1830 if (!NT_STATUS_IS_OK(status)) {
1831 printf("DeleteUser failed - %s\n", nt_errstr(status));
1838 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1839 struct policy_handle *handle)
1842 struct samr_CreateUser2 r;
1843 struct samr_QueryUserInfo q;
1844 struct samr_DeleteUser d;
1845 struct policy_handle user_handle;
1847 struct lsa_String name;
1852 uint32_t acct_flags;
1853 const char *account_name;
1855 } account_types[] = {
1856 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1857 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1858 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1859 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1860 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1861 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1862 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1863 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1864 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1865 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1866 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1867 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1868 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1869 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1870 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1873 for (i = 0; account_types[i].account_name; i++) {
1874 TALLOC_CTX *user_ctx;
1875 uint32_t acct_flags = account_types[i].acct_flags;
1876 uint32_t access_granted;
1877 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1878 init_lsa_String(&name, account_types[i].account_name);
1880 r.in.domain_handle = handle;
1881 r.in.account_name = &name;
1882 r.in.acct_flags = acct_flags;
1883 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1884 r.out.user_handle = &user_handle;
1885 r.out.access_granted = &access_granted;
1888 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1890 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1892 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1893 talloc_free(user_ctx);
1894 printf("Server refused create of '%s'\n", r.in.account_name->string);
1897 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1898 if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1899 talloc_free(user_ctx);
1903 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1906 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1907 printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
1908 nt_errstr(status), nt_errstr(account_types[i].nt_status));
1912 if (NT_STATUS_IS_OK(status)) {
1913 q.in.user_handle = &user_handle;
1916 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1917 if (!NT_STATUS_IS_OK(status)) {
1918 printf("QueryUserInfo level %u failed - %s\n",
1919 q.in.level, nt_errstr(status));
1922 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1923 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1924 q.out.info->info16.acct_flags,
1930 if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1934 printf("Testing DeleteUser (createuser2 test)\n");
1936 d.in.user_handle = &user_handle;
1937 d.out.user_handle = &user_handle;
1939 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1940 if (!NT_STATUS_IS_OK(status)) {
1941 printf("DeleteUser failed - %s\n", nt_errstr(status));
1945 talloc_free(user_ctx);
1951 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1952 struct policy_handle *handle)
1955 struct samr_QueryAliasInfo r;
1956 uint16_t levels[] = {1, 2, 3};
1960 for (i=0;i<ARRAY_SIZE(levels);i++) {
1961 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1963 r.in.alias_handle = handle;
1964 r.in.level = levels[i];
1966 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1967 if (!NT_STATUS_IS_OK(status)) {
1968 printf("QueryAliasInfo level %u failed - %s\n",
1969 levels[i], nt_errstr(status));
1977 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1978 struct policy_handle *handle)
1981 struct samr_QueryGroupInfo r;
1982 uint16_t levels[] = {1, 2, 3, 4, 5};
1986 for (i=0;i<ARRAY_SIZE(levels);i++) {
1987 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1989 r.in.group_handle = handle;
1990 r.in.level = levels[i];
1992 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1993 if (!NT_STATUS_IS_OK(status)) {
1994 printf("QueryGroupInfo level %u failed - %s\n",
1995 levels[i], nt_errstr(status));
2003 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2004 struct policy_handle *handle)
2007 struct samr_QueryGroupMember r;
2010 printf("Testing QueryGroupMember\n");
2012 r.in.group_handle = handle;
2014 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2015 if (!NT_STATUS_IS_OK(status)) {
2016 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2024 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2025 struct policy_handle *handle)
2028 struct samr_QueryGroupInfo r;
2029 struct samr_SetGroupInfo s;
2030 uint16_t levels[] = {1, 2, 3, 4};
2031 uint16_t set_ok[] = {0, 1, 1, 1};
2035 for (i=0;i<ARRAY_SIZE(levels);i++) {
2036 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2038 r.in.group_handle = handle;
2039 r.in.level = levels[i];
2041 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2042 if (!NT_STATUS_IS_OK(status)) {
2043 printf("QueryGroupInfo level %u failed - %s\n",
2044 levels[i], nt_errstr(status));
2048 printf("Testing SetGroupInfo level %u\n", levels[i]);
2050 s.in.group_handle = handle;
2051 s.in.level = levels[i];
2052 s.in.info = r.out.info;
2055 /* disabled this, as it changes the name only from the point of view of samr,
2056 but leaves the name from the point of view of w2k3 internals (and ldap). This means
2057 the name is still reserved, so creating the old name fails, but deleting by the old name
2059 if (s.in.level == 2) {
2060 init_lsa_String(&s.in.info->string, "NewName");
2064 if (s.in.level == 4) {
2065 init_lsa_String(&s.in.info->description, "test description");
2068 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2070 if (!NT_STATUS_IS_OK(status)) {
2071 printf("SetGroupInfo level %u failed - %s\n",
2072 r.in.level, nt_errstr(status));
2077 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2078 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2079 r.in.level, nt_errstr(status));
2089 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2090 struct policy_handle *handle)
2093 struct samr_QueryUserInfo r;
2094 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2095 11, 12, 13, 14, 16, 17, 20, 21};
2099 for (i=0;i<ARRAY_SIZE(levels);i++) {
2100 printf("Testing QueryUserInfo level %u\n", levels[i]);
2102 r.in.user_handle = handle;
2103 r.in.level = levels[i];
2105 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2106 if (!NT_STATUS_IS_OK(status)) {
2107 printf("QueryUserInfo level %u failed - %s\n",
2108 levels[i], nt_errstr(status));
2116 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2117 struct policy_handle *handle)
2120 struct samr_QueryUserInfo2 r;
2121 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2122 11, 12, 13, 14, 16, 17, 20, 21};
2126 for (i=0;i<ARRAY_SIZE(levels);i++) {
2127 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2129 r.in.user_handle = handle;
2130 r.in.level = levels[i];
2132 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2133 if (!NT_STATUS_IS_OK(status)) {
2134 printf("QueryUserInfo2 level %u failed - %s\n",
2135 levels[i], nt_errstr(status));
2143 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2144 struct policy_handle *handle, uint32_t rid)
2147 struct samr_OpenUser r;
2148 struct policy_handle user_handle;
2151 printf("Testing OpenUser(%u)\n", rid);
2153 r.in.domain_handle = handle;
2154 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2156 r.out.user_handle = &user_handle;
2158 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2159 if (!NT_STATUS_IS_OK(status)) {
2160 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2164 if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2168 if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2172 if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2176 if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2180 if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2184 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2191 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2192 struct policy_handle *handle, uint32_t rid)
2195 struct samr_OpenGroup r;
2196 struct policy_handle group_handle;
2199 printf("Testing OpenGroup(%u)\n", rid);
2201 r.in.domain_handle = handle;
2202 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2204 r.out.group_handle = &group_handle;
2206 status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2207 if (!NT_STATUS_IS_OK(status)) {
2208 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2212 if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2216 if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2220 if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2224 if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2231 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2232 struct policy_handle *handle, uint32_t rid)
2235 struct samr_OpenAlias r;
2236 struct policy_handle alias_handle;
2239 printf("Testing OpenAlias(%u)\n", rid);
2241 r.in.domain_handle = handle;
2242 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2244 r.out.alias_handle = &alias_handle;
2246 status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2247 if (!NT_STATUS_IS_OK(status)) {
2248 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2252 if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2256 if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2260 if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2264 if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2271 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2272 struct policy_handle *handle)
2275 struct samr_EnumDomainUsers r;
2276 uint32_t resume_handle=0;
2279 struct samr_LookupNames n;
2280 struct samr_LookupRids lr ;
2282 printf("Testing EnumDomainUsers\n");
2284 r.in.domain_handle = handle;
2285 r.in.resume_handle = &resume_handle;
2286 r.in.acct_flags = 0;
2287 r.in.max_size = (uint32_t)-1;
2288 r.out.resume_handle = &resume_handle;
2290 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2291 if (!NT_STATUS_IS_OK(status)) {
2292 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2300 if (r.out.sam->count == 0) {
2304 for (i=0;i<r.out.sam->count;i++) {
2305 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2310 printf("Testing LookupNames\n");
2311 n.in.domain_handle = handle;
2312 n.in.num_names = r.out.sam->count;
2313 n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2314 for (i=0;i<r.out.sam->count;i++) {
2315 n.in.names[i].string = r.out.sam->entries[i].name.string;
2317 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2318 if (!NT_STATUS_IS_OK(status)) {
2319 printf("LookupNames failed - %s\n", nt_errstr(status));
2324 printf("Testing LookupRids\n");
2325 lr.in.domain_handle = handle;
2326 lr.in.num_rids = r.out.sam->count;
2327 lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2328 for (i=0;i<r.out.sam->count;i++) {
2329 lr.in.rids[i] = r.out.sam->entries[i].idx;
2331 status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2332 if (!NT_STATUS_IS_OK(status)) {
2333 printf("LookupRids failed - %s\n", nt_errstr(status));
2341 try blasting the server with a bunch of sync requests
2343 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2344 struct policy_handle *handle)
2347 struct samr_EnumDomainUsers r;
2348 uint32_t resume_handle=0;
2350 #define ASYNC_COUNT 100
2351 struct rpc_request *req[ASYNC_COUNT];
2353 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2354 printf("samr async test disabled - enable dangerous tests to use\n");
2358 printf("Testing EnumDomainUsers_async\n");
2360 r.in.domain_handle = handle;
2361 r.in.resume_handle = &resume_handle;
2362 r.in.acct_flags = 0;
2363 r.in.max_size = (uint32_t)-1;
2364 r.out.resume_handle = &resume_handle;
2366 for (i=0;i<ASYNC_COUNT;i++) {
2367 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2370 for (i=0;i<ASYNC_COUNT;i++) {
2371 status = dcerpc_ndr_request_recv(req[i]);
2372 if (!NT_STATUS_IS_OK(status)) {
2373 printf("EnumDomainUsers[%d] failed - %s\n",
2374 i, nt_errstr(status));
2379 printf("%d async requests OK\n", i);
2384 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2385 struct policy_handle *handle)
2388 struct samr_EnumDomainGroups r;
2389 uint32_t resume_handle=0;
2393 printf("Testing EnumDomainGroups\n");
2395 r.in.domain_handle = handle;
2396 r.in.resume_handle = &resume_handle;
2397 r.in.max_size = (uint32_t)-1;
2398 r.out.resume_handle = &resume_handle;
2400 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2401 if (!NT_STATUS_IS_OK(status)) {
2402 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2410 for (i=0;i<r.out.sam->count;i++) {
2411 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2419 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2420 struct policy_handle *handle)
2423 struct samr_EnumDomainAliases r;
2424 uint32_t resume_handle=0;
2428 printf("Testing EnumDomainAliases\n");
2430 r.in.domain_handle = handle;
2431 r.in.resume_handle = &resume_handle;
2432 r.in.acct_flags = (uint32_t)-1;
2433 r.out.resume_handle = &resume_handle;
2435 status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2436 if (!NT_STATUS_IS_OK(status)) {
2437 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2445 for (i=0;i<r.out.sam->count;i++) {
2446 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2454 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2455 struct policy_handle *handle)
2458 struct samr_GetDisplayEnumerationIndex r;
2460 uint16_t levels[] = {1, 2, 3, 4, 5};
2461 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2464 for (i=0;i<ARRAY_SIZE(levels);i++) {
2465 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2467 r.in.domain_handle = handle;
2468 r.in.level = levels[i];
2469 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2471 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2474 !NT_STATUS_IS_OK(status) &&
2475 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2476 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2477 levels[i], nt_errstr(status));
2481 init_lsa_String(&r.in.name, "zzzzzzzz");
2483 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2485 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2486 printf("GetDisplayEnumerationIndex level %u failed - %s\n",
2487 levels[i], nt_errstr(status));
2495 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2496 struct policy_handle *handle)
2499 struct samr_GetDisplayEnumerationIndex2 r;
2501 uint16_t levels[] = {1, 2, 3, 4, 5};
2502 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2505 for (i=0;i<ARRAY_SIZE(levels);i++) {
2506 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2508 r.in.domain_handle = handle;
2509 r.in.level = levels[i];
2510 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2512 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2514 !NT_STATUS_IS_OK(status) &&
2515 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2516 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2517 levels[i], nt_errstr(status));
2521 init_lsa_String(&r.in.name, "zzzzzzzz");
2523 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2524 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2525 printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
2526 levels[i], nt_errstr(status));
2534 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2535 struct policy_handle *handle)
2538 struct samr_QueryDisplayInfo r;
2540 uint16_t levels[] = {1, 2, 3, 4, 5};
2543 for (i=0;i<ARRAY_SIZE(levels);i++) {
2544 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2546 r.in.domain_handle = handle;
2547 r.in.level = levels[i];
2549 r.in.max_entries = 1000;
2550 r.in.buf_size = (uint32_t)-1;
2552 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2553 if (!NT_STATUS_IS_OK(status)) {
2554 printf("QueryDisplayInfo level %u failed - %s\n",
2555 levels[i], nt_errstr(status));
2563 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2564 struct policy_handle *handle)
2567 struct samr_QueryDisplayInfo2 r;
2569 uint16_t levels[] = {1, 2, 3, 4, 5};
2572 for (i=0;i<ARRAY_SIZE(levels);i++) {
2573 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2575 r.in.domain_handle = handle;
2576 r.in.level = levels[i];
2578 r.in.max_entries = 1000;
2579 r.in.buf_size = (uint32_t)-1;
2581 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2582 if (!NT_STATUS_IS_OK(status)) {
2583 printf("QueryDisplayInfo2 level %u failed - %s\n",
2584 levels[i], nt_errstr(status));
2592 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2593 struct policy_handle *handle)
2596 struct samr_QueryDisplayInfo3 r;
2598 uint16_t levels[] = {1, 2, 3, 4, 5};
2601 for (i=0;i<ARRAY_SIZE(levels);i++) {
2602 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2604 r.in.domain_handle = handle;
2605 r.in.level = levels[i];
2607 r.in.max_entries = 1000;
2608 r.in.buf_size = (uint32_t)-1;
2610 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2611 if (!NT_STATUS_IS_OK(status)) {
2612 printf("QueryDisplayInfo3 level %u failed - %s\n",
2613 levels[i], nt_errstr(status));
2622 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2623 struct policy_handle *handle)
2626 struct samr_QueryDisplayInfo r;
2629 printf("Testing QueryDisplayInfo continuation\n");
2631 r.in.domain_handle = handle;
2634 r.in.max_entries = 1;
2635 r.in.buf_size = (uint32_t)-1;
2638 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2639 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2640 if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2641 printf("expected idx %d but got %d\n",
2643 r.out.info.info1.entries[0].idx);
2647 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2648 !NT_STATUS_IS_OK(status)) {
2649 printf("QueryDisplayInfo level %u failed - %s\n",
2650 r.in.level, nt_errstr(status));
2655 } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2656 NT_STATUS_IS_OK(status)) &&
2657 r.out.returned_size != 0);
2662 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2663 struct policy_handle *handle)
2666 struct samr_QueryDomainInfo r;
2667 struct samr_SetDomainInfo s;
2668 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2669 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
2672 const char *domain_comment = talloc_asprintf(mem_ctx,
2673 "Tortured by Samba4 RPC-SAMR: %s",
2674 timestring(mem_ctx, time(NULL)));
2676 s.in.domain_handle = handle;
2678 s.in.info = talloc(mem_ctx, union samr_DomainInfo);
2680 s.in.info->info4.comment.string = domain_comment;
2681 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2682 if (!NT_STATUS_IS_OK(status)) {
2683 printf("SetDomainInfo level %u (set comment) failed - %s\n",
2684 r.in.level, nt_errstr(status));
2688 for (i=0;i<ARRAY_SIZE(levels);i++) {
2689 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2691 r.in.domain_handle = handle;
2692 r.in.level = levels[i];
2694 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2695 if (!NT_STATUS_IS_OK(status)) {
2696 printf("QueryDomainInfo level %u failed - %s\n",
2697 r.in.level, nt_errstr(status));
2702 switch (levels[i]) {
2704 if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
2705 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2706 levels[i], r.out.info->info2.comment.string, domain_comment);
2711 if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
2712 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2713 levels[i], r.out.info->info4.comment.string, domain_comment);
2718 if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
2719 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
2720 levels[i], r.out.info->info11.info2.comment.string, domain_comment);
2726 printf("Testing SetDomainInfo level %u\n", levels[i]);
2728 s.in.domain_handle = handle;
2729 s.in.level = levels[i];
2730 s.in.info = r.out.info;
2732 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2734 if (!NT_STATUS_IS_OK(status)) {
2735 printf("SetDomainInfo level %u failed - %s\n",
2736 r.in.level, nt_errstr(status));
2741 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2742 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
2743 r.in.level, nt_errstr(status));
2749 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2750 if (!NT_STATUS_IS_OK(status)) {
2751 printf("QueryDomainInfo level %u failed - %s\n",
2752 r.in.level, nt_errstr(status));
2762 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2763 struct policy_handle *handle)
2766 struct samr_QueryDomainInfo2 r;
2767 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2771 for (i=0;i<ARRAY_SIZE(levels);i++) {
2772 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2774 r.in.domain_handle = handle;
2775 r.in.level = levels[i];
2777 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2778 if (!NT_STATUS_IS_OK(status)) {
2779 printf("QueryDomainInfo2 level %u failed - %s\n",
2780 r.in.level, nt_errstr(status));
2789 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2790 set of group names. */
2791 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2792 struct policy_handle *handle)
2794 struct samr_EnumDomainGroups q1;
2795 struct samr_QueryDisplayInfo q2;
2797 uint32_t resume_handle=0;
2802 const char **names = NULL;
2804 printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2806 q1.in.domain_handle = handle;
2807 q1.in.resume_handle = &resume_handle;
2809 q1.out.resume_handle = &resume_handle;
2811 status = STATUS_MORE_ENTRIES;
2812 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2813 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2815 if (!NT_STATUS_IS_OK(status) &&
2816 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2819 for (i=0; i<q1.out.num_entries; i++) {
2820 add_string_to_array(mem_ctx,
2821 q1.out.sam->entries[i].name.string,
2822 &names, &num_names);
2826 if (!NT_STATUS_IS_OK(status)) {
2827 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2835 q2.in.domain_handle = handle;
2837 q2.in.start_idx = 0;
2838 q2.in.max_entries = 5;
2839 q2.in.buf_size = (uint32_t)-1;
2841 status = STATUS_MORE_ENTRIES;
2842 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2843 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2845 if (!NT_STATUS_IS_OK(status) &&
2846 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2849 for (i=0; i<q2.out.info.info5.count; i++) {
2851 const char *name = q2.out.info.info5.entries[i].account_name.string;
2853 for (j=0; j<num_names; j++) {
2854 if (names[j] == NULL)
2856 /* Hmm. No strequal in samba4 */
2857 if (strequal(names[j], name)) {
2865 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2870 q2.in.start_idx += q2.out.info.info5.count;
2873 if (!NT_STATUS_IS_OK(status)) {
2874 printf("QueryDisplayInfo level 5 failed - %s\n",
2879 for (i=0; i<num_names; i++) {
2880 if (names[i] != NULL) {
2881 printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2890 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2891 struct policy_handle *group_handle)
2893 struct samr_DeleteDomainGroup d;
2897 printf("Testing DeleteDomainGroup\n");
2899 d.in.group_handle = group_handle;
2900 d.out.group_handle = group_handle;
2902 status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2903 if (!NT_STATUS_IS_OK(status)) {
2904 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2911 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2912 struct policy_handle *domain_handle)
2914 struct samr_TestPrivateFunctionsDomain r;
2918 printf("Testing TestPrivateFunctionsDomain\n");
2920 r.in.domain_handle = domain_handle;
2922 status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2923 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2924 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2931 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2932 struct dom_sid *domain_sid,
2933 struct policy_handle *domain_handle)
2935 struct samr_RidToSid r;
2938 struct dom_sid *calc_sid;
2939 int rids[] = { 0, 42, 512, 10200 };
2942 for (i=0;i<ARRAY_SIZE(rids);i++) {
2944 printf("Testing RidToSid\n");
2946 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2947 r.in.domain_handle = domain_handle;
2950 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2951 if (!NT_STATUS_IS_OK(status)) {
2952 printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2955 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2957 if (!dom_sid_equal(calc_sid, r.out.sid)) {
2958 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
2959 dom_sid_string(mem_ctx, r.out.sid),
2960 dom_sid_string(mem_ctx, calc_sid));
2969 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2970 struct policy_handle *domain_handle)
2972 struct samr_GetBootKeyInformation r;
2976 printf("Testing GetBootKeyInformation\n");
2978 r.in.domain_handle = domain_handle;
2980 status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2981 if (!NT_STATUS_IS_OK(status)) {
2982 /* w2k3 seems to fail this sometimes and pass it sometimes */
2983 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2989 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2990 struct policy_handle *domain_handle,
2991 struct policy_handle *group_handle)
2994 struct samr_AddGroupMember r;
2995 struct samr_DeleteGroupMember d;
2996 struct samr_QueryGroupMember q;
2997 struct samr_SetMemberAttributesOfGroup s;
3001 status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
3002 if (!NT_STATUS_IS_OK(status)) {
3006 r.in.group_handle = group_handle;
3008 r.in.flags = 0; /* ??? */
3010 printf("Testing AddGroupMember and DeleteGroupMember\n");
3012 d.in.group_handle = group_handle;
3015 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3016 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
3017 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n",
3022 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3023 if (!NT_STATUS_IS_OK(status)) {
3024 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3028 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3029 if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
3030 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n",
3035 if (lp_parm_bool(-1, "target", "samba4", False)) {
3036 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
3038 /* this one is quite strange. I am using random inputs in the
3039 hope of triggering an error that might give us a clue */
3041 s.in.group_handle = group_handle;
3042 s.in.unknown1 = random();
3043 s.in.unknown2 = random();
3045 status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
3046 if (!NT_STATUS_IS_OK(status)) {
3047 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
3052 q.in.group_handle = group_handle;
3054 status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
3060 status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
3061 if (!NT_STATUS_IS_OK(status)) {
3062 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
3066 status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3067 if (!NT_STATUS_IS_OK(status)) {
3068 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3076 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3077 struct policy_handle *domain_handle, struct policy_handle *group_handle)
3080 struct samr_CreateDomainGroup r;
3082 struct lsa_String name;
3085 init_lsa_String(&name, TEST_GROUPNAME);
3087 r.in.domain_handle = domain_handle;
3089 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3090 r.out.group_handle = group_handle;
3093 printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3095 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3097 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3098 printf("Server refused create of '%s'\n", r.in.name->string);
3099 ZERO_STRUCTP(group_handle);
3103 if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3104 NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3105 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3108 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3110 if (!NT_STATUS_IS_OK(status)) {
3111 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3115 if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3119 if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3128 its not totally clear what this does. It seems to accept any sid you like.
3130 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
3131 TALLOC_CTX *mem_ctx,
3132 struct policy_handle *domain_handle)
3135 struct samr_RemoveMemberFromForeignDomain r;
3137 r.in.domain_handle = domain_handle;
3138 r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3140 status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3141 if (!NT_STATUS_IS_OK(status)) {
3142 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3151 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3152 struct policy_handle *handle);
3154 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3155 struct policy_handle *handle, struct dom_sid *sid)
3158 struct samr_OpenDomain r;
3159 struct policy_handle domain_handle;
3160 struct policy_handle user_handle;
3161 struct policy_handle alias_handle;
3162 struct policy_handle group_handle;
3165 ZERO_STRUCT(user_handle);
3166 ZERO_STRUCT(alias_handle);
3167 ZERO_STRUCT(group_handle);
3168 ZERO_STRUCT(domain_handle);
3170 printf("Testing OpenDomain\n");
3172 r.in.connect_handle = handle;
3173 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3175 r.out.domain_handle = &domain_handle;
3177 status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("OpenDomain failed - %s\n", nt_errstr(status));
3183 /* run the domain tests with the main handle closed - this tests
3184 the servers reference counting */
3185 ret &= test_samr_handle_Close(p, mem_ctx, handle);
3187 ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3188 ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3189 ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3190 ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3191 ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3192 ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3193 ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3194 ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3195 ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3196 ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3197 ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3198 ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3199 ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3200 ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3201 ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3202 ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3204 if (lp_parm_bool(-1, "target", "samba4", False)) {
3205 printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
3207 ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3208 ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3210 ret &= test_GroupList(p, mem_ctx, &domain_handle);
3211 ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3212 ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3213 ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3215 if (!policy_handle_empty(&user_handle) &&
3216 !test_DeleteUser(p, mem_ctx, &user_handle)) {
3220 if (!policy_handle_empty(&alias_handle) &&
3221 !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3225 if (!policy_handle_empty(&group_handle) &&
3226 !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3230 ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3232 /* reconnect the main handle */
3233 ret &= test_Connect(p, mem_ctx, handle);
3238 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3239 struct policy_handle *handle, struct lsa_String *domain)
3242 struct samr_LookupDomain r;
3243 struct lsa_String n2;
3246 printf("Testing LookupDomain(%s)\n", domain->string);
3248 /* check for correct error codes */
3249 r.in.connect_handle = handle;
3250 r.in.domain_name = &n2;
3253 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3254 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3255 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3259 n2.string = "xxNODOMAINxx";
3261 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3262 if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3263 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3267 r.in.connect_handle = handle;
3268 r.in.domain_name = domain;
3270 status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 printf("LookupDomain failed - %s\n", nt_errstr(status));
3276 if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3280 if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3288 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3289 struct policy_handle *handle)
3292 struct samr_EnumDomains r;
3293 uint32_t resume_handle = 0;
3297 r.in.connect_handle = handle;
3298 r.in.resume_handle = &resume_handle;
3299 r.in.buf_size = (uint32_t)-1;
3300 r.out.resume_handle = &resume_handle;
3302 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3303 if (!NT_STATUS_IS_OK(status)) {
3304 printf("EnumDomains failed - %s\n", nt_errstr(status));
3312 for (i=0;i<r.out.sam->count;i++) {
3313 if (!test_LookupDomain(p, mem_ctx, handle,
3314 &r.out.sam->entries[i].name)) {
3319 status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3320 if (!NT_STATUS_IS_OK(status)) {
3321 printf("EnumDomains failed - %s\n", nt_errstr(status));
3329 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3330 struct policy_handle *handle)
3333 struct samr_Connect r;
3334 struct samr_Connect2 r2;
3335 struct samr_Connect3 r3;
3336 struct samr_Connect4 r4;
3337 struct samr_Connect5 r5;
3338 union samr_ConnectInfo info;
3339 struct policy_handle h;
3340 BOOL ret = True, got_handle = False;
3342 printf("testing samr_Connect\n");
3344 r.in.system_name = 0;
3345 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3346 r.out.connect_handle = &h;
3348 status = dcerpc_samr_Connect(p, mem_ctx, &r);
3349 if (!NT_STATUS_IS_OK(status)) {
3350 printf("Connect failed - %s\n", nt_errstr(status));
3357 printf("testing samr_Connect2\n");
3359 r2.in.system_name = NULL;
3360 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3361 r2.out.connect_handle = &h;
3363 status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3364 if (!NT_STATUS_IS_OK(status)) {
3365 printf("Connect2 failed - %s\n", nt_errstr(status));
3369 test_samr_handle_Close(p, mem_ctx, handle);
3375 printf("testing samr_Connect3\n");
3377 r3.in.system_name = NULL;
3379 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3380 r3.out.connect_handle = &h;
3382 status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3383 if (!NT_STATUS_IS_OK(status)) {
3384 printf("Connect3 failed - %s\n", nt_errstr(status));
3388 test_samr_handle_Close(p, mem_ctx, handle);
3394 printf("testing samr_Connect4\n");
3396 r4.in.system_name = "";
3398 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3399 r4.out.connect_handle = &h;
3401 status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3402 if (!NT_STATUS_IS_OK(status)) {
3403 printf("Connect4 failed - %s\n", nt_errstr(status));
3407 test_samr_handle_Close(p, mem_ctx, handle);
3413 printf("testing samr_Connect5\n");
3415 info.info1.unknown1 = 0;
3416 info.info1.unknown2 = 0;
3418 r5.in.system_name = "";
3419 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3422 r5.out.info = &info;
3423 r5.out.connect_handle = &h;
3425 status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3426 if (!NT_STATUS_IS_OK(status)) {
3427 printf("Connect5 failed - %s\n", nt_errstr(status));
3431 test_samr_handle_Close(p, mem_ctx, handle);
3441 BOOL torture_rpc_samr(struct torture_context *torture)
3444 struct dcerpc_pipe *p;
3446 struct policy_handle handle;
3448 status = torture_rpc_connection(torture, &p, &dcerpc_table_samr);
3449 if (!NT_STATUS_IS_OK(status)) {
3453 ret &= test_Connect(p, torture, &handle);
3455 ret &= test_QuerySecurity(p, torture, &handle);
3457 ret &= test_EnumDomains(p, torture, &handle);
3459 ret &= test_SetDsrmPassword(p, torture, &handle);
3461 ret &= test_Shutdown(p, torture, &handle);
3463 ret &= test_samr_handle_Close(p, torture, &handle);