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