r14860: create libcli/security/security.h
[bbaumbach/samba-autobuild/.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
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.
12    
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.
17    
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.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "librpc/gen_ndr/ndr_security.h"
28 #include "smb.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"
33
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$"
39
40
41 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
42                                struct policy_handle *handle);
43
44 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
45                                 struct policy_handle *handle);
46
47 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
48                                struct policy_handle *handle);
49
50 static void init_lsa_String(struct lsa_String *string, const char *s)
51 {
52         string->string = s;
53 }
54
55 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
56                                    struct policy_handle *handle)
57 {
58         NTSTATUS status;
59         struct samr_Close r;
60
61         r.in.handle = handle;
62         r.out.handle = handle;
63
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));
67                 return False;
68         }
69
70         return True;
71 }
72
73 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
74                        struct policy_handle *handle)
75 {
76         NTSTATUS status;
77         struct samr_Shutdown r;
78
79         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
80                 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
81                 return True;
82         }
83
84         r.in.connect_handle = handle;
85
86         printf("testing samr_Shutdown\n");
87
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));
91                 return False;
92         }
93
94         return True;
95 }
96
97 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
98                                  struct policy_handle *handle)
99 {
100         NTSTATUS status;
101         struct samr_SetDsrmPassword r;
102         struct lsa_String string;
103         struct samr_Password hash;
104
105         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
106                 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
107                 return True;
108         }
109
110         E_md4hash("TeSTDSRM123", hash.hash);
111
112         init_lsa_String(&string, "Administrator");
113
114         r.in.name = &string;
115         r.in.unknown = 0;
116         r.in.hash = &hash;
117
118         printf("testing samr_SetDsrmPassword\n");
119
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));
123                 return False;
124         }
125
126         return True;
127 }
128
129
130 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
131                                struct policy_handle *handle)
132 {
133         NTSTATUS status;
134         struct samr_QuerySecurity r;
135         struct samr_SetSecurity s;
136
137         r.in.handle = handle;
138         r.in.sec_info = 7;
139
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));
143                 return False;
144         }
145
146         if (r.out.sdbuf == NULL) {
147                 return False;
148         }
149
150         s.in.handle = handle;
151         s.in.sec_info = 7;
152         s.in.sdbuf = r.out.sdbuf;
153
154         status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
155         if (!NT_STATUS_IS_OK(status)) {
156                 printf("SetSecurity failed - %s\n", nt_errstr(status));
157                 return False;
158         }
159
160         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
161         if (!NT_STATUS_IS_OK(status)) {
162                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
163                 return False;
164         }
165
166         return True;
167 }
168
169
170 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
171                              struct policy_handle *handle, uint32_t base_acct_flags,
172                              const char *base_account_name)
173 {
174         NTSTATUS status;
175         struct samr_SetUserInfo s;
176         struct samr_SetUserInfo2 s2;
177         struct samr_QueryUserInfo q;
178         struct samr_QueryUserInfo q0;
179         union samr_UserInfo u;
180         BOOL ret = True;
181         const char *test_account_name;
182
183         uint32_t user_extra_flags = 0;
184         if (base_acct_flags == ACB_NORMAL) {
185                 /* When created, accounts are expired by default */
186                 user_extra_flags = ACB_PW_EXPIRED;
187         }
188
189         s.in.user_handle = handle;
190         s.in.info = &u;
191
192         s2.in.user_handle = handle;
193         s2.in.info = &u;
194
195         q.in.user_handle = handle;
196         q.out.info = &u;
197         q0 = q;
198
199 #define TESTCALL(call, r) \
200                 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
201                 if (!NT_STATUS_IS_OK(status)) { \
202                         printf(#call " level %u failed - %s (%s)\n", \
203                                r.in.level, nt_errstr(status), __location__); \
204                         ret = False; \
205                         break; \
206                 }
207
208 #define STRING_EQUAL(s1, s2, field) \
209                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
210                         printf("Failed to set %s to '%s' (%s)\n", \
211                                #field, s2, __location__); \
212                         ret = False; \
213                         break; \
214                 }
215
216 #define INT_EQUAL(i1, i2, field) \
217                 if (i1 != i2) { \
218                         printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
219                                #field, i2, i1, __location__); \
220                         ret = False; \
221                         break; \
222                 }
223
224 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
225                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
226                 q.in.level = lvl1; \
227                 TESTCALL(QueryUserInfo, q) \
228                 s.in.level = lvl1; \
229                 s2.in.level = lvl1; \
230                 u = *q.out.info; \
231                 if (lvl1 == 21) { \
232                         ZERO_STRUCT(u.info21); \
233                         u.info21.fields_present = fpval; \
234                 } \
235                 init_lsa_String(&u.info ## lvl1.field1, value); \
236                 TESTCALL(SetUserInfo, s) \
237                 TESTCALL(SetUserInfo2, s2) \
238                 init_lsa_String(&u.info ## lvl1.field1, ""); \
239                 TESTCALL(QueryUserInfo, q); \
240                 u = *q.out.info; \
241                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
242                 q.in.level = lvl2; \
243                 TESTCALL(QueryUserInfo, q) \
244                 u = *q.out.info; \
245                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
246         } while (0)
247
248 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
249                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
250                 q.in.level = lvl1; \
251                 TESTCALL(QueryUserInfo, q) \
252                 s.in.level = lvl1; \
253                 s2.in.level = lvl1; \
254                 u = *q.out.info; \
255                 if (lvl1 == 21) { \
256                         uint8_t *bits = u.info21.logon_hours.bits; \
257                         ZERO_STRUCT(u.info21); \
258                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
259                                 u.info21.logon_hours.units_per_week = 168; \
260                                 u.info21.logon_hours.bits = bits; \
261                         } \
262                         u.info21.fields_present = fpval; \
263                 } \
264                 u.info ## lvl1.field1 = value; \
265                 TESTCALL(SetUserInfo, s) \
266                 TESTCALL(SetUserInfo2, s2) \
267                 u.info ## lvl1.field1 = 0; \
268                 TESTCALL(QueryUserInfo, q); \
269                 u = *q.out.info; \
270                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
271                 q.in.level = lvl2; \
272                 TESTCALL(QueryUserInfo, q) \
273                 u = *q.out.info; \
274                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
275         } while (0)
276
277 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
278         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
279         } while (0)
280
281         q0.in.level = 12;
282         do { TESTCALL(QueryUserInfo, q0) } while (0);
283
284         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
285         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
286         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment", 
287                            SAMR_FIELD_COMMENT);
288
289         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
290         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
291         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
292         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
293         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
294         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
295         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
296         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
297         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
298         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
299         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
300         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
301         test_account_name = base_account_name;
302         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name, 
303                            SAMR_FIELD_ACCOUNT_NAME);
304
305         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
306         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
307         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
308         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
309         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
310         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
311         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
312         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name", 
313                            SAMR_FIELD_FULL_NAME);
314
315         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
316         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
317         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
318         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
319                            SAMR_FIELD_LOGON_SCRIPT);
320
321         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
322         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
323         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
324         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
325                            SAMR_FIELD_PROFILE_PATH);
326
327         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
328         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
329         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
330         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
331                            SAMR_FIELD_DESCRIPTION);
332
333         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
334         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
335         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
336         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
337                            SAMR_FIELD_WORKSTATIONS);
338
339         TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
340         TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters", 
341                            SAMR_FIELD_PARAMETERS);
342
343         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
344         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
345                           SAMR_FIELD_COUNTRY_CODE);
346
347         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
348         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
349                           SAMR_FIELD_CODE_PAGE);
350
351         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
352         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
353         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
354         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
355                           SAMR_FIELD_LOGON_HOURS);
356
357         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
358                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
359                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
360                               0);
361         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
362                               (base_acct_flags  | ACB_DISABLED), 
363                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
364                               0);
365         
366         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
367         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
368                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
369                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
370                               0);
371         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
372                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
373                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
374                               0);
375
376         /* The 'autolock' flag doesn't stick - check this */
377         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
378                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
379                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
380                               0);
381
382         /* The 'store plaintext' flag does stick */
383         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
384                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
385                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
386                               0);
387         /* The 'use DES' flag does stick */
388         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
389                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
390                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
391                               0);
392         /* The 'don't require kerberos pre-authentication flag does stick */
393         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
394                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
395                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
396                               0);
397         /* The 'no kerberos PAC required' flag sticks */
398         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
399                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
400                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
401                               0);
402
403         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
404                               (base_acct_flags | ACB_DISABLED), 
405                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
406                               SAMR_FIELD_ACCT_FLAGS);
407
408 #if 0
409         /* these fail with win2003 - it appears you can't set the primary gid?
410            the set succeeds, but the gid isn't changed. Very weird! */
411         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
412         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
413         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
414         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
415 #endif
416
417         return ret;
418 }
419
420 /*
421   generate a random password for password change tests
422 */
423 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
424 {
425         size_t len = MAX(8, min_len) + (random() % 6);
426         char *s = generate_random_str(mem_ctx, len);
427         printf("Generated password '%s'\n", s);
428         return s;
429 }
430
431 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
432                              struct policy_handle *handle, char **password)
433 {
434         NTSTATUS status;
435         struct samr_SetUserInfo s;
436         union samr_UserInfo u;
437         BOOL ret = True;
438         DATA_BLOB session_key;
439         char *newpass;
440         struct samr_GetUserPwInfo pwp;
441         int policy_min_pw_len = 0;
442         pwp.in.user_handle = handle;
443
444         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
445         if (NT_STATUS_IS_OK(status)) {
446                 policy_min_pw_len = pwp.out.info.min_password_length;
447         }
448         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
449
450         s.in.user_handle = handle;
451         s.in.info = &u;
452         s.in.level = 24;
453
454         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
455         /* w2k3 ignores this length */
456         u.info24.pw_len = strlen_m(newpass) * 2;
457
458         status = dcerpc_fetch_session_key(p, &session_key);
459         if (!NT_STATUS_IS_OK(status)) {
460                 printf("SetUserInfo level %u - no session key - %s\n",
461                        s.in.level, nt_errstr(status));
462                 return False;
463         }
464
465         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
466
467         printf("Testing SetUserInfo level 24 (set password)\n");
468
469         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
470         if (!NT_STATUS_IS_OK(status)) {
471                 printf("SetUserInfo level %u failed - %s\n",
472                        s.in.level, nt_errstr(status));
473                 ret = False;
474         } else {
475                 *password = newpass;
476         }
477
478         return ret;
479 }
480
481
482 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
483                                 struct policy_handle *handle, uint32_t fields_present,
484                                 char **password)
485 {
486         NTSTATUS status;
487         struct samr_SetUserInfo s;
488         union samr_UserInfo u;
489         BOOL ret = True;
490         DATA_BLOB session_key;
491         char *newpass;
492         struct samr_GetUserPwInfo pwp;
493         int policy_min_pw_len = 0;
494         pwp.in.user_handle = handle;
495
496         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
497         if (NT_STATUS_IS_OK(status)) {
498                 policy_min_pw_len = pwp.out.info.min_password_length;
499         }
500         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
501
502         s.in.user_handle = handle;
503         s.in.info = &u;
504         s.in.level = 23;
505
506         ZERO_STRUCT(u);
507
508         u.info23.info.fields_present = fields_present;
509
510         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
511
512         status = dcerpc_fetch_session_key(p, &session_key);
513         if (!NT_STATUS_IS_OK(status)) {
514                 printf("SetUserInfo level %u - no session key - %s\n",
515                        s.in.level, nt_errstr(status));
516                 return False;
517         }
518
519         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
520
521         printf("Testing SetUserInfo level 23 (set password)\n");
522
523         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
524         if (!NT_STATUS_IS_OK(status)) {
525                 printf("SetUserInfo level %u failed - %s\n",
526                        s.in.level, nt_errstr(status));
527                 ret = False;
528         } else {
529                 *password = newpass;
530         }
531
532         return ret;
533 }
534
535
536 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
537                                struct policy_handle *handle, char **password)
538 {
539         NTSTATUS status;
540         struct samr_SetUserInfo s;
541         union samr_UserInfo u;
542         BOOL ret = True;
543         DATA_BLOB session_key;
544         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
545         uint8_t confounder[16];
546         char *newpass;
547         struct MD5Context ctx;
548         struct samr_GetUserPwInfo pwp;
549         int policy_min_pw_len = 0;
550         pwp.in.user_handle = handle;
551
552         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
553         if (NT_STATUS_IS_OK(status)) {
554                 policy_min_pw_len = pwp.out.info.min_password_length;
555         }
556         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
557
558         s.in.user_handle = handle;
559         s.in.info = &u;
560         s.in.level = 26;
561
562         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
563         u.info26.pw_len = strlen(newpass);
564
565         status = dcerpc_fetch_session_key(p, &session_key);
566         if (!NT_STATUS_IS_OK(status)) {
567                 printf("SetUserInfo level %u - no session key - %s\n",
568                        s.in.level, nt_errstr(status));
569                 return False;
570         }
571
572         generate_random_buffer((uint8_t *)confounder, 16);
573
574         MD5Init(&ctx);
575         MD5Update(&ctx, confounder, 16);
576         MD5Update(&ctx, session_key.data, session_key.length);
577         MD5Final(confounded_session_key.data, &ctx);
578
579         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
580         memcpy(&u.info26.password.data[516], confounder, 16);
581
582         printf("Testing SetUserInfo level 26 (set password ex)\n");
583
584         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
585         if (!NT_STATUS_IS_OK(status)) {
586                 printf("SetUserInfo level %u failed - %s\n",
587                        s.in.level, nt_errstr(status));
588                 ret = False;
589         } else {
590                 *password = newpass;
591         }
592
593         return ret;
594 }
595
596 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
597                                 struct policy_handle *handle, uint32_t fields_present,
598                                 char **password)
599 {
600         NTSTATUS status;
601         struct samr_SetUserInfo s;
602         union samr_UserInfo u;
603         BOOL ret = True;
604         DATA_BLOB session_key;
605         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
606         struct MD5Context ctx;
607         uint8_t confounder[16];
608         char *newpass;
609         struct samr_GetUserPwInfo pwp;
610         int policy_min_pw_len = 0;
611         pwp.in.user_handle = handle;
612
613         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
614         if (NT_STATUS_IS_OK(status)) {
615                 policy_min_pw_len = pwp.out.info.min_password_length;
616         }
617         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
618
619         s.in.user_handle = handle;
620         s.in.info = &u;
621         s.in.level = 25;
622
623         ZERO_STRUCT(u);
624
625         u.info25.info.fields_present = fields_present;
626
627         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
628
629         status = dcerpc_fetch_session_key(p, &session_key);
630         if (!NT_STATUS_IS_OK(status)) {
631                 printf("SetUserInfo level %u - no session key - %s\n",
632                        s.in.level, nt_errstr(status));
633                 return False;
634         }
635
636         generate_random_buffer((uint8_t *)confounder, 16);
637
638         MD5Init(&ctx);
639         MD5Update(&ctx, confounder, 16);
640         MD5Update(&ctx, session_key.data, session_key.length);
641         MD5Final(confounded_session_key.data, &ctx);
642
643         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
644         memcpy(&u.info25.password.data[516], confounder, 16);
645
646         printf("Testing SetUserInfo level 25 (set password ex)\n");
647
648         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
649         if (!NT_STATUS_IS_OK(status)) {
650                 printf("SetUserInfo level %u failed - %s\n",
651                        s.in.level, nt_errstr(status));
652                 ret = False;
653         } else {
654                 *password = newpass;
655         }
656
657         return ret;
658 }
659
660 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
661                                struct policy_handle *handle)
662 {
663         NTSTATUS status;
664         struct samr_SetAliasInfo r;
665         struct samr_QueryAliasInfo q;
666         uint16_t levels[] = {2, 3};
667         int i;
668         BOOL ret = True;
669
670         /* Ignoring switch level 1, as that includes the number of members for the alias
671          * and setting this to a wrong value might have negative consequences
672          */
673
674         for (i=0;i<ARRAY_SIZE(levels);i++) {
675                 printf("Testing SetAliasInfo level %u\n", levels[i]);
676
677                 r.in.alias_handle = handle;
678                 r.in.level = levels[i];
679                 r.in.info  = talloc(mem_ctx, union samr_AliasInfo);
680                 switch (r.in.level) {
681                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
682                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
683                                 "Test Description, should test I18N as well"); break;
684                 }
685
686                 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
687                 if (!NT_STATUS_IS_OK(status)) {
688                         printf("SetAliasInfo level %u failed - %s\n",
689                                levels[i], nt_errstr(status));
690                         ret = False;
691                 }
692
693                 q.in.alias_handle = handle;
694                 q.in.level = levels[i];
695
696                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
697                 if (!NT_STATUS_IS_OK(status)) {
698                         printf("QueryAliasInfo level %u failed - %s\n",
699                                levels[i], nt_errstr(status));
700                         ret = False;
701                 }
702         }
703
704         return ret;
705 }
706
707 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
708                                   struct policy_handle *user_handle)
709 {
710         struct samr_GetGroupsForUser r;
711         NTSTATUS status;
712         BOOL ret = True;
713
714         printf("testing GetGroupsForUser\n");
715
716         r.in.user_handle = user_handle;
717
718         status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
719         if (!NT_STATUS_IS_OK(status)) {
720                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
721                 ret = False;
722         }
723
724         return ret;
725
726 }
727
728 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
729                               struct lsa_String *domain_name)
730 {
731         NTSTATUS status;
732         struct samr_GetDomPwInfo r;
733         BOOL ret = True;
734
735         r.in.domain_name = domain_name;
736         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
737
738         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
739         if (!NT_STATUS_IS_OK(status)) {
740                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
741                 ret = False;
742         }
743
744         r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
745         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
746
747         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
748         if (!NT_STATUS_IS_OK(status)) {
749                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
750                 ret = False;
751         }
752
753         r.in.domain_name->string = "\\\\__NONAME__";
754         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
755
756         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
757         if (!NT_STATUS_IS_OK(status)) {
758                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
759                 ret = False;
760         }
761
762         r.in.domain_name->string = "\\\\Builtin";
763         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
764
765         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
766         if (!NT_STATUS_IS_OK(status)) {
767                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
768                 ret = False;
769         }
770
771
772         return ret;
773 }
774
775 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
776                                struct policy_handle *handle)
777 {
778         NTSTATUS status;
779         struct samr_GetUserPwInfo r;
780         BOOL ret = True;
781
782         printf("Testing GetUserPwInfo\n");
783
784         r.in.user_handle = handle;
785
786         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
787         if (!NT_STATUS_IS_OK(status)) {
788                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
789                 ret = False;
790         }
791
792         return ret;
793 }
794
795 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
796                                 struct policy_handle *domain_handle, const char *name,
797                                 uint32_t *rid)
798 {
799         NTSTATUS status;
800         struct samr_LookupNames n;
801         struct lsa_String sname[2];
802
803         init_lsa_String(&sname[0], name);
804
805         n.in.domain_handle = domain_handle;
806         n.in.num_names = 1;
807         n.in.names = sname;
808         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
809         if (NT_STATUS_IS_OK(status)) {
810                 *rid = n.out.rids.ids[0];
811         } else {
812                 return status;
813         }
814
815         init_lsa_String(&sname[1], "xxNONAMExx");
816         n.in.num_names = 2;
817         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
818         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
819                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
820                 return status;
821         }
822
823         init_lsa_String(&sname[1], "xxNONAMExx");
824         n.in.num_names = 0;
825         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
826         if (!NT_STATUS_IS_OK(status)) {
827                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
828         }
829
830         return status;
831 }
832
833 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
834                                      struct policy_handle *domain_handle,
835                                      const char *name, struct policy_handle *user_handle)
836 {
837         NTSTATUS status;
838         struct samr_OpenUser r;
839         uint32_t rid;
840
841         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
842         if (!NT_STATUS_IS_OK(status)) {
843                 return status;
844         }
845
846         r.in.domain_handle = domain_handle;
847         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
848         r.in.rid = rid;
849         r.out.user_handle = user_handle;
850         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
851         if (!NT_STATUS_IS_OK(status)) {
852                 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
853         }
854
855         return status;
856 }
857
858 #if 0
859 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
860                                    struct policy_handle *handle)
861 {
862         NTSTATUS status;
863         struct samr_ChangePasswordUser r;
864         BOOL ret = True;
865         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
866         struct policy_handle user_handle;
867         char *oldpass = "test";
868         char *newpass = "test2";
869         uint8_t old_nt_hash[16], new_nt_hash[16];
870         uint8_t old_lm_hash[16], new_lm_hash[16];
871
872         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
873         if (!NT_STATUS_IS_OK(status)) {
874                 return False;
875         }
876
877         printf("Testing ChangePasswordUser for user 'testuser'\n");
878
879         printf("old password: %s\n", oldpass);
880         printf("new password: %s\n", newpass);
881
882         E_md4hash(oldpass, old_nt_hash);
883         E_md4hash(newpass, new_nt_hash);
884         E_deshash(oldpass, old_lm_hash);
885         E_deshash(newpass, new_lm_hash);
886
887         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
888         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
889         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
890         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
891         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
892         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
893
894         r.in.handle = &user_handle;
895         r.in.lm_present = 1;
896         r.in.old_lm_crypted = &hash1;
897         r.in.new_lm_crypted = &hash2;
898         r.in.nt_present = 1;
899         r.in.old_nt_crypted = &hash3;
900         r.in.new_nt_crypted = &hash4;
901         r.in.cross1_present = 1;
902         r.in.nt_cross = &hash5;
903         r.in.cross2_present = 1;
904         r.in.lm_cross = &hash6;
905
906         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
907         if (!NT_STATUS_IS_OK(status)) {
908                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
909                 ret = False;
910         }
911
912         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
913                 ret = False;
914         }
915
916         return ret;
917 }
918 #endif
919
920 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
921                                     struct policy_handle *handle, char **password)
922 {
923         NTSTATUS status;
924         struct samr_ChangePasswordUser r;
925         BOOL ret = True;
926         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
927         struct policy_handle user_handle;
928         char *oldpass = *password;
929         uint8_t old_nt_hash[16], new_nt_hash[16];
930         uint8_t old_lm_hash[16], new_lm_hash[16];
931
932         char *newpass;
933         struct samr_GetUserPwInfo pwp;
934         int policy_min_pw_len = 0;
935
936         status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
937         if (!NT_STATUS_IS_OK(status)) {
938                 return False;
939         }
940         pwp.in.user_handle = &user_handle;
941
942         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
943         if (NT_STATUS_IS_OK(status)) {
944                 policy_min_pw_len = pwp.out.info.min_password_length;
945         }
946         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
947
948         printf("Testing ChangePasswordUser\n");
949
950         E_md4hash(oldpass, old_nt_hash);
951         E_md4hash(newpass, new_nt_hash);
952         E_deshash(oldpass, old_lm_hash);
953         E_deshash(newpass, new_lm_hash);
954
955         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
956         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
957         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
958         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
959         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
960         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
961
962         r.in.user_handle = &user_handle;
963         r.in.lm_present = 1;
964         r.in.old_lm_crypted = &hash1;
965         r.in.new_lm_crypted = &hash2;
966         r.in.nt_present = 1;
967         r.in.old_nt_crypted = &hash3;
968         r.in.new_nt_crypted = &hash4;
969         r.in.cross1_present = 1;
970         r.in.nt_cross = &hash5;
971         r.in.cross2_present = 1;
972         r.in.lm_cross = &hash6;
973
974         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
975         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
976                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
977         } else  if (!NT_STATUS_IS_OK(status)) {
978                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
979                 ret = False;
980         } else {
981                 *password = newpass;
982         }
983
984         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
985                 ret = False;
986         }
987
988         return ret;
989 }
990
991
992 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
993                                         struct policy_handle *handle, char **password)
994 {
995         NTSTATUS status;
996         struct samr_OemChangePasswordUser2 r;
997         BOOL ret = True;
998         struct samr_Password lm_verifier;
999         struct samr_CryptPassword lm_pass;
1000         struct lsa_AsciiString server, account, account_bad;
1001         char *oldpass = *password;
1002         char *newpass;
1003         uint8_t old_lm_hash[16], new_lm_hash[16];
1004
1005         struct samr_GetDomPwInfo dom_pw_info;
1006         int policy_min_pw_len = 0;
1007
1008         struct lsa_String domain_name;
1009         domain_name.string = "";
1010         dom_pw_info.in.domain_name = &domain_name;
1011
1012         printf("Testing OemChangePasswordUser2\n");
1013
1014         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1015         if (NT_STATUS_IS_OK(status)) {
1016                 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1017         }
1018
1019         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1020
1021         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1022         account.string = TEST_ACCOUNT_NAME;
1023
1024         E_deshash(oldpass, old_lm_hash);
1025         E_deshash(newpass, new_lm_hash);
1026
1027         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1028         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1029         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1030
1031         r.in.server = &server;
1032         r.in.account = &account;
1033         r.in.password = &lm_pass;
1034         r.in.hash = &lm_verifier;
1035
1036         /* Break the verification */
1037         lm_verifier.hash[0]++;
1038
1039         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1040
1041         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1042             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1043                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1044                         nt_errstr(status));
1045                 ret = False;
1046         }
1047
1048         /* This shouldn't be a valid name */
1049         account_bad.string = TEST_ACCOUNT_NAME "XX";
1050         r.in.account = &account_bad;
1051
1052         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1053
1054         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1055                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1056                         nt_errstr(status));
1057                 ret = False;
1058         }
1059
1060         E_deshash(oldpass, old_lm_hash);
1061         E_deshash(newpass, new_lm_hash);
1062
1063         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1064         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1065         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1066
1067         r.in.server = &server;
1068         r.in.account = &account;
1069         r.in.password = &lm_pass;
1070         r.in.hash = &lm_verifier;
1071
1072         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1073         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1074                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1075         } else if (!NT_STATUS_IS_OK(status)) {
1076                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1077                 ret = False;
1078         } else {
1079                 *password = newpass;
1080         }
1081
1082         return ret;
1083 }
1084
1085
1086 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1087                                      struct policy_handle *handle, char **password)
1088 {
1089         NTSTATUS status;
1090         struct samr_ChangePasswordUser2 r;
1091         BOOL ret = True;
1092         struct lsa_String server, account;
1093         struct samr_CryptPassword nt_pass, lm_pass;
1094         struct samr_Password nt_verifier, lm_verifier;
1095         char *oldpass = *password;
1096         char *newpass;
1097         uint8_t old_nt_hash[16], new_nt_hash[16];
1098         uint8_t old_lm_hash[16], new_lm_hash[16];
1099
1100         struct samr_GetDomPwInfo dom_pw_info;
1101         int policy_min_pw_len = 0;
1102
1103         struct lsa_String domain_name;
1104         domain_name.string = "";
1105         dom_pw_info.in.domain_name = &domain_name;
1106
1107         printf("Testing ChangePasswordUser2\n");
1108
1109         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1110         if (NT_STATUS_IS_OK(status)) {
1111                 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1112         }
1113
1114         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1115
1116         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1117         init_lsa_String(&account, TEST_ACCOUNT_NAME);
1118
1119         E_md4hash(oldpass, old_nt_hash);
1120         E_md4hash(newpass, new_nt_hash);
1121
1122         E_deshash(oldpass, old_lm_hash);
1123         E_deshash(newpass, new_lm_hash);
1124
1125         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1126         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1127         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1128
1129         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1130         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1131         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1132
1133         r.in.server = &server;
1134         r.in.account = &account;
1135         r.in.nt_password = &nt_pass;
1136         r.in.nt_verifier = &nt_verifier;
1137         r.in.lm_change = 1;
1138         r.in.lm_password = &lm_pass;
1139         r.in.lm_verifier = &lm_verifier;
1140
1141         status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1142         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1143                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1144         } else if (!NT_STATUS_IS_OK(status)) {
1145                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1146                 ret = False;
1147         } else {
1148                 *password = newpass;
1149         }
1150
1151         return ret;
1152 }
1153
1154
1155 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1156                               const char *account_string,
1157                               int policy_min_pw_len,
1158                               char **password)
1159 {
1160         NTSTATUS status;
1161         struct samr_ChangePasswordUser3 r;
1162         BOOL ret = True;
1163         struct lsa_String server, account, account_bad;
1164         struct samr_CryptPassword nt_pass, lm_pass;
1165         struct samr_Password nt_verifier, lm_verifier;
1166         char *oldpass = *password;
1167         char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);     
1168         uint8_t old_nt_hash[16], new_nt_hash[16];
1169         uint8_t old_lm_hash[16], new_lm_hash[16];
1170
1171         printf("Testing ChangePasswordUser3\n");
1172
1173         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1174         init_lsa_String(&account, account_string);
1175
1176         E_md4hash(oldpass, old_nt_hash);
1177         E_md4hash(newpass, new_nt_hash);
1178
1179         E_deshash(oldpass, old_lm_hash);
1180         E_deshash(newpass, new_lm_hash);
1181
1182         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1183         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1184         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1185
1186         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1187         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1188         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1189         
1190         /* Break the verification */
1191         nt_verifier.hash[0]++;
1192
1193         r.in.server = &server;
1194         r.in.account = &account;
1195         r.in.nt_password = &nt_pass;
1196         r.in.nt_verifier = &nt_verifier;
1197         r.in.lm_change = 1;
1198         r.in.lm_password = &lm_pass;
1199         r.in.lm_verifier = &lm_verifier;
1200         r.in.password3 = NULL;
1201
1202         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1203         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1204             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1205                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1206                         nt_errstr(status));
1207                 ret = False;
1208         }
1209         
1210         /* This shouldn't be a valid name */
1211         init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1212
1213         r.in.account = &account_bad;
1214         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1215         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1216                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1217                         nt_errstr(status));
1218                 ret = False;
1219         }
1220
1221         E_md4hash(oldpass, old_nt_hash);
1222         E_md4hash(newpass, new_nt_hash);
1223
1224         E_deshash(oldpass, old_lm_hash);
1225         E_deshash(newpass, new_lm_hash);
1226
1227         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1228         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1229         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1230
1231         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1232         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1233         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1234
1235         r.in.server = &server;
1236         r.in.account = &account;
1237         r.in.nt_password = &nt_pass;
1238         r.in.nt_verifier = &nt_verifier;
1239         r.in.lm_change = 1;
1240         r.in.lm_password = &lm_pass;
1241         r.in.lm_verifier = &lm_verifier;
1242         r.in.password3 = NULL;
1243
1244         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1245         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) 
1246             && !policy_min_pw_len) {
1247                 if (r.out.dominfo) {
1248                         policy_min_pw_len = r.out.dominfo->min_password_length;
1249                 }
1250                 if (policy_min_pw_len) /* try again with the right min password length */ {
1251                         ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1252                 } else {
1253                         printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1254                         ret = False;
1255                 }
1256         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1257                 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1258         } else if (!NT_STATUS_IS_OK(status)) {
1259                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1260                 ret = False;
1261         } else {
1262                 *password = newpass;
1263         }
1264
1265         return ret;
1266 }
1267
1268
1269 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1270                                   struct policy_handle *alias_handle)
1271 {
1272         struct samr_GetMembersInAlias r;
1273         struct lsa_SidArray sids;
1274         NTSTATUS status;
1275         BOOL     ret = True;
1276
1277         printf("Testing GetMembersInAlias\n");
1278
1279         r.in.alias_handle = alias_handle;
1280         r.out.sids = &sids;
1281
1282         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1283         if (!NT_STATUS_IS_OK(status)) {
1284                 printf("GetMembersInAlias failed - %s\n",
1285                        nt_errstr(status));
1286                 ret = False;
1287         }
1288
1289         return ret;
1290 }
1291
1292 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1293                                   struct policy_handle *alias_handle,
1294                                   const struct dom_sid *domain_sid)
1295 {
1296         struct samr_AddAliasMember r;
1297         struct samr_DeleteAliasMember d;
1298         NTSTATUS status;
1299         BOOL ret = True;
1300         struct dom_sid *sid;
1301
1302         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1303
1304         printf("testing AddAliasMember\n");
1305         r.in.alias_handle = alias_handle;
1306         r.in.sid = sid;
1307
1308         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1309         if (!NT_STATUS_IS_OK(status)) {
1310                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1311                 ret = False;
1312         }
1313
1314         d.in.alias_handle = alias_handle;
1315         d.in.sid = sid;
1316
1317         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1318         if (!NT_STATUS_IS_OK(status)) {
1319                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1320                 ret = False;
1321         }
1322
1323         return ret;
1324 }
1325
1326 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1327                                            struct policy_handle *alias_handle)
1328 {
1329         struct samr_AddMultipleMembersToAlias a;
1330         struct samr_RemoveMultipleMembersFromAlias r;
1331         NTSTATUS status;
1332         BOOL ret = True;
1333         struct lsa_SidArray sids;
1334
1335         printf("testing AddMultipleMembersToAlias\n");
1336         a.in.alias_handle = alias_handle;
1337         a.in.sids = &sids;
1338
1339         sids.num_sids = 3;
1340         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1341
1342         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1343         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1344         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1345
1346         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1347         if (!NT_STATUS_IS_OK(status)) {
1348                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1349                 ret = False;
1350         }
1351
1352
1353         printf("testing RemoveMultipleMembersFromAlias\n");
1354         r.in.alias_handle = alias_handle;
1355         r.in.sids = &sids;
1356
1357         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1358         if (!NT_STATUS_IS_OK(status)) {
1359                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1360                 ret = False;
1361         }
1362
1363         /* strange! removing twice doesn't give any error */
1364         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1365         if (!NT_STATUS_IS_OK(status)) {
1366                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1367                 ret = False;
1368         }
1369
1370         /* but removing an alias that isn't there does */
1371         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1372
1373         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1374         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1375                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1376                 ret = False;
1377         }
1378
1379         return ret;
1380 }
1381
1382 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1383                                             struct policy_handle *user_handle)
1384 {
1385         struct samr_TestPrivateFunctionsUser r;
1386         NTSTATUS status;
1387         BOOL ret = True;
1388
1389         printf("Testing TestPrivateFunctionsUser\n");
1390
1391         r.in.user_handle = user_handle;
1392
1393         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1394         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1395                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1396                 ret = False;
1397         }
1398
1399         return ret;
1400 }
1401
1402
1403 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1404                           struct policy_handle *handle, uint32_t base_acct_flags, 
1405                           const char *base_acct_name)
1406 {
1407         BOOL ret = True;
1408
1409         if (!test_QuerySecurity(p, mem_ctx, handle)) {
1410                 ret = False;
1411         }
1412
1413         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1414                 ret = False;
1415         }
1416
1417         if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1418                 ret = False;
1419         }
1420
1421         if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1422                               base_acct_name)) {
1423                 ret = False;
1424         }       
1425
1426         if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1427                 ret = False;
1428         }
1429
1430         if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1431                 ret = False;
1432         }
1433
1434         return ret;
1435 }
1436
1437 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1438                            struct policy_handle *alias_handle,
1439                            const struct dom_sid *domain_sid)
1440 {
1441         BOOL ret = True;
1442
1443         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1444                 ret = False;
1445         }
1446
1447         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1448                 ret = False;
1449         }
1450
1451         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1452                 ret = False;
1453         }
1454
1455         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1456                 ret = False;
1457         }
1458
1459         if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1460                 ret = False;
1461         }
1462
1463         return ret;
1464 }
1465
1466
1467 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1468                             struct policy_handle *handle, const char *name)
1469 {
1470         NTSTATUS status;
1471         struct samr_DeleteUser d;
1472         struct policy_handle user_handle;
1473         uint32_t rid;
1474
1475         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1476         if (!NT_STATUS_IS_OK(status)) {
1477                 goto failed;
1478         }
1479
1480         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1481         if (!NT_STATUS_IS_OK(status)) {
1482                 goto failed;
1483         }
1484
1485         d.in.user_handle = &user_handle;
1486         d.out.user_handle = &user_handle;
1487         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1488         if (!NT_STATUS_IS_OK(status)) {
1489                 goto failed;
1490         }
1491
1492         return True;
1493
1494 failed:
1495         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1496         return False;
1497 }
1498
1499
1500 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1501                                     struct policy_handle *handle, const char *name)
1502 {
1503         NTSTATUS status;
1504         struct samr_OpenGroup r;
1505         struct samr_DeleteDomainGroup d;
1506         struct policy_handle group_handle;
1507         uint32_t rid;
1508
1509         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1510         if (!NT_STATUS_IS_OK(status)) {
1511                 goto failed;
1512         }
1513
1514         r.in.domain_handle = handle;
1515         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1516         r.in.rid = rid;
1517         r.out.group_handle = &group_handle;
1518         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1519         if (!NT_STATUS_IS_OK(status)) {
1520                 goto failed;
1521         }
1522
1523         d.in.group_handle = &group_handle;
1524         d.out.group_handle = &group_handle;
1525         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1526         if (!NT_STATUS_IS_OK(status)) {
1527                 goto failed;
1528         }
1529
1530         return True;
1531
1532 failed:
1533         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1534         return False;
1535 }
1536
1537
1538 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1539                                    struct policy_handle *domain_handle, const char *name)
1540 {
1541         NTSTATUS status;
1542         struct samr_OpenAlias r;
1543         struct samr_DeleteDomAlias d;
1544         struct policy_handle alias_handle;
1545         uint32_t rid;
1546
1547         printf("testing DeleteAlias_byname\n");
1548
1549         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1550         if (!NT_STATUS_IS_OK(status)) {
1551                 goto failed;
1552         }
1553
1554         r.in.domain_handle = domain_handle;
1555         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1556         r.in.rid = rid;
1557         r.out.alias_handle = &alias_handle;
1558         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1559         if (!NT_STATUS_IS_OK(status)) {
1560                 goto failed;
1561         }
1562
1563         d.in.alias_handle = &alias_handle;
1564         d.out.alias_handle = &alias_handle;
1565         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1566         if (!NT_STATUS_IS_OK(status)) {
1567                 goto failed;
1568         }
1569
1570         return True;
1571
1572 failed:
1573         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1574         return False;
1575 }
1576
1577 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1578                                      struct policy_handle *alias_handle)
1579 {
1580         struct samr_DeleteDomAlias d;
1581         NTSTATUS status;
1582         BOOL ret = True;
1583         printf("Testing DeleteAlias\n");
1584
1585         d.in.alias_handle = alias_handle;
1586         d.out.alias_handle = alias_handle;
1587
1588         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1589         if (!NT_STATUS_IS_OK(status)) {
1590                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1591                 ret = False;
1592         }
1593
1594         return ret;
1595 }
1596
1597 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1598                             struct policy_handle *domain_handle, 
1599                              struct policy_handle *alias_handle, 
1600                              const struct dom_sid *domain_sid)
1601 {
1602         NTSTATUS status;
1603         struct samr_CreateDomAlias r;
1604         struct lsa_String name;
1605         uint32_t rid;
1606         BOOL ret = True;
1607
1608         init_lsa_String(&name, TEST_ALIASNAME);
1609         r.in.domain_handle = domain_handle;
1610         r.in.alias_name = &name;
1611         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1612         r.out.alias_handle = alias_handle;
1613         r.out.rid = &rid;
1614
1615         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1616
1617         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1618
1619         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1620                 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1621                 return True;
1622         }
1623
1624         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1625                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1626                         return False;
1627                 }
1628                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1629         }
1630
1631         if (!NT_STATUS_IS_OK(status)) {
1632                 printf("CreateAlias failed - %s\n", nt_errstr(status));
1633                 return False;
1634         }
1635
1636         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1637                 ret = False;
1638         }
1639
1640         return ret;
1641 }
1642
1643 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1644                                 struct policy_handle *domain_handle, char **password)
1645 {
1646         BOOL ret = True;
1647
1648         if (!*password) {
1649                 return False;
1650         }
1651
1652         if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1653                 ret = False;
1654         }
1655
1656         if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1657                 ret = False;
1658         }
1659
1660         if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1661                 ret = False;
1662         }
1663
1664         /* we change passwords twice - this has the effect of verifying
1665            they were changed correctly for the final call */
1666         if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1667                 ret = False;
1668         }
1669
1670         if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1671                 ret = False;
1672         }
1673
1674         return ret;
1675 }
1676
1677 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1678                             struct policy_handle *domain_handle, struct policy_handle *user_handle)
1679 {
1680         NTSTATUS status;
1681         struct samr_CreateUser r;
1682         struct samr_QueryUserInfo q;
1683         uint32_t rid;
1684         char *password = NULL;
1685
1686         int i;
1687         const uint32_t password_fields[] = {
1688                 SAMR_FIELD_PASSWORD,
1689                 SAMR_FIELD_PASSWORD2,
1690                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1691                 0
1692         };
1693         
1694         TALLOC_CTX *user_ctx;
1695
1696         /* This call creates a 'normal' account - check that it really does */
1697         const uint32_t acct_flags = ACB_NORMAL;
1698         struct lsa_String name;
1699         BOOL ret = True;
1700
1701         user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1702         init_lsa_String(&name, TEST_ACCOUNT_NAME);
1703
1704         r.in.domain_handle = domain_handle;
1705         r.in.account_name = &name;
1706         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1707         r.out.user_handle = user_handle;
1708         r.out.rid = &rid;
1709
1710         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1711
1712         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1713
1714         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1715                 printf("Server refused create of '%s'\n", r.in.account_name->string);
1716                 ZERO_STRUCTP(user_handle);
1717                 talloc_free(user_ctx);
1718                 return True;
1719         }
1720
1721         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1722                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1723                         talloc_free(user_ctx);
1724                         return False;
1725                 }
1726                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1727         }
1728         if (!NT_STATUS_IS_OK(status)) {
1729                 talloc_free(user_ctx);
1730                 printf("CreateUser failed - %s\n", nt_errstr(status));
1731                 return False;
1732         }
1733
1734         q.in.user_handle = user_handle;
1735         q.in.level = 16;
1736
1737         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1738         if (!NT_STATUS_IS_OK(status)) {
1739                 printf("QueryUserInfo level %u failed - %s\n", 
1740                        q.in.level, nt_errstr(status));
1741                 ret = False;
1742         } else {
1743                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1744                         printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1745                                q.out.info->info16.acct_flags, q.out.info->info16.acct_flags, 
1746                                acct_flags, acct_flags);
1747                         ret = False;
1748                 }
1749         }
1750
1751         if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1752                 ret = False;
1753         }
1754
1755         if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1756                 ret = False;
1757         }       
1758
1759         for (i = 0; password_fields[i]; i++) {
1760                 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1761                         ret = False;
1762                 }       
1763                 
1764                 /* check it was set right */
1765                 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1766                         ret = False;
1767                 }
1768         }               
1769
1770         for (i = 0; password_fields[i]; i++) {
1771                 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1772                         ret = False;
1773                 }       
1774                 
1775                 /* check it was set right */
1776                 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1777                         ret = False;
1778                 }
1779         }               
1780
1781         if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1782                 ret = False;
1783         }       
1784
1785         if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1786                 ret = False;
1787         }       
1788
1789         talloc_free(user_ctx);
1790         
1791         return ret;
1792 }
1793
1794
1795 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1796                             struct policy_handle *user_handle)
1797 {
1798         struct samr_DeleteUser d;
1799         NTSTATUS status;
1800         BOOL ret = True;
1801
1802         printf("Testing DeleteUser\n");
1803
1804         d.in.user_handle = user_handle;
1805         d.out.user_handle = user_handle;
1806
1807         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1808         if (!NT_STATUS_IS_OK(status)) {
1809                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1810                 ret = False;
1811         }
1812
1813         return ret;
1814 }
1815
1816 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1817                              struct policy_handle *handle)
1818 {
1819         NTSTATUS status;
1820         struct samr_CreateUser2 r;
1821         struct samr_QueryUserInfo q;
1822         struct samr_DeleteUser d;
1823         struct policy_handle user_handle;
1824         uint32_t rid;
1825         struct lsa_String name;
1826         BOOL ret = True;
1827         int i;
1828
1829         struct {
1830                 uint32_t acct_flags;
1831                 const char *account_name;
1832                 NTSTATUS nt_status;
1833         } account_types[] = {
1834                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1835                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1836                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1837                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1838                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1839                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1840                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1841                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1842                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1843                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1844                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1845                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1846                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1847                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1848                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1849         };
1850
1851         for (i = 0; account_types[i].account_name; i++) {
1852                 TALLOC_CTX *user_ctx;
1853                 uint32_t acct_flags = account_types[i].acct_flags;
1854                 uint32_t access_granted;
1855                 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1856                 init_lsa_String(&name, account_types[i].account_name);
1857
1858                 r.in.domain_handle = handle;
1859                 r.in.account_name = &name;
1860                 r.in.acct_flags = acct_flags;
1861                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1862                 r.out.user_handle = &user_handle;
1863                 r.out.access_granted = &access_granted;
1864                 r.out.rid = &rid;
1865                 
1866                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1867                 
1868                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1869                 
1870                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1871                         talloc_free(user_ctx);
1872                         printf("Server refused create of '%s'\n", r.in.account_name->string);
1873                         continue;
1874
1875                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1876                         if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1877                                 talloc_free(user_ctx);
1878                                 ret = False;
1879                                 continue;
1880                         }
1881                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1882
1883                 }
1884                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1885                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
1886                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
1887                         ret = False;
1888                 }
1889                 
1890                 if (NT_STATUS_IS_OK(status)) {
1891                         q.in.user_handle = &user_handle;
1892                         q.in.level = 16;
1893                         
1894                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1895                         if (!NT_STATUS_IS_OK(status)) {
1896                                 printf("QueryUserInfo level %u failed - %s\n", 
1897                                        q.in.level, nt_errstr(status));
1898                                 ret = False;
1899                         } else {
1900                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1901                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1902                                                q.out.info->info16.acct_flags, 
1903                                                acct_flags);
1904                                         ret = False;
1905                                 }
1906                         }
1907                 
1908                         if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1909                                 ret = False;
1910                         }
1911
1912                         printf("Testing DeleteUser (createuser2 test)\n");
1913                 
1914                         d.in.user_handle = &user_handle;
1915                         d.out.user_handle = &user_handle;
1916                         
1917                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1918                         if (!NT_STATUS_IS_OK(status)) {
1919                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1920                                 ret = False;
1921                         }
1922                 }
1923                 talloc_free(user_ctx);
1924         }
1925
1926         return ret;
1927 }
1928
1929 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1930                                 struct policy_handle *handle)
1931 {
1932         NTSTATUS status;
1933         struct samr_QueryAliasInfo r;
1934         uint16_t levels[] = {1, 2, 3};
1935         int i;
1936         BOOL ret = True;
1937
1938         for (i=0;i<ARRAY_SIZE(levels);i++) {
1939                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1940
1941                 r.in.alias_handle = handle;
1942                 r.in.level = levels[i];
1943
1944                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1945                 if (!NT_STATUS_IS_OK(status)) {
1946                         printf("QueryAliasInfo level %u failed - %s\n", 
1947                                levels[i], nt_errstr(status));
1948                         ret = False;
1949                 }
1950         }
1951
1952         return ret;
1953 }
1954
1955 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1956                                 struct policy_handle *handle)
1957 {
1958         NTSTATUS status;
1959         struct samr_QueryGroupInfo r;
1960         uint16_t levels[] = {1, 2, 3, 4, 5};
1961         int i;
1962         BOOL ret = True;
1963
1964         for (i=0;i<ARRAY_SIZE(levels);i++) {
1965                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1966
1967                 r.in.group_handle = handle;
1968                 r.in.level = levels[i];
1969
1970                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1971                 if (!NT_STATUS_IS_OK(status)) {
1972                         printf("QueryGroupInfo level %u failed - %s\n", 
1973                                levels[i], nt_errstr(status));
1974                         ret = False;
1975                 }
1976         }
1977
1978         return ret;
1979 }
1980
1981 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1982                                   struct policy_handle *handle)
1983 {
1984         NTSTATUS status;
1985         struct samr_QueryGroupMember r;
1986         BOOL ret = True;
1987
1988         printf("Testing QueryGroupMember\n");
1989
1990         r.in.group_handle = handle;
1991
1992         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1993         if (!NT_STATUS_IS_OK(status)) {
1994                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1995                 ret = False;
1996         }
1997
1998         return ret;
1999 }
2000
2001
2002 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2003                               struct policy_handle *handle)
2004 {
2005         NTSTATUS status;
2006         struct samr_QueryGroupInfo r;
2007         struct samr_SetGroupInfo s;
2008         uint16_t levels[] = {1, 2, 3, 4};
2009         uint16_t set_ok[] = {0, 1, 1, 1};
2010         int i;
2011         BOOL ret = True;
2012
2013         for (i=0;i<ARRAY_SIZE(levels);i++) {
2014                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2015
2016                 r.in.group_handle = handle;
2017                 r.in.level = levels[i];
2018
2019                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2020                 if (!NT_STATUS_IS_OK(status)) {
2021                         printf("QueryGroupInfo level %u failed - %s\n", 
2022                                levels[i], nt_errstr(status));
2023                         ret = False;
2024                 }
2025
2026                 printf("Testing SetGroupInfo level %u\n", levels[i]);
2027
2028                 s.in.group_handle = handle;
2029                 s.in.level = levels[i];
2030                 s.in.info = r.out.info;
2031
2032 #if 0
2033                 /* disabled this, as it changes the name only from the point of view of samr, 
2034                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
2035                    the name is still reserved, so creating the old name fails, but deleting by the old name
2036                    also fails */
2037                 if (s.in.level == 2) {
2038                         init_lsa_String(&s.in.info->string, "NewName");
2039                 }
2040 #endif
2041
2042                 if (s.in.level == 4) {
2043                         init_lsa_String(&s.in.info->description, "test description");
2044                 }
2045
2046                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2047                 if (set_ok[i]) {
2048                         if (!NT_STATUS_IS_OK(status)) {
2049                                 printf("SetGroupInfo level %u failed - %s\n", 
2050                                        r.in.level, nt_errstr(status));
2051                                 ret = False;
2052                                 continue;
2053                         }
2054                 } else {
2055                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2056                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2057                                        r.in.level, nt_errstr(status));
2058                                 ret = False;
2059                                 continue;
2060                         }
2061                 }
2062         }
2063
2064         return ret;
2065 }
2066
2067 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2068                                struct policy_handle *handle)
2069 {
2070         NTSTATUS status;
2071         struct samr_QueryUserInfo r;
2072         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2073                            11, 12, 13, 14, 16, 17, 20, 21};
2074         int i;
2075         BOOL ret = True;
2076
2077         for (i=0;i<ARRAY_SIZE(levels);i++) {
2078                 printf("Testing QueryUserInfo level %u\n", levels[i]);
2079
2080                 r.in.user_handle = handle;
2081                 r.in.level = levels[i];
2082
2083                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2084                 if (!NT_STATUS_IS_OK(status)) {
2085                         printf("QueryUserInfo level %u failed - %s\n", 
2086                                levels[i], nt_errstr(status));
2087                         ret = False;
2088                 }
2089         }
2090
2091         return ret;
2092 }
2093
2094 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2095                                 struct policy_handle *handle)
2096 {
2097         NTSTATUS status;
2098         struct samr_QueryUserInfo2 r;
2099         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2100                            11, 12, 13, 14, 16, 17, 20, 21};
2101         int i;
2102         BOOL ret = True;
2103
2104         for (i=0;i<ARRAY_SIZE(levels);i++) {
2105                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2106
2107                 r.in.user_handle = handle;
2108                 r.in.level = levels[i];
2109
2110                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2111                 if (!NT_STATUS_IS_OK(status)) {
2112                         printf("QueryUserInfo2 level %u failed - %s\n", 
2113                                levels[i], nt_errstr(status));
2114                         ret = False;
2115                 }
2116         }
2117
2118         return ret;
2119 }
2120
2121 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2122                           struct policy_handle *handle, uint32_t rid)
2123 {
2124         NTSTATUS status;
2125         struct samr_OpenUser r;
2126         struct policy_handle user_handle;
2127         BOOL ret = True;
2128
2129         printf("Testing OpenUser(%u)\n", rid);
2130
2131         r.in.domain_handle = handle;
2132         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2133         r.in.rid = rid;
2134         r.out.user_handle = &user_handle;
2135
2136         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2137         if (!NT_STATUS_IS_OK(status)) {
2138                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2139                 return False;
2140         }
2141
2142         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2143                 ret = False;
2144         }
2145
2146         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2147                 ret = False;
2148         }
2149
2150         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2151                 ret = False;
2152         }
2153
2154         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2155                 ret = False;
2156         }
2157
2158         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2159                 ret = False;
2160         }
2161
2162         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2163                 ret = False;
2164         }
2165
2166         return ret;
2167 }
2168
2169 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2170                            struct policy_handle *handle, uint32_t rid)
2171 {
2172         NTSTATUS status;
2173         struct samr_OpenGroup r;
2174         struct policy_handle group_handle;
2175         BOOL ret = True;
2176
2177         printf("Testing OpenGroup(%u)\n", rid);
2178
2179         r.in.domain_handle = handle;
2180         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2181         r.in.rid = rid;
2182         r.out.group_handle = &group_handle;
2183
2184         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2185         if (!NT_STATUS_IS_OK(status)) {
2186                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2187                 return False;
2188         }
2189
2190         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2191                 ret = False;
2192         }
2193
2194         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2195                 ret = False;
2196         }
2197
2198         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2199                 ret = False;
2200         }
2201
2202         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2203                 ret = False;
2204         }
2205
2206         return ret;
2207 }
2208
2209 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2210                            struct policy_handle *handle, uint32_t rid)
2211 {
2212         NTSTATUS status;
2213         struct samr_OpenAlias r;
2214         struct policy_handle alias_handle;
2215         BOOL ret = True;
2216
2217         printf("Testing OpenAlias(%u)\n", rid);
2218
2219         r.in.domain_handle = handle;
2220         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2221         r.in.rid = rid;
2222         r.out.alias_handle = &alias_handle;
2223
2224         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2225         if (!NT_STATUS_IS_OK(status)) {
2226                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2227                 return False;
2228         }
2229
2230         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2231                 ret = False;
2232         }
2233
2234         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2235                 ret = False;
2236         }
2237
2238         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2239                 ret = False;
2240         }
2241
2242         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2243                 ret = False;
2244         }
2245
2246         return ret;
2247 }
2248
2249 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2250                                  struct policy_handle *handle)
2251 {
2252         NTSTATUS status;
2253         struct samr_EnumDomainUsers r;
2254         uint32_t resume_handle=0;
2255         int i;
2256         BOOL ret = True;
2257         struct samr_LookupNames n;
2258         struct samr_LookupRids  lr ;
2259
2260         printf("Testing EnumDomainUsers\n");
2261
2262         r.in.domain_handle = handle;
2263         r.in.resume_handle = &resume_handle;
2264         r.in.acct_flags = 0;
2265         r.in.max_size = (uint32_t)-1;
2266         r.out.resume_handle = &resume_handle;
2267
2268         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2269         if (!NT_STATUS_IS_OK(status)) {
2270                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2271                 return False;
2272         }
2273         
2274         if (!r.out.sam) {
2275                 return False;
2276         }
2277
2278         if (r.out.sam->count == 0) {
2279                 return True;
2280         }
2281
2282         for (i=0;i<r.out.sam->count;i++) {
2283                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2284                         ret = False;
2285                 }
2286         }
2287
2288         printf("Testing LookupNames\n");
2289         n.in.domain_handle = handle;
2290         n.in.num_names = r.out.sam->count;
2291         n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2292         for (i=0;i<r.out.sam->count;i++) {
2293                 n.in.names[i].string = r.out.sam->entries[i].name.string;
2294         }
2295         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2296         if (!NT_STATUS_IS_OK(status)) {
2297                 printf("LookupNames failed - %s\n", nt_errstr(status));
2298                 ret = False;
2299         }
2300
2301
2302         printf("Testing LookupRids\n");
2303         lr.in.domain_handle = handle;
2304         lr.in.num_rids = r.out.sam->count;
2305         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2306         for (i=0;i<r.out.sam->count;i++) {
2307                 lr.in.rids[i] = r.out.sam->entries[i].idx;
2308         }
2309         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2310         if (!NT_STATUS_IS_OK(status)) {
2311                 printf("LookupRids failed - %s\n", nt_errstr(status));
2312                 ret = False;
2313         }
2314
2315         return ret;     
2316 }
2317
2318 /*
2319   try blasting the server with a bunch of sync requests
2320 */
2321 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2322                                        struct policy_handle *handle)
2323 {
2324         NTSTATUS status;
2325         struct samr_EnumDomainUsers r;
2326         uint32_t resume_handle=0;
2327         int i;
2328 #define ASYNC_COUNT 100
2329         struct rpc_request *req[ASYNC_COUNT];
2330
2331         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2332                 printf("samr async test disabled - enable dangerous tests to use\n");
2333                 return True;
2334         }
2335
2336         printf("Testing EnumDomainUsers_async\n");
2337
2338         r.in.domain_handle = handle;
2339         r.in.resume_handle = &resume_handle;
2340         r.in.acct_flags = 0;
2341         r.in.max_size = (uint32_t)-1;
2342         r.out.resume_handle = &resume_handle;
2343
2344         for (i=0;i<ASYNC_COUNT;i++) {
2345                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2346         }
2347
2348         for (i=0;i<ASYNC_COUNT;i++) {
2349                 status = dcerpc_ndr_request_recv(req[i]);
2350                 if (!NT_STATUS_IS_OK(status)) {
2351                         printf("EnumDomainUsers[%d] failed - %s\n", 
2352                                i, nt_errstr(status));
2353                         return False;
2354                 }
2355         }
2356         
2357         printf("%d async requests OK\n", i);
2358
2359         return True;
2360 }
2361
2362 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2363                                   struct policy_handle *handle)
2364 {
2365         NTSTATUS status;
2366         struct samr_EnumDomainGroups r;
2367         uint32_t resume_handle=0;
2368         int i;
2369         BOOL ret = True;
2370
2371         printf("Testing EnumDomainGroups\n");
2372
2373         r.in.domain_handle = handle;
2374         r.in.resume_handle = &resume_handle;
2375         r.in.max_size = (uint32_t)-1;
2376         r.out.resume_handle = &resume_handle;
2377
2378         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2379         if (!NT_STATUS_IS_OK(status)) {
2380                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2381                 return False;
2382         }
2383         
2384         if (!r.out.sam) {
2385                 return False;
2386         }
2387
2388         for (i=0;i<r.out.sam->count;i++) {
2389                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2390                         ret = False;
2391                 }
2392         }
2393
2394         return ret;
2395 }
2396
2397 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2398                                    struct policy_handle *handle)
2399 {
2400         NTSTATUS status;
2401         struct samr_EnumDomainAliases r;
2402         uint32_t resume_handle=0;
2403         int i;
2404         BOOL ret = True;
2405
2406         printf("Testing EnumDomainAliases\n");
2407
2408         r.in.domain_handle = handle;
2409         r.in.resume_handle = &resume_handle;
2410         r.in.acct_flags = (uint32_t)-1;
2411         r.out.resume_handle = &resume_handle;
2412
2413         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2414         if (!NT_STATUS_IS_OK(status)) {
2415                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2416                 return False;
2417         }
2418         
2419         if (!r.out.sam) {
2420                 return False;
2421         }
2422
2423         for (i=0;i<r.out.sam->count;i++) {
2424                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2425                         ret = False;
2426                 }
2427         }
2428
2429         return ret;     
2430 }
2431
2432 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2433                                             struct policy_handle *handle)
2434 {
2435         NTSTATUS status;
2436         struct samr_GetDisplayEnumerationIndex r;
2437         BOOL ret = True;
2438         uint16_t levels[] = {1, 2, 3, 4, 5};
2439         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2440         int i;
2441
2442         for (i=0;i<ARRAY_SIZE(levels);i++) {
2443                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2444
2445                 r.in.domain_handle = handle;
2446                 r.in.level = levels[i];
2447                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2448
2449                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2450
2451                 if (ok_lvl[i] && 
2452                     !NT_STATUS_IS_OK(status) &&
2453                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2454                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2455                                levels[i], nt_errstr(status));
2456                         ret = False;
2457                 }
2458
2459                 init_lsa_String(&r.in.name, "zzzzzzzz");
2460
2461                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2462                 
2463                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2464                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2465                                levels[i], nt_errstr(status));
2466                         ret = False;
2467                 }
2468         }
2469         
2470         return ret;     
2471 }
2472
2473 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2474                                              struct policy_handle *handle)
2475 {
2476         NTSTATUS status;
2477         struct samr_GetDisplayEnumerationIndex2 r;
2478         BOOL ret = True;
2479         uint16_t levels[] = {1, 2, 3, 4, 5};
2480         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2481         int i;
2482
2483         for (i=0;i<ARRAY_SIZE(levels);i++) {
2484                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2485
2486                 r.in.domain_handle = handle;
2487                 r.in.level = levels[i];
2488                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2489
2490                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2491                 if (ok_lvl[i] && 
2492                     !NT_STATUS_IS_OK(status) && 
2493                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2494                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2495                                levels[i], nt_errstr(status));
2496                         ret = False;
2497                 }
2498
2499                 init_lsa_String(&r.in.name, "zzzzzzzz");
2500
2501                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2502                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2503                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2504                                levels[i], nt_errstr(status));
2505                         ret = False;
2506                 }
2507         }
2508         
2509         return ret;     
2510 }
2511
2512 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2513                                   struct policy_handle *handle)
2514 {
2515         NTSTATUS status;
2516         struct samr_QueryDisplayInfo r;
2517         BOOL ret = True;
2518         uint16_t levels[] = {1, 2, 3, 4, 5};
2519         int i;
2520
2521         for (i=0;i<ARRAY_SIZE(levels);i++) {
2522                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2523
2524                 r.in.domain_handle = handle;
2525                 r.in.level = levels[i];
2526                 r.in.start_idx = 0;
2527                 r.in.max_entries = 1000;
2528                 r.in.buf_size = (uint32_t)-1;
2529
2530                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2531                 if (!NT_STATUS_IS_OK(status)) {
2532                         printf("QueryDisplayInfo level %u failed - %s\n", 
2533                                levels[i], nt_errstr(status));
2534                         ret = False;
2535                 }
2536         }
2537         
2538         return ret;     
2539 }
2540
2541 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2542                                   struct policy_handle *handle)
2543 {
2544         NTSTATUS status;
2545         struct samr_QueryDisplayInfo2 r;
2546         BOOL ret = True;
2547         uint16_t levels[] = {1, 2, 3, 4, 5};
2548         int i;
2549
2550         for (i=0;i<ARRAY_SIZE(levels);i++) {
2551                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2552
2553                 r.in.domain_handle = handle;
2554                 r.in.level = levels[i];
2555                 r.in.start_idx = 0;
2556                 r.in.max_entries = 1000;
2557                 r.in.buf_size = (uint32_t)-1;
2558
2559                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2560                 if (!NT_STATUS_IS_OK(status)) {
2561                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
2562                                levels[i], nt_errstr(status));
2563                         ret = False;
2564                 }
2565         }
2566         
2567         return ret;     
2568 }
2569
2570 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2571                                   struct policy_handle *handle)
2572 {
2573         NTSTATUS status;
2574         struct samr_QueryDisplayInfo3 r;
2575         BOOL ret = True;
2576         uint16_t levels[] = {1, 2, 3, 4, 5};
2577         int i;
2578
2579         for (i=0;i<ARRAY_SIZE(levels);i++) {
2580                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2581
2582                 r.in.domain_handle = handle;
2583                 r.in.level = levels[i];
2584                 r.in.start_idx = 0;
2585                 r.in.max_entries = 1000;
2586                 r.in.buf_size = (uint32_t)-1;
2587
2588                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2589                 if (!NT_STATUS_IS_OK(status)) {
2590                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
2591                                levels[i], nt_errstr(status));
2592                         ret = False;
2593                 }
2594         }
2595         
2596         return ret;     
2597 }
2598
2599
2600 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2601                                            struct policy_handle *handle)
2602 {
2603         NTSTATUS status;
2604         struct samr_QueryDisplayInfo r;
2605         BOOL ret = True;
2606
2607         printf("Testing QueryDisplayInfo continuation\n");
2608
2609         r.in.domain_handle = handle;
2610         r.in.level = 1;
2611         r.in.start_idx = 0;
2612         r.in.max_entries = 1;
2613         r.in.buf_size = (uint32_t)-1;
2614
2615         do {
2616                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2617                 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2618                         if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2619                                 printf("expected idx %d but got %d\n",
2620                                        r.in.start_idx + 1,
2621                                        r.out.info.info1.entries[0].idx);
2622                                 break;
2623                         }
2624                 }
2625                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2626                     !NT_STATUS_IS_OK(status)) {
2627                         printf("QueryDisplayInfo level %u failed - %s\n", 
2628                                r.in.level, nt_errstr(status));
2629                         ret = False;
2630                         break;
2631                 }
2632                 r.in.start_idx++;
2633         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2634                   NT_STATUS_IS_OK(status)) &&
2635                  r.out.returned_size != 0);
2636         
2637         return ret;     
2638 }
2639
2640 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2641                                  struct policy_handle *handle)
2642 {
2643         NTSTATUS status;
2644         struct samr_QueryDomainInfo r;
2645         struct samr_SetDomainInfo s;
2646         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2647         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
2648         int i;
2649         BOOL ret = True;
2650
2651         for (i=0;i<ARRAY_SIZE(levels);i++) {
2652                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2653
2654                 r.in.domain_handle = handle;
2655                 r.in.level = levels[i];
2656
2657                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2658                 if (!NT_STATUS_IS_OK(status)) {
2659                         printf("QueryDomainInfo level %u failed - %s\n", 
2660                                r.in.level, nt_errstr(status));
2661                         ret = False;
2662                         continue;
2663                 }
2664
2665                 printf("Testing SetDomainInfo level %u\n", levels[i]);
2666
2667                 s.in.domain_handle = handle;
2668                 s.in.level = levels[i];
2669                 s.in.info = r.out.info;
2670
2671                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2672                 if (set_ok[i]) {
2673                         if (!NT_STATUS_IS_OK(status)) {
2674                                 printf("SetDomainInfo level %u failed - %s\n", 
2675                                        r.in.level, nt_errstr(status));
2676                                 ret = False;
2677                                 continue;
2678                         }
2679                 } else {
2680                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2681                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2682                                        r.in.level, nt_errstr(status));
2683                                 ret = False;
2684                                 continue;
2685                         }
2686                 }
2687
2688                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2689                 if (!NT_STATUS_IS_OK(status)) {
2690                         printf("QueryDomainInfo level %u failed - %s\n", 
2691                                r.in.level, nt_errstr(status));
2692                         ret = False;
2693                         continue;
2694                 }
2695         }
2696
2697         return True;    
2698 }
2699
2700
2701 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2702                                   struct policy_handle *handle)
2703 {
2704         NTSTATUS status;
2705         struct samr_QueryDomainInfo2 r;
2706         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2707         int i;
2708         BOOL ret = True;
2709
2710         for (i=0;i<ARRAY_SIZE(levels);i++) {
2711                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2712
2713                 r.in.domain_handle = handle;
2714                 r.in.level = levels[i];
2715
2716                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2717                 if (!NT_STATUS_IS_OK(status)) {
2718                         printf("QueryDomainInfo2 level %u failed - %s\n", 
2719                                r.in.level, nt_errstr(status));
2720                         ret = False;
2721                         continue;
2722                 }
2723         }
2724
2725         return True;    
2726 }
2727
2728 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2729    set of group names. */
2730 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2731                            struct policy_handle *handle)
2732 {
2733         struct samr_EnumDomainGroups q1;
2734         struct samr_QueryDisplayInfo q2;
2735         NTSTATUS status;
2736         uint32_t resume_handle=0;
2737         int i;
2738         BOOL ret = True;
2739
2740         int num_names = 0;
2741         const char **names = NULL;
2742
2743         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2744
2745         q1.in.domain_handle = handle;
2746         q1.in.resume_handle = &resume_handle;
2747         q1.in.max_size = 5;
2748         q1.out.resume_handle = &resume_handle;
2749
2750         status = STATUS_MORE_ENTRIES;
2751         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2752                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2753
2754                 if (!NT_STATUS_IS_OK(status) &&
2755                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2756                         break;
2757
2758                 for (i=0; i<q1.out.num_entries; i++) {
2759                         add_string_to_array(mem_ctx,
2760                                             q1.out.sam->entries[i].name.string,
2761                                             &names, &num_names);
2762                 }
2763         }
2764
2765         if (!NT_STATUS_IS_OK(status)) {
2766                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2767                 return False;
2768         }
2769         
2770         if (!q1.out.sam) {
2771                 return False;
2772         }
2773
2774         q2.in.domain_handle = handle;
2775         q2.in.level = 5;
2776         q2.in.start_idx = 0;
2777         q2.in.max_entries = 5;
2778         q2.in.buf_size = (uint32_t)-1;
2779
2780         status = STATUS_MORE_ENTRIES;
2781         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2782                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2783
2784                 if (!NT_STATUS_IS_OK(status) &&
2785                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2786                         break;
2787
2788                 for (i=0; i<q2.out.info.info5.count; i++) {
2789                         int j;
2790                         const char *name = q2.out.info.info5.entries[i].account_name.string;
2791                         BOOL found = False;
2792                         for (j=0; j<num_names; j++) {
2793                                 if (names[j] == NULL)
2794                                         continue;
2795                                 /* Hmm. No strequal in samba4 */
2796                                 if (strequal(names[j], name)) {
2797                                         names[j] = NULL;
2798                                         found = True;
2799                                         break;
2800                                 }
2801                         }
2802
2803                         if (!found) {
2804                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2805                                        name);
2806                                 ret = False;
2807                         }
2808                 }
2809                 q2.in.start_idx += q2.out.info.info5.count;
2810         }
2811
2812         if (!NT_STATUS_IS_OK(status)) {
2813                 printf("QueryDisplayInfo level 5 failed - %s\n",
2814                        nt_errstr(status));
2815                 ret = False;
2816         }
2817
2818         for (i=0; i<num_names; i++) {
2819                 if (names[i] != NULL) {
2820                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2821                                names[i]);
2822                         ret = False;
2823                 }
2824         }
2825
2826         return ret;
2827 }
2828
2829 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2830                                    struct policy_handle *group_handle)
2831 {
2832         struct samr_DeleteDomainGroup d;
2833         NTSTATUS status;
2834         BOOL ret = True;
2835
2836         printf("Testing DeleteDomainGroup\n");
2837
2838         d.in.group_handle = group_handle;
2839         d.out.group_handle = group_handle;
2840
2841         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2842         if (!NT_STATUS_IS_OK(status)) {
2843                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2844                 ret = False;
2845         }
2846
2847         return ret;
2848 }
2849
2850 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2851                                             struct policy_handle *domain_handle)
2852 {
2853         struct samr_TestPrivateFunctionsDomain r;
2854         NTSTATUS status;
2855         BOOL ret = True;
2856
2857         printf("Testing TestPrivateFunctionsDomain\n");
2858
2859         r.in.domain_handle = domain_handle;
2860
2861         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2862         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2863                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2864                 ret = False;
2865         }
2866
2867         return ret;
2868 }
2869
2870 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2871                           struct dom_sid *domain_sid,
2872                           struct policy_handle *domain_handle)
2873 {
2874         struct samr_RidToSid r;
2875         NTSTATUS status;
2876         BOOL ret = True;
2877         struct dom_sid *calc_sid;
2878         int rids[] = { 0, 42, 512, 10200 };
2879         int i;
2880
2881         for (i=0;i<ARRAY_SIZE(rids);i++) {
2882         
2883                 printf("Testing RidToSid\n");
2884                 
2885                 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2886                 r.in.domain_handle = domain_handle;
2887                 r.in.rid = rids[i];
2888                 
2889                 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2890                 if (!NT_STATUS_IS_OK(status)) {
2891                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2892                         ret = False;
2893                 } else {
2894                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2895
2896                         if (!dom_sid_equal(calc_sid, r.out.sid)) {
2897                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
2898                                        dom_sid_string(mem_ctx, r.out.sid), 
2899                                        dom_sid_string(mem_ctx, calc_sid));
2900                                 ret = False;
2901                         }
2902                 }
2903         }
2904
2905         return ret;
2906 }
2907
2908 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2909                                        struct policy_handle *domain_handle)
2910 {
2911         struct samr_GetBootKeyInformation r;
2912         NTSTATUS status;
2913         BOOL ret = True;
2914
2915         printf("Testing GetBootKeyInformation\n");
2916
2917         r.in.domain_handle = domain_handle;
2918
2919         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2920         if (!NT_STATUS_IS_OK(status)) {
2921                 /* w2k3 seems to fail this sometimes and pass it sometimes */
2922                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2923         }
2924
2925         return ret;
2926 }
2927
2928 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2929                                 struct policy_handle *domain_handle,
2930                                 struct policy_handle *group_handle)
2931 {
2932         NTSTATUS status;
2933         struct samr_AddGroupMember r;
2934         struct samr_DeleteGroupMember d;
2935         struct samr_QueryGroupMember q;
2936         struct samr_SetMemberAttributesOfGroup s;
2937         BOOL ret = True;
2938         uint32_t rid;
2939
2940         status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2941         if (!NT_STATUS_IS_OK(status)) {
2942                 return False;
2943         }
2944
2945         r.in.group_handle = group_handle;
2946         r.in.rid = rid;
2947         r.in.flags = 0; /* ??? */
2948
2949         printf("Testing AddGroupMember and DeleteGroupMember\n");
2950
2951         d.in.group_handle = group_handle;
2952         d.in.rid = rid;
2953
2954         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2955         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2956                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
2957                        nt_errstr(status));
2958                 return False;
2959         }
2960
2961         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2962         if (!NT_STATUS_IS_OK(status)) {
2963                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2964                 return False;
2965         }
2966
2967         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2968         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2969                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
2970                        nt_errstr(status));
2971                 return False;
2972         }
2973
2974         /* this one is quite strange. I am using random inputs in the
2975            hope of triggering an error that might give us a clue */
2976         s.in.group_handle = group_handle;
2977         s.in.unknown1 = random();
2978         s.in.unknown2 = random();
2979
2980         status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2981         if (!NT_STATUS_IS_OK(status)) {
2982                 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2983                 return False;
2984         }
2985
2986         q.in.group_handle = group_handle;
2987
2988         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2989         if (!NT_STATUS_IS_OK(status)) {
2990                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2991                 return False;
2992         }
2993
2994         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2995         if (!NT_STATUS_IS_OK(status)) {
2996                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2997                 return False;
2998         }
2999
3000         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
3001         if (!NT_STATUS_IS_OK(status)) {
3002                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
3003                 return False;
3004         }
3005
3006         return ret;
3007 }
3008
3009
3010 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3011                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
3012 {
3013         NTSTATUS status;
3014         struct samr_CreateDomainGroup r;
3015         uint32_t rid;
3016         struct lsa_String name;
3017         BOOL ret = True;
3018
3019         init_lsa_String(&name, TEST_GROUPNAME);
3020
3021         r.in.domain_handle = domain_handle;
3022         r.in.name = &name;
3023         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3024         r.out.group_handle = group_handle;
3025         r.out.rid = &rid;
3026
3027         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3028
3029         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3030
3031         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3032                 printf("Server refused create of '%s'\n", r.in.name->string);
3033                 ZERO_STRUCTP(group_handle);
3034                 return True;
3035         }
3036
3037         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3038             NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3039                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3040                         return False;
3041                 }
3042                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3043         }
3044         if (!NT_STATUS_IS_OK(status)) {
3045                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3046                 return False;
3047         }
3048
3049         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3050                 ret = False;
3051         }
3052
3053         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3054                 ret = False;
3055         }
3056
3057         return ret;
3058 }
3059
3060
3061 /*
3062   its not totally clear what this does. It seems to accept any sid you like.
3063 */
3064 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
3065                                                TALLOC_CTX *mem_ctx, 
3066                                                struct policy_handle *domain_handle)
3067 {
3068         NTSTATUS status;
3069         struct samr_RemoveMemberFromForeignDomain r;
3070
3071         r.in.domain_handle = domain_handle;
3072         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3073
3074         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3075         if (!NT_STATUS_IS_OK(status)) {
3076                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3077                 return False;
3078         }
3079
3080         return True;
3081 }
3082
3083
3084
3085 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3086                          struct policy_handle *handle);
3087
3088 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3089                             struct policy_handle *handle, struct dom_sid *sid)
3090 {
3091         NTSTATUS status;
3092         struct samr_OpenDomain r;
3093         struct policy_handle domain_handle;
3094         struct policy_handle user_handle;
3095         struct policy_handle alias_handle;
3096         struct policy_handle group_handle;
3097         BOOL ret = True;
3098
3099         ZERO_STRUCT(user_handle);
3100         ZERO_STRUCT(alias_handle);
3101         ZERO_STRUCT(group_handle);
3102         ZERO_STRUCT(domain_handle);
3103
3104         printf("Testing OpenDomain\n");
3105
3106         r.in.connect_handle = handle;
3107         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3108         r.in.sid = sid;
3109         r.out.domain_handle = &domain_handle;
3110
3111         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3112         if (!NT_STATUS_IS_OK(status)) {
3113                 printf("OpenDomain failed - %s\n", nt_errstr(status));
3114                 return False;
3115         }
3116
3117         /* run the domain tests with the main handle closed - this tests
3118            the servers reference counting */
3119         ret &= test_samr_handle_Close(p, mem_ctx, handle);
3120
3121         ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3122         ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3123         ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3124         ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3125         ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3126         ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3127         ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3128         ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3129         ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3130         ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3131         ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3132         ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3133         ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3134         ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3135         ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3136         ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3137         ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3138         ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3139         ret &= test_GroupList(p, mem_ctx, &domain_handle);
3140         ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3141         ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3142         ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3143
3144         if (!policy_handle_empty(&user_handle) &&
3145             !test_DeleteUser(p, mem_ctx, &user_handle)) {
3146                 ret = False;
3147         }
3148
3149         if (!policy_handle_empty(&alias_handle) &&
3150             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3151                 ret = False;
3152         }
3153
3154         if (!policy_handle_empty(&group_handle) &&
3155             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3156                 ret = False;
3157         }
3158
3159         ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3160
3161         /* reconnect the main handle */
3162         ret &= test_Connect(p, mem_ctx, handle);
3163
3164         return ret;
3165 }
3166
3167 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3168                               struct policy_handle *handle, struct lsa_String *domain)
3169 {
3170         NTSTATUS status;
3171         struct samr_LookupDomain r;
3172         struct lsa_String n2;
3173         BOOL ret = True;
3174
3175         printf("Testing LookupDomain(%s)\n", domain->string);
3176
3177         /* check for correct error codes */
3178         r.in.connect_handle = handle;
3179         r.in.domain_name = &n2;
3180         n2.string = NULL;
3181
3182         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3183         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3184                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3185                 ret = False;
3186         }
3187
3188         n2.string = "xxNODOMAINxx";
3189
3190         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3191         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3192                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3193                 ret = False;
3194         }
3195
3196         r.in.connect_handle = handle;
3197         r.in.domain_name = domain;
3198
3199         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3200         if (!NT_STATUS_IS_OK(status)) {
3201                 printf("LookupDomain failed - %s\n", nt_errstr(status));
3202                 ret = False;
3203         }
3204
3205         if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3206                 ret = False;
3207         }
3208
3209         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3210                 ret = False;
3211         }
3212
3213         return ret;
3214 }
3215
3216
3217 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3218                              struct policy_handle *handle)
3219 {
3220         NTSTATUS status;
3221         struct samr_EnumDomains r;
3222         uint32_t resume_handle = 0;
3223         int i;
3224         BOOL ret = True;
3225
3226         r.in.connect_handle = handle;
3227         r.in.resume_handle = &resume_handle;
3228         r.in.buf_size = (uint32_t)-1;
3229         r.out.resume_handle = &resume_handle;
3230
3231         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3232         if (!NT_STATUS_IS_OK(status)) {
3233                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3234                 return False;
3235         }
3236
3237         if (!r.out.sam) {
3238                 return False;
3239         }
3240
3241         for (i=0;i<r.out.sam->count;i++) {
3242                 if (!test_LookupDomain(p, mem_ctx, handle, 
3243                                        &r.out.sam->entries[i].name)) {
3244                         ret = False;
3245                 }
3246         }
3247
3248         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3249         if (!NT_STATUS_IS_OK(status)) {
3250                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3251                 return False;
3252         }
3253
3254         return ret;
3255 }
3256
3257
3258 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3259                          struct policy_handle *handle)
3260 {
3261         NTSTATUS status;
3262         struct samr_Connect r;
3263         struct samr_Connect2 r2;
3264         struct samr_Connect3 r3;
3265         struct samr_Connect4 r4;
3266         struct samr_Connect5 r5;
3267         union samr_ConnectInfo info;
3268         struct policy_handle h;
3269         BOOL ret = True, got_handle = False;
3270
3271         printf("testing samr_Connect\n");
3272
3273         r.in.system_name = 0;
3274         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3275         r.out.connect_handle = &h;
3276
3277         status = dcerpc_samr_Connect(p, mem_ctx, &r);
3278         if (!NT_STATUS_IS_OK(status)) {
3279                 printf("Connect failed - %s\n", nt_errstr(status));
3280                 ret = False;
3281         } else {
3282                 got_handle = True;
3283                 *handle = h;
3284         }
3285
3286         printf("testing samr_Connect2\n");
3287
3288         r2.in.system_name = NULL;
3289         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3290         r2.out.connect_handle = &h;
3291
3292         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3293         if (!NT_STATUS_IS_OK(status)) {
3294                 printf("Connect2 failed - %s\n", nt_errstr(status));
3295                 ret = False;
3296         } else {
3297                 if (got_handle) {
3298                         test_samr_handle_Close(p, mem_ctx, handle);
3299                 }
3300                 got_handle = True;
3301                 *handle = h;
3302         }
3303
3304         printf("testing samr_Connect3\n");
3305
3306         r3.in.system_name = NULL;
3307         r3.in.unknown = 0;
3308         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3309         r3.out.connect_handle = &h;
3310
3311         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3312         if (!NT_STATUS_IS_OK(status)) {
3313                 printf("Connect3 failed - %s\n", nt_errstr(status));
3314                 ret = False;
3315         } else {
3316                 if (got_handle) {
3317                         test_samr_handle_Close(p, mem_ctx, handle);
3318                 }
3319                 got_handle = True;
3320                 *handle = h;
3321         }
3322
3323         printf("testing samr_Connect4\n");
3324
3325         r4.in.system_name = "";
3326         r4.in.unknown = 0;
3327         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3328         r4.out.connect_handle = &h;
3329
3330         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3331         if (!NT_STATUS_IS_OK(status)) {
3332                 printf("Connect4 failed - %s\n", nt_errstr(status));
3333                 ret = False;
3334         } else {
3335                 if (got_handle) {
3336                         test_samr_handle_Close(p, mem_ctx, handle);
3337                 }
3338                 got_handle = True;
3339                 *handle = h;
3340         }
3341
3342         printf("testing samr_Connect5\n");
3343
3344         info.info1.unknown1 = 0;
3345         info.info1.unknown2 = 0;
3346
3347         r5.in.system_name = "";
3348         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3349         r5.in.level = 1;
3350         r5.in.info = &info;
3351         r5.out.info = &info;
3352         r5.out.connect_handle = &h;
3353
3354         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3355         if (!NT_STATUS_IS_OK(status)) {
3356                 printf("Connect5 failed - %s\n", nt_errstr(status));
3357                 ret = False;
3358         } else {
3359                 if (got_handle) {
3360                         test_samr_handle_Close(p, mem_ctx, handle);
3361                 }
3362                 got_handle = True;
3363                 *handle = h;
3364         }
3365
3366         return ret;
3367 }
3368
3369
3370 BOOL torture_rpc_samr(struct torture_context *torture)
3371 {
3372         NTSTATUS status;
3373         struct dcerpc_pipe *p;
3374         TALLOC_CTX *mem_ctx;
3375         BOOL ret = True;
3376         struct policy_handle handle;
3377
3378         mem_ctx = talloc_init("torture_rpc_samr");
3379
3380         status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3381         if (!NT_STATUS_IS_OK(status)) {
3382                 talloc_free(mem_ctx);
3383                 return False;
3384         }
3385
3386         if (!test_Connect(p, mem_ctx, &handle)) {
3387                 ret = False;
3388         }
3389
3390         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3391                 ret = False;
3392         }
3393
3394         if (!test_EnumDomains(p, mem_ctx, &handle)) {
3395                 ret = False;
3396         }
3397
3398         if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3399                 ret = False;
3400         }
3401
3402         if (!test_Shutdown(p, mem_ctx, &handle)) {
3403                 ret = False;
3404         }
3405
3406         if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3407                 ret = False;
3408         }
3409
3410         talloc_free(mem_ctx);
3411
3412         return ret;
3413 }
3414