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