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