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