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