Remove unused include param/param.h.
[jra/samba/.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "../lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
37
38 enum torture_samr_choice {
39         TORTURE_SAMR_PASSWORDS,
40         TORTURE_SAMR_USER_ATTRIBUTES,
41         TORTURE_SAMR_OTHER
42 };
43
44 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
45                                struct policy_handle *handle);
46
47 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
48                                 struct policy_handle *handle);
49
50 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51                                struct policy_handle *handle);
52
53 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
54                                 const char *acct_name, 
55                                 struct policy_handle *domain_handle, char **password);
56
57 static void init_lsa_String(struct lsa_String *string, const char *s)
58 {
59         string->string = s;
60 }
61
62 bool test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
63                                    struct policy_handle *handle)
64 {
65         NTSTATUS status;
66         struct samr_Close r;
67
68         r.in.handle = handle;
69         r.out.handle = handle;
70
71         status = dcerpc_samr_Close(p, mem_ctx, &r);
72         if (!NT_STATUS_IS_OK(status)) {
73                 printf("Close handle failed - %s\n", nt_errstr(status));
74                 return false;
75         }
76
77         return true;
78 }
79
80 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
81                        struct policy_handle *handle)
82 {
83         NTSTATUS status;
84         struct samr_Shutdown r;
85
86         if (!torture_setting_bool(tctx, "dangerous", false)) {
87                 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
88                 return true;
89         }
90
91         r.in.connect_handle = handle;
92
93         printf("testing samr_Shutdown\n");
94
95         status = dcerpc_samr_Shutdown(p, tctx, &r);
96         if (!NT_STATUS_IS_OK(status)) {
97                 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
98                 return false;
99         }
100
101         return true;
102 }
103
104 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
105                                  struct policy_handle *handle)
106 {
107         NTSTATUS status;
108         struct samr_SetDsrmPassword r;
109         struct lsa_String string;
110         struct samr_Password hash;
111
112         if (!torture_setting_bool(tctx, "dangerous", false)) {
113                 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
114                 return true;
115         }
116
117         E_md4hash("TeSTDSRM123", hash.hash);
118
119         init_lsa_String(&string, "Administrator");
120
121         r.in.name = &string;
122         r.in.unknown = 0;
123         r.in.hash = &hash;
124
125         printf("testing samr_SetDsrmPassword\n");
126
127         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
128         if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
129                 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
130                 return false;
131         }
132
133         return true;
134 }
135
136
137 static bool test_QuerySecurity(struct dcerpc_pipe *p, 
138                                struct torture_context *tctx, 
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, tctx, &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 (torture_setting_bool(tctx, "samba4", false)) {
163                 printf("skipping SetSecurity test against Samba4\n");
164                 return true;
165         }
166
167         status = dcerpc_samr_SetSecurity(p, tctx, &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, tctx, &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, struct torture_context *tctx, 
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, tctx, &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%llx - got 0x%llx (%s)\n", \
232                                #field, (unsigned long long)i2, (unsigned long long)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(tctx, "%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(tctx, "%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(tctx, "%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(tctx, "%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(tctx, "%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(tctx, "%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(6, full_name,  1, full_name, "", 0);
329         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
330         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
331         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
332         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
333         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
334         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
335         TEST_USERINFO_STRING(21, full_name, 21, full_name, "", 
336                            SAMR_FIELD_FULL_NAME);
337
338         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
339         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
340         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
341         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
342                            SAMR_FIELD_LOGON_SCRIPT);
343
344         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
345         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
346         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
347         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
348                            SAMR_FIELD_PROFILE_PATH);
349
350         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
351         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
352         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
353         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
354                              SAMR_FIELD_HOME_DIRECTORY);
355         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
356                              SAMR_FIELD_HOME_DIRECTORY);
357
358         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
359         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
360         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
361         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
362                              SAMR_FIELD_HOME_DRIVE);
363         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
364                              SAMR_FIELD_HOME_DRIVE);
365         
366         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
367         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
368         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
369         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
370                            SAMR_FIELD_DESCRIPTION);
371
372         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
373         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
374         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
375         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
376                            SAMR_FIELD_WORKSTATIONS);
377         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3", 
378                            SAMR_FIELD_WORKSTATIONS);
379         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5", 
380                            SAMR_FIELD_WORKSTATIONS);
381         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", 
382                            SAMR_FIELD_WORKSTATIONS);
383
384         TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
385         TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters", 
386                            SAMR_FIELD_PARAMETERS);
387         TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters", 
388                            SAMR_FIELD_PARAMETERS);
389
390         TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
391         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
392         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
393                           SAMR_FIELD_COUNTRY_CODE);
394         TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__, 
395                           SAMR_FIELD_COUNTRY_CODE);
396
397         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
398         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
399                           SAMR_FIELD_CODE_PAGE);
400         TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__, 
401                           SAMR_FIELD_CODE_PAGE);
402
403         TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
404         TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
405         TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__, 
406                           SAMR_FIELD_ACCT_EXPIRY);
407         TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__, 
408                           SAMR_FIELD_ACCT_EXPIRY);
409         TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__, 
410                           SAMR_FIELD_ACCT_EXPIRY);
411
412         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
413         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
414         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
415         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
416                           SAMR_FIELD_LOGON_HOURS);
417
418         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
419                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
420                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
421                               0);
422         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
423                               (base_acct_flags  | ACB_DISABLED), 
424                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
425                               0);
426         
427         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
428         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
429                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
430                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
431                               0);
432         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
433                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
434                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
435                               0);
436
437
438         /* The 'autolock' flag doesn't stick - check this */
439         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
440                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
441                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
442                               0);
443 #if 0
444         /* Removing the 'disabled' flag doesn't stick - check this */
445         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
446                               (base_acct_flags), 
447                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
448                               0);
449 #endif
450         /* The 'store plaintext' flag does stick */
451         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
452                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
453                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
454                               0);
455         /* The 'use DES' flag does stick */
456         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
457                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
458                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
459                               0);
460         /* The 'don't require kerberos pre-authentication flag does stick */
461         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
462                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
463                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
464                               0);
465         /* The 'no kerberos PAC required' flag sticks */
466         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
467                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
468                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
469                               0);
470
471         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
472                               (base_acct_flags | ACB_DISABLED), 
473                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
474                               SAMR_FIELD_ACCT_FLAGS);
475
476 #if 0
477         /* these fail with win2003 - it appears you can't set the primary gid?
478            the set succeeds, but the gid isn't changed. Very weird! */
479         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
480         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
481         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
482         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
483 #endif
484
485         return ret;
486 }
487
488 /*
489   generate a random password for password change tests
490 */
491 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
492 {
493         size_t len = MAX(8, min_len) + (random() % 6);
494         char *s = generate_random_str(mem_ctx, len);
495         printf("Generated password '%s'\n", s);
496         return s;
497 }
498
499 /*
500   generate a random password for password change tests
501 */
502 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
503 {
504         int i;
505         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
506         generate_random_buffer(password.data, password.length);
507
508         for (i=0; i < len; i++) {
509                 if (((uint16_t *)password.data)[i] == 0) {
510                         ((uint16_t *)password.data)[i] = 1;
511                 }
512         }
513
514         return password;
515 }
516
517 /*
518   generate a random password for password change tests (fixed length)
519 */
520 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
521 {
522         char *s = generate_random_str(mem_ctx, len);
523         printf("Generated password '%s'\n", s);
524         return s;
525 }
526
527 static bool test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
528                              struct policy_handle *handle, char **password)
529 {
530         NTSTATUS status;
531         struct samr_SetUserInfo s;
532         union samr_UserInfo u;
533         bool ret = true;
534         DATA_BLOB session_key;
535         char *newpass;
536         struct samr_GetUserPwInfo pwp;
537         int policy_min_pw_len = 0;
538         pwp.in.user_handle = handle;
539
540         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
541         if (NT_STATUS_IS_OK(status)) {
542                 policy_min_pw_len = pwp.out.info.min_password_length;
543         }
544         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
545
546         s.in.user_handle = handle;
547         s.in.info = &u;
548         s.in.level = 24;
549
550         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
551         /* w2k3 ignores this length */
552         u.info24.pw_len = strlen_m(newpass) * 2;
553
554         status = dcerpc_fetch_session_key(p, &session_key);
555         if (!NT_STATUS_IS_OK(status)) {
556                 printf("SetUserInfo level %u - no session key - %s\n",
557                        s.in.level, nt_errstr(status));
558                 return false;
559         }
560
561         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
562
563         printf("Testing SetUserInfo level 24 (set password)\n");
564
565         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
566         if (!NT_STATUS_IS_OK(status)) {
567                 printf("SetUserInfo level %u failed - %s\n",
568                        s.in.level, nt_errstr(status));
569                 ret = false;
570         } else {
571                 *password = newpass;
572         }
573
574         return ret;
575 }
576
577
578 static bool test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
579                                 struct policy_handle *handle, uint32_t fields_present,
580                                 char **password)
581 {
582         NTSTATUS status;
583         struct samr_SetUserInfo s;
584         union samr_UserInfo u;
585         bool ret = true;
586         DATA_BLOB session_key;
587         char *newpass;
588         struct samr_GetUserPwInfo pwp;
589         int policy_min_pw_len = 0;
590         pwp.in.user_handle = handle;
591
592         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
593         if (NT_STATUS_IS_OK(status)) {
594                 policy_min_pw_len = pwp.out.info.min_password_length;
595         }
596         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
597
598         s.in.user_handle = handle;
599         s.in.info = &u;
600         s.in.level = 23;
601
602         ZERO_STRUCT(u);
603
604         u.info23.info.fields_present = fields_present;
605
606         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
607
608         status = dcerpc_fetch_session_key(p, &session_key);
609         if (!NT_STATUS_IS_OK(status)) {
610                 printf("SetUserInfo level %u - no session key - %s\n",
611                        s.in.level, nt_errstr(status));
612                 return false;
613         }
614
615         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
616
617         printf("Testing SetUserInfo level 23 (set password)\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         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
629
630         status = dcerpc_fetch_session_key(p, &session_key);
631         if (!NT_STATUS_IS_OK(status)) {
632                 printf("SetUserInfo level %u - no session key - %s\n",
633                        s.in.level, nt_errstr(status));
634                 return false;
635         }
636
637         /* This should break the key nicely */
638         session_key.length--;
639         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
640
641         printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
642
643         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
644         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
645                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
646                        s.in.level, nt_errstr(status));
647                 ret = false;
648         }
649
650         return ret;
651 }
652
653
654 static bool test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
655                                struct policy_handle *handle, bool makeshort, 
656                                char **password)
657 {
658         NTSTATUS status;
659         struct samr_SetUserInfo s;
660         union samr_UserInfo u;
661         bool ret = true;
662         DATA_BLOB session_key;
663         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
664         uint8_t confounder[16];
665         char *newpass;
666         struct MD5Context ctx;
667         struct samr_GetUserPwInfo pwp;
668         int policy_min_pw_len = 0;
669         pwp.in.user_handle = handle;
670
671         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
672         if (NT_STATUS_IS_OK(status)) {
673                 policy_min_pw_len = pwp.out.info.min_password_length;
674         }
675         if (makeshort && policy_min_pw_len) {
676                 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
677         } else {
678                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
679         }
680
681         s.in.user_handle = handle;
682         s.in.info = &u;
683         s.in.level = 26;
684
685         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
686         u.info26.pw_len = strlen(newpass);
687
688         status = dcerpc_fetch_session_key(p, &session_key);
689         if (!NT_STATUS_IS_OK(status)) {
690                 printf("SetUserInfo level %u - no session key - %s\n",
691                        s.in.level, nt_errstr(status));
692                 return false;
693         }
694
695         generate_random_buffer((uint8_t *)confounder, 16);
696
697         MD5Init(&ctx);
698         MD5Update(&ctx, confounder, 16);
699         MD5Update(&ctx, session_key.data, session_key.length);
700         MD5Final(confounded_session_key.data, &ctx);
701
702         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
703         memcpy(&u.info26.password.data[516], confounder, 16);
704
705         printf("Testing SetUserInfo level 26 (set password ex)\n");
706
707         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
708         if (!NT_STATUS_IS_OK(status)) {
709                 printf("SetUserInfo level %u failed - %s\n",
710                        s.in.level, nt_errstr(status));
711                 ret = false;
712         } else {
713                 *password = newpass;
714         }
715
716         /* This should break the key nicely */
717         confounded_session_key.data[0]++;
718
719         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
720         memcpy(&u.info26.password.data[516], confounder, 16);
721
722         printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
723
724         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
725         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
726                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
727                        s.in.level, nt_errstr(status));
728                 ret = false;
729         } else {
730                 *password = newpass;
731         }
732
733         return ret;
734 }
735
736 static bool test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
737                                 struct policy_handle *handle, uint32_t fields_present,
738                                 char **password)
739 {
740         NTSTATUS status;
741         struct samr_SetUserInfo s;
742         union samr_UserInfo u;
743         bool ret = true;
744         DATA_BLOB session_key;
745         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
746         struct MD5Context ctx;
747         uint8_t confounder[16];
748         char *newpass;
749         struct samr_GetUserPwInfo pwp;
750         int policy_min_pw_len = 0;
751         pwp.in.user_handle = handle;
752
753         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
754         if (NT_STATUS_IS_OK(status)) {
755                 policy_min_pw_len = pwp.out.info.min_password_length;
756         }
757         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
758
759         s.in.user_handle = handle;
760         s.in.info = &u;
761         s.in.level = 25;
762
763         ZERO_STRUCT(u);
764
765         u.info25.info.fields_present = fields_present;
766
767         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
768
769         status = dcerpc_fetch_session_key(p, &session_key);
770         if (!NT_STATUS_IS_OK(status)) {
771                 printf("SetUserInfo level %u - no session key - %s\n",
772                        s.in.level, nt_errstr(status));
773                 return false;
774         }
775
776         generate_random_buffer((uint8_t *)confounder, 16);
777
778         MD5Init(&ctx);
779         MD5Update(&ctx, confounder, 16);
780         MD5Update(&ctx, session_key.data, session_key.length);
781         MD5Final(confounded_session_key.data, &ctx);
782
783         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
784         memcpy(&u.info25.password.data[516], confounder, 16);
785
786         printf("Testing SetUserInfo level 25 (set password ex)\n");
787
788         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
789         if (!NT_STATUS_IS_OK(status)) {
790                 printf("SetUserInfo level %u failed - %s\n",
791                        s.in.level, nt_errstr(status));
792                 ret = false;
793         } else {
794                 *password = newpass;
795         }
796
797         /* This should break the key nicely */
798         confounded_session_key.data[0]++;
799
800         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
801         memcpy(&u.info25.password.data[516], confounder, 16);
802
803         printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
804
805         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
806         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
807                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
808                        s.in.level, nt_errstr(status));
809                 ret = false;
810         }
811
812         return ret;
813 }
814
815 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
816                                struct policy_handle *handle)
817 {
818         NTSTATUS status;
819         struct samr_SetAliasInfo r;
820         struct samr_QueryAliasInfo q;
821         uint16_t levels[] = {2, 3};
822         int i;
823         bool ret = true;
824
825         /* Ignoring switch level 1, as that includes the number of members for the alias
826          * and setting this to a wrong value might have negative consequences
827          */
828
829         for (i=0;i<ARRAY_SIZE(levels);i++) {
830                 printf("Testing SetAliasInfo level %u\n", levels[i]);
831
832                 r.in.alias_handle = handle;
833                 r.in.level = levels[i];
834                 r.in.info  = talloc(tctx, union samr_AliasInfo);
835                 switch (r.in.level) {
836                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
837                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
838                                 "Test Description, should test I18N as well"); break;
839                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
840                 }
841
842                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
843                 if (!NT_STATUS_IS_OK(status)) {
844                         printf("SetAliasInfo level %u failed - %s\n",
845                                levels[i], nt_errstr(status));
846                         ret = false;
847                 }
848
849                 q.in.alias_handle = handle;
850                 q.in.level = levels[i];
851
852                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
853                 if (!NT_STATUS_IS_OK(status)) {
854                         printf("QueryAliasInfo level %u failed - %s\n",
855                                levels[i], nt_errstr(status));
856                         ret = false;
857                 }
858         }
859
860         return ret;
861 }
862
863 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
864                                   struct policy_handle *user_handle)
865 {
866         struct samr_GetGroupsForUser r;
867         NTSTATUS status;
868         bool ret = true;
869
870         printf("testing GetGroupsForUser\n");
871
872         r.in.user_handle = user_handle;
873
874         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
875         if (!NT_STATUS_IS_OK(status)) {
876                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
877                 ret = false;
878         }
879
880         return ret;
881
882 }
883
884 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
885                               struct lsa_String *domain_name)
886 {
887         NTSTATUS status;
888         struct samr_GetDomPwInfo r;
889         bool ret = true;
890
891         r.in.domain_name = domain_name;
892         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
893
894         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
895         if (!NT_STATUS_IS_OK(status)) {
896                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
897                 ret = false;
898         }
899
900         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
901         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
902
903         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
904         if (!NT_STATUS_IS_OK(status)) {
905                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
906                 ret = false;
907         }
908
909         r.in.domain_name->string = "\\\\__NONAME__";
910         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
911
912         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
913         if (!NT_STATUS_IS_OK(status)) {
914                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
915                 ret = false;
916         }
917
918         r.in.domain_name->string = "\\\\Builtin";
919         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
920
921         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
922         if (!NT_STATUS_IS_OK(status)) {
923                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
924                 ret = false;
925         }
926
927
928         return ret;
929 }
930
931 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
932                                struct policy_handle *handle)
933 {
934         NTSTATUS status;
935         struct samr_GetUserPwInfo r;
936         bool ret = true;
937
938         printf("Testing GetUserPwInfo\n");
939
940         r.in.user_handle = handle;
941
942         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
943         if (!NT_STATUS_IS_OK(status)) {
944                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
945                 ret = false;
946         }
947
948         return ret;
949 }
950
951 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
952                                 struct policy_handle *domain_handle, const char *name,
953                                 uint32_t *rid)
954 {
955         NTSTATUS status;
956         struct samr_LookupNames n;
957         struct lsa_String sname[2];
958
959         init_lsa_String(&sname[0], name);
960
961         n.in.domain_handle = domain_handle;
962         n.in.num_names = 1;
963         n.in.names = sname;
964         status = dcerpc_samr_LookupNames(p, tctx, &n);
965         if (NT_STATUS_IS_OK(status)) {
966                 *rid = n.out.rids.ids[0];
967         } else {
968                 return status;
969         }
970
971         init_lsa_String(&sname[1], "xxNONAMExx");
972         n.in.num_names = 2;
973         status = dcerpc_samr_LookupNames(p, tctx, &n);
974         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
975                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
976                 if (NT_STATUS_IS_OK(status)) {
977                         return NT_STATUS_UNSUCCESSFUL;
978                 }
979                 return status;
980         }
981
982         n.in.num_names = 0;
983         status = dcerpc_samr_LookupNames(p, tctx, &n);
984         if (!NT_STATUS_IS_OK(status)) {
985                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
986                 return status;
987         }
988
989         init_lsa_String(&sname[0], "xxNONAMExx");
990         n.in.num_names = 1;
991         status = dcerpc_samr_LookupNames(p, tctx, &n);
992         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
993                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
994                 if (NT_STATUS_IS_OK(status)) {
995                         return NT_STATUS_UNSUCCESSFUL;
996                 }
997                 return status;
998         }
999
1000         init_lsa_String(&sname[0], "xxNONAMExx");
1001         init_lsa_String(&sname[1], "xxNONAME2xx");
1002         n.in.num_names = 2;
1003         status = dcerpc_samr_LookupNames(p, tctx, &n);
1004         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1005                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
1006                 if (NT_STATUS_IS_OK(status)) {
1007                         return NT_STATUS_UNSUCCESSFUL;
1008                 }
1009                 return status;
1010         }
1011
1012         return NT_STATUS_OK;
1013 }
1014
1015 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1016                                      struct policy_handle *domain_handle,
1017                                      const char *name, struct policy_handle *user_handle)
1018 {
1019         NTSTATUS status;
1020         struct samr_OpenUser r;
1021         uint32_t rid;
1022
1023         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1024         if (!NT_STATUS_IS_OK(status)) {
1025                 return status;
1026         }
1027
1028         r.in.domain_handle = domain_handle;
1029         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1030         r.in.rid = rid;
1031         r.out.user_handle = user_handle;
1032         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1033         if (!NT_STATUS_IS_OK(status)) {
1034                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1035         }
1036
1037         return status;
1038 }
1039
1040 #if 0
1041 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1042                                    struct policy_handle *handle)
1043 {
1044         NTSTATUS status;
1045         struct samr_ChangePasswordUser r;
1046         bool ret = true;
1047         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1048         struct policy_handle user_handle;
1049         char *oldpass = "test";
1050         char *newpass = "test2";
1051         uint8_t old_nt_hash[16], new_nt_hash[16];
1052         uint8_t old_lm_hash[16], new_lm_hash[16];
1053
1054         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1055         if (!NT_STATUS_IS_OK(status)) {
1056                 return false;
1057         }
1058
1059         printf("Testing ChangePasswordUser for user 'testuser'\n");
1060
1061         printf("old password: %s\n", oldpass);
1062         printf("new password: %s\n", newpass);
1063
1064         E_md4hash(oldpass, old_nt_hash);
1065         E_md4hash(newpass, new_nt_hash);
1066         E_deshash(oldpass, old_lm_hash);
1067         E_deshash(newpass, new_lm_hash);
1068
1069         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1070         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1071         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1072         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1073         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1074         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1075
1076         r.in.handle = &user_handle;
1077         r.in.lm_present = 1;
1078         r.in.old_lm_crypted = &hash1;
1079         r.in.new_lm_crypted = &hash2;
1080         r.in.nt_present = 1;
1081         r.in.old_nt_crypted = &hash3;
1082         r.in.new_nt_crypted = &hash4;
1083         r.in.cross1_present = 1;
1084         r.in.nt_cross = &hash5;
1085         r.in.cross2_present = 1;
1086         r.in.lm_cross = &hash6;
1087
1088         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1089         if (!NT_STATUS_IS_OK(status)) {
1090                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1091                 ret = false;
1092         }
1093
1094         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1095                 ret = false;
1096         }
1097
1098         return ret;
1099 }
1100 #endif
1101
1102 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1103                                     const char *acct_name, 
1104                                     struct policy_handle *handle, char **password)
1105 {
1106         NTSTATUS status;
1107         struct samr_ChangePasswordUser r;
1108         bool ret = true;
1109         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1110         struct policy_handle user_handle;
1111         char *oldpass;
1112         uint8_t old_nt_hash[16], new_nt_hash[16];
1113         uint8_t old_lm_hash[16], new_lm_hash[16];
1114         bool changed = true;
1115
1116         char *newpass;
1117         struct samr_GetUserPwInfo pwp;
1118         int policy_min_pw_len = 0;
1119
1120         status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1121         if (!NT_STATUS_IS_OK(status)) {
1122                 return false;
1123         }
1124         pwp.in.user_handle = &user_handle;
1125
1126         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1127         if (NT_STATUS_IS_OK(status)) {
1128                 policy_min_pw_len = pwp.out.info.min_password_length;
1129         }
1130         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1131
1132         printf("Testing ChangePasswordUser\n");
1133
1134         if (!*password) {
1135                 printf("Failing ChangePasswordUser as old password was NULL.  Previous test failed?\n");
1136                 return false;
1137         }
1138
1139         oldpass = *password;
1140
1141         E_md4hash(oldpass, old_nt_hash);
1142         E_md4hash(newpass, new_nt_hash);
1143         E_deshash(oldpass, old_lm_hash);
1144         E_deshash(newpass, new_lm_hash);
1145
1146         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1147         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1148         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1149         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1150         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1151         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1152
1153         r.in.user_handle = &user_handle;
1154         r.in.lm_present = 1;
1155         /* Break the LM hash */
1156         hash1.hash[0]++;
1157         r.in.old_lm_crypted = &hash1;
1158         r.in.new_lm_crypted = &hash2;
1159         r.in.nt_present = 1;
1160         r.in.old_nt_crypted = &hash3;
1161         r.in.new_nt_crypted = &hash4;
1162         r.in.cross1_present = 1;
1163         r.in.nt_cross = &hash5;
1164         r.in.cross2_present = 1;
1165         r.in.lm_cross = &hash6;
1166
1167         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1168         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1169                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1170                 ret = false;
1171         }
1172
1173         /* Unbreak the LM hash */
1174         hash1.hash[0]--;
1175
1176         r.in.user_handle = &user_handle;
1177         r.in.lm_present = 1;
1178         r.in.old_lm_crypted = &hash1;
1179         r.in.new_lm_crypted = &hash2;
1180         /* Break the NT hash */
1181         hash3.hash[0]--;
1182         r.in.nt_present = 1;
1183         r.in.old_nt_crypted = &hash3;
1184         r.in.new_nt_crypted = &hash4;
1185         r.in.cross1_present = 1;
1186         r.in.nt_cross = &hash5;
1187         r.in.cross2_present = 1;
1188         r.in.lm_cross = &hash6;
1189
1190         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1191         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1192                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1193                 ret = false;
1194         }
1195
1196         /* Unbreak the NT hash */
1197         hash3.hash[0]--;
1198
1199         r.in.user_handle = &user_handle;
1200         r.in.lm_present = 1;
1201         r.in.old_lm_crypted = &hash1;
1202         r.in.new_lm_crypted = &hash2;
1203         r.in.nt_present = 1;
1204         r.in.old_nt_crypted = &hash3;
1205         r.in.new_nt_crypted = &hash4;
1206         r.in.cross1_present = 1;
1207         r.in.nt_cross = &hash5;
1208         r.in.cross2_present = 1;
1209         /* Break the LM cross */
1210         hash6.hash[0]++;
1211         r.in.lm_cross = &hash6;
1212
1213         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1214         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1215                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1216                 ret = false;
1217         }
1218
1219         /* Unbreak the LM cross */
1220         hash6.hash[0]--;
1221
1222         r.in.user_handle = &user_handle;
1223         r.in.lm_present = 1;
1224         r.in.old_lm_crypted = &hash1;
1225         r.in.new_lm_crypted = &hash2;
1226         r.in.nt_present = 1;
1227         r.in.old_nt_crypted = &hash3;
1228         r.in.new_nt_crypted = &hash4;
1229         r.in.cross1_present = 1;
1230         /* Break the NT cross */
1231         hash5.hash[0]++;
1232         r.in.nt_cross = &hash5;
1233         r.in.cross2_present = 1;
1234         r.in.lm_cross = &hash6;
1235
1236         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1237         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1238                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1239                 ret = false;
1240         }
1241
1242         /* Unbreak the NT cross */
1243         hash5.hash[0]--;
1244
1245
1246         /* Reset the hashes to not broken values */
1247         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1248         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1249         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1250         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1251         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1252         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1253
1254         r.in.user_handle = &user_handle;
1255         r.in.lm_present = 1;
1256         r.in.old_lm_crypted = &hash1;
1257         r.in.new_lm_crypted = &hash2;
1258         r.in.nt_present = 1;
1259         r.in.old_nt_crypted = &hash3;
1260         r.in.new_nt_crypted = &hash4;
1261         r.in.cross1_present = 1;
1262         r.in.nt_cross = &hash5;
1263         r.in.cross2_present = 0;
1264         r.in.lm_cross = NULL;
1265
1266         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1267         if (NT_STATUS_IS_OK(status)) {
1268                 changed = true;
1269                 *password = newpass;
1270         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1271                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1272                 ret = false;
1273         }
1274
1275         oldpass = newpass;
1276         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1277
1278         E_md4hash(oldpass, old_nt_hash);
1279         E_md4hash(newpass, new_nt_hash);
1280         E_deshash(oldpass, old_lm_hash);
1281         E_deshash(newpass, new_lm_hash);
1282
1283
1284         /* Reset the hashes to not broken values */
1285         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1286         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1287         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1288         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1289         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1290         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1291
1292         r.in.user_handle = &user_handle;
1293         r.in.lm_present = 1;
1294         r.in.old_lm_crypted = &hash1;
1295         r.in.new_lm_crypted = &hash2;
1296         r.in.nt_present = 1;
1297         r.in.old_nt_crypted = &hash3;
1298         r.in.new_nt_crypted = &hash4;
1299         r.in.cross1_present = 0;
1300         r.in.nt_cross = NULL;
1301         r.in.cross2_present = 1;
1302         r.in.lm_cross = &hash6;
1303
1304         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1305         if (NT_STATUS_IS_OK(status)) {
1306                 changed = true;
1307                 *password = newpass;
1308         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1309                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1310                 ret = false;
1311         }
1312
1313         oldpass = newpass;
1314         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1315
1316         E_md4hash(oldpass, old_nt_hash);
1317         E_md4hash(newpass, new_nt_hash);
1318         E_deshash(oldpass, old_lm_hash);
1319         E_deshash(newpass, new_lm_hash);
1320
1321
1322         /* Reset the hashes to not broken values */
1323         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1324         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1325         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1326         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1327         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1328         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1329
1330         r.in.user_handle = &user_handle;
1331         r.in.lm_present = 1;
1332         r.in.old_lm_crypted = &hash1;
1333         r.in.new_lm_crypted = &hash2;
1334         r.in.nt_present = 1;
1335         r.in.old_nt_crypted = &hash3;
1336         r.in.new_nt_crypted = &hash4;
1337         r.in.cross1_present = 1;
1338         r.in.nt_cross = &hash5;
1339         r.in.cross2_present = 1;
1340         r.in.lm_cross = &hash6;
1341
1342         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1343         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1344                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1345         } else  if (!NT_STATUS_IS_OK(status)) {
1346                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1347                 ret = false;
1348         } else {
1349                 changed = true;
1350                 *password = newpass;
1351         }
1352
1353         r.in.user_handle = &user_handle;
1354         r.in.lm_present = 1;
1355         r.in.old_lm_crypted = &hash1;
1356         r.in.new_lm_crypted = &hash2;
1357         r.in.nt_present = 1;
1358         r.in.old_nt_crypted = &hash3;
1359         r.in.new_nt_crypted = &hash4;
1360         r.in.cross1_present = 1;
1361         r.in.nt_cross = &hash5;
1362         r.in.cross2_present = 1;
1363         r.in.lm_cross = &hash6;
1364
1365         if (changed) {
1366                 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1367                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1368                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1369                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1370                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1371                         ret = false;
1372                 }
1373         }
1374
1375         
1376         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1377                 ret = false;
1378         }
1379
1380         return ret;
1381 }
1382
1383
1384 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1385                                         const char *acct_name,
1386                                         struct policy_handle *handle, char **password)
1387 {
1388         NTSTATUS status;
1389         struct samr_OemChangePasswordUser2 r;
1390         bool ret = true;
1391         struct samr_Password lm_verifier;
1392         struct samr_CryptPassword lm_pass;
1393         struct lsa_AsciiString server, account, account_bad;
1394         char *oldpass;
1395         char *newpass;
1396         uint8_t old_lm_hash[16], new_lm_hash[16];
1397
1398         struct samr_GetDomPwInfo dom_pw_info;
1399         int policy_min_pw_len = 0;
1400
1401         struct lsa_String domain_name;
1402
1403         domain_name.string = "";
1404         dom_pw_info.in.domain_name = &domain_name;
1405
1406         printf("Testing OemChangePasswordUser2\n");
1407
1408         if (!*password) {
1409                 printf("Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?\n");
1410                 return false;
1411         }
1412
1413         oldpass = *password;
1414
1415         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1416         if (NT_STATUS_IS_OK(status)) {
1417                 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1418         }
1419
1420         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1421
1422         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1423         account.string = acct_name;
1424
1425         E_deshash(oldpass, old_lm_hash);
1426         E_deshash(newpass, new_lm_hash);
1427
1428         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1429         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1430         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1431
1432         r.in.server = &server;
1433         r.in.account = &account;
1434         r.in.password = &lm_pass;
1435         r.in.hash = &lm_verifier;
1436
1437         /* Break the verification */
1438         lm_verifier.hash[0]++;
1439
1440         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1441
1442         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1443             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1444                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1445                         nt_errstr(status));
1446                 ret = false;
1447         }
1448
1449         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1450         /* Break the old password */
1451         old_lm_hash[0]++;
1452         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1453         /* unbreak it for the next operation */
1454         old_lm_hash[0]--;
1455         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1456
1457         r.in.server = &server;
1458         r.in.account = &account;
1459         r.in.password = &lm_pass;
1460         r.in.hash = &lm_verifier;
1461
1462         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1463
1464         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1465             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1466                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1467                         nt_errstr(status));
1468                 ret = false;
1469         }
1470
1471         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1472         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1473
1474         r.in.server = &server;
1475         r.in.account = &account;
1476         r.in.password = &lm_pass;
1477         r.in.hash = NULL;
1478
1479         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1480
1481         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1482             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1483                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1484                         nt_errstr(status));
1485                 ret = false;
1486         }
1487
1488         /* This shouldn't be a valid name */
1489         account_bad.string = TEST_ACCOUNT_NAME "XX";
1490         r.in.account = &account_bad;
1491
1492         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1493
1494         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1495                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1496                         nt_errstr(status));
1497                 ret = false;
1498         }
1499
1500         /* This shouldn't be a valid name */
1501         account_bad.string = TEST_ACCOUNT_NAME "XX";
1502         r.in.account = &account_bad;
1503         r.in.password = &lm_pass;
1504         r.in.hash = &lm_verifier;
1505
1506         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1507
1508         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1509                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1510                         nt_errstr(status));
1511                 ret = false;
1512         }
1513
1514         /* This shouldn't be a valid name */
1515         account_bad.string = TEST_ACCOUNT_NAME "XX";
1516         r.in.account = &account_bad;
1517         r.in.password = NULL;
1518         r.in.hash = &lm_verifier;
1519
1520         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1521
1522         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1523                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1524                         nt_errstr(status));
1525                 ret = false;
1526         }
1527
1528         E_deshash(oldpass, old_lm_hash);
1529         E_deshash(newpass, new_lm_hash);
1530
1531         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1532         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1533         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1534
1535         r.in.server = &server;
1536         r.in.account = &account;
1537         r.in.password = &lm_pass;
1538         r.in.hash = &lm_verifier;
1539
1540         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1541         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1542                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1543         } else if (!NT_STATUS_IS_OK(status)) {
1544                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1545                 ret = false;
1546         } else {
1547                 *password = newpass;
1548         }
1549
1550         return ret;
1551 }
1552
1553
1554 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1555                                      const char *acct_name,
1556                                      char **password,
1557                                      char *newpass, bool allow_password_restriction)
1558 {
1559         NTSTATUS status;
1560         struct samr_ChangePasswordUser2 r;
1561         bool ret = true;
1562         struct lsa_String server, account;
1563         struct samr_CryptPassword nt_pass, lm_pass;
1564         struct samr_Password nt_verifier, lm_verifier;
1565         char *oldpass;
1566         uint8_t old_nt_hash[16], new_nt_hash[16];
1567         uint8_t old_lm_hash[16], new_lm_hash[16];
1568
1569         struct samr_GetDomPwInfo dom_pw_info;
1570
1571         struct lsa_String domain_name;
1572
1573         domain_name.string = "";
1574         dom_pw_info.in.domain_name = &domain_name;
1575
1576         printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1577
1578         if (!*password) {
1579                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1580                 return false;
1581         }
1582         oldpass = *password;
1583
1584         if (!newpass) {
1585                 int policy_min_pw_len = 0;
1586                 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1587                 if (NT_STATUS_IS_OK(status)) {
1588                         policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1589                 }
1590
1591                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1592         } 
1593
1594         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1595         init_lsa_String(&account, acct_name);
1596
1597         E_md4hash(oldpass, old_nt_hash);
1598         E_md4hash(newpass, new_nt_hash);
1599
1600         E_deshash(oldpass, old_lm_hash);
1601         E_deshash(newpass, new_lm_hash);
1602
1603         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1604         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1605         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1606
1607         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1608         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1609         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1610
1611         r.in.server = &server;
1612         r.in.account = &account;
1613         r.in.nt_password = &nt_pass;
1614         r.in.nt_verifier = &nt_verifier;
1615         r.in.lm_change = 1;
1616         r.in.lm_password = &lm_pass;
1617         r.in.lm_verifier = &lm_verifier;
1618
1619         status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1620         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1621                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1622         } else if (!NT_STATUS_IS_OK(status)) {
1623                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1624                 ret = false;
1625         } else {
1626                 *password = newpass;
1627         }
1628
1629         return ret;
1630 }
1631
1632
1633 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1634                               const char *account_string,
1635                               int policy_min_pw_len,
1636                               char **password,
1637                               const char *newpass,
1638                               NTTIME last_password_change,
1639                               bool handle_reject_reason)
1640 {
1641         NTSTATUS status;
1642         struct samr_ChangePasswordUser3 r;
1643         bool ret = true;
1644         struct lsa_String server, account, account_bad;
1645         struct samr_CryptPassword nt_pass, lm_pass;
1646         struct samr_Password nt_verifier, lm_verifier;
1647         char *oldpass;
1648         uint8_t old_nt_hash[16], new_nt_hash[16];
1649         uint8_t old_lm_hash[16], new_lm_hash[16];
1650         NTTIME t;
1651
1652         printf("Testing ChangePasswordUser3\n");
1653
1654         if (newpass == NULL) {
1655                 do {
1656                         if (policy_min_pw_len == 0) {
1657                                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1658                         } else {
1659                                 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1660                         }
1661                 } while (check_password_quality(newpass) == false);
1662         } else {
1663                 printf("Using password '%s'\n", newpass);
1664         }
1665
1666         if (!*password) {
1667                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1668                 return false;
1669         }
1670
1671         oldpass = *password;
1672         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1673         init_lsa_String(&account, account_string);
1674
1675         E_md4hash(oldpass, old_nt_hash);
1676         E_md4hash(newpass, new_nt_hash);
1677
1678         E_deshash(oldpass, old_lm_hash);
1679         E_deshash(newpass, new_lm_hash);
1680
1681         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1682         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1683         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1684
1685         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1686         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1687         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1688         
1689         /* Break the verification */
1690         nt_verifier.hash[0]++;
1691
1692         r.in.server = &server;
1693         r.in.account = &account;
1694         r.in.nt_password = &nt_pass;
1695         r.in.nt_verifier = &nt_verifier;
1696         r.in.lm_change = 1;
1697         r.in.lm_password = &lm_pass;
1698         r.in.lm_verifier = &lm_verifier;
1699         r.in.password3 = NULL;
1700
1701         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1702         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1703             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1704                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1705                         nt_errstr(status));
1706                 ret = false;
1707         }
1708         
1709         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1710         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1711         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1712
1713         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1714         /* Break the NT hash */
1715         old_nt_hash[0]++;
1716         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1717         /* Unbreak it again */
1718         old_nt_hash[0]--;
1719         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1720         
1721         r.in.server = &server;
1722         r.in.account = &account;
1723         r.in.nt_password = &nt_pass;
1724         r.in.nt_verifier = &nt_verifier;
1725         r.in.lm_change = 1;
1726         r.in.lm_password = &lm_pass;
1727         r.in.lm_verifier = &lm_verifier;
1728         r.in.password3 = NULL;
1729
1730         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1731         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1732             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1733                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1734                         nt_errstr(status));
1735                 ret = false;
1736         }
1737         
1738         /* This shouldn't be a valid name */
1739         init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1740
1741         r.in.account = &account_bad;
1742         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1743         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1744                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1745                         nt_errstr(status));
1746                 ret = false;
1747         }
1748
1749         E_md4hash(oldpass, old_nt_hash);
1750         E_md4hash(newpass, new_nt_hash);
1751
1752         E_deshash(oldpass, old_lm_hash);
1753         E_deshash(newpass, new_lm_hash);
1754
1755         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1756         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1757         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1758
1759         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1760         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1761         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1762
1763         r.in.server = &server;
1764         r.in.account = &account;
1765         r.in.nt_password = &nt_pass;
1766         r.in.nt_verifier = &nt_verifier;
1767         r.in.lm_change = 1;
1768         r.in.lm_password = &lm_pass;
1769         r.in.lm_verifier = &lm_verifier;
1770         r.in.password3 = NULL;
1771
1772         unix_to_nt_time(&t, time(NULL));
1773
1774         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1775
1776         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1777             && r.out.dominfo
1778             && r.out.reject
1779             && handle_reject_reason
1780             && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1781                 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1782
1783                         if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1784                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1785                                         SAMR_REJECT_OTHER, r.out.reject->reason);
1786                                 return false;
1787                         }
1788                 }
1789
1790                 /* We tested the order of precendence which is as follows:
1791                 
1792                 * pwd min_age 
1793                 * pwd length
1794                 * pwd complexity
1795                 * pwd history
1796
1797                 Guenther */
1798
1799                 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) && 
1800                            (last_password_change + r.out.dominfo->min_password_age > t)) {
1801
1802                         if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1803                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1804                                         SAMR_REJECT_OTHER, r.out.reject->reason);
1805                                 return false;
1806                         }
1807
1808                 } else if ((r.out.dominfo->min_password_length > 0) && 
1809                            (strlen(newpass) < r.out.dominfo->min_password_length)) {
1810
1811                         if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1812                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
1813                                         SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1814                                 return false;
1815                         }
1816
1817                 } else if ((r.out.dominfo->password_history_length > 0) && 
1818                             strequal(oldpass, newpass)) {
1819
1820                         if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1821                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
1822                                         SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1823                                 return false;
1824                         }
1825                 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1826
1827                         if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1828                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
1829                                         SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1830                                 return false;
1831                         }
1832
1833                 }
1834
1835                 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1836                         /* retry with adjusted size */
1837                         return test_ChangePasswordUser3(p, mem_ctx, account_string, 
1838                                                         r.out.dominfo->min_password_length, 
1839                                                         password, NULL, 0, false); 
1840
1841                 }
1842
1843         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1844                 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1845                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1846                                SAMR_REJECT_OTHER, r.out.reject->reason);
1847                         return false;
1848                 }
1849                 /* Perhaps the server has a 'min password age' set? */
1850
1851         } else if (!NT_STATUS_IS_OK(status)) {
1852                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1853                 ret = false;
1854         } else {
1855                 *password = talloc_strdup(mem_ctx, newpass);
1856         }
1857
1858         return ret;
1859 }
1860
1861 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1862                                     const char *account_string,
1863                                     struct policy_handle *handle, 
1864                                     char **password)
1865 {
1866         NTSTATUS status;
1867         struct samr_ChangePasswordUser3 r;
1868         struct samr_SetUserInfo s;
1869         union samr_UserInfo u;
1870         DATA_BLOB session_key;
1871         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
1872         uint8_t confounder[16];
1873         struct MD5Context ctx;
1874
1875         bool ret = true;
1876         struct lsa_String server, account;
1877         struct samr_CryptPassword nt_pass;
1878         struct samr_Password nt_verifier;
1879         DATA_BLOB new_random_pass;
1880         char *newpass;
1881         char *oldpass;
1882         uint8_t old_nt_hash[16], new_nt_hash[16];
1883         NTTIME t;
1884
1885         new_random_pass = samr_very_rand_pass(mem_ctx, 128);
1886
1887         if (!*password) {
1888                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1889                 return false;
1890         }
1891
1892         oldpass = *password;
1893         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1894         init_lsa_String(&account, account_string);
1895
1896         s.in.user_handle = handle;
1897         s.in.info = &u;
1898         s.in.level = 25;
1899
1900         ZERO_STRUCT(u);
1901
1902         u.info25.info.fields_present = SAMR_FIELD_PASSWORD;
1903
1904         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
1905
1906         status = dcerpc_fetch_session_key(p, &session_key);
1907         if (!NT_STATUS_IS_OK(status)) {
1908                 printf("SetUserInfo level %u - no session key - %s\n",
1909                        s.in.level, nt_errstr(status));
1910                 return false;
1911         }
1912
1913         generate_random_buffer((uint8_t *)confounder, 16);
1914
1915         MD5Init(&ctx);
1916         MD5Update(&ctx, confounder, 16);
1917         MD5Update(&ctx, session_key.data, session_key.length);
1918         MD5Final(confounded_session_key.data, &ctx);
1919
1920         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1921         memcpy(&u.info25.password.data[516], confounder, 16);
1922
1923         printf("Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
1924
1925         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
1926         if (!NT_STATUS_IS_OK(status)) {
1927                 printf("SetUserInfo level %u failed - %s\n",
1928                        s.in.level, nt_errstr(status));
1929                 ret = false;
1930         }
1931
1932         printf("Testing ChangePasswordUser3 with a password made up of only random bytes\n");
1933
1934         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1935
1936         new_random_pass = samr_very_rand_pass(mem_ctx, 128);
1937
1938         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
1939
1940         set_pw_in_buffer(nt_pass.data, &new_random_pass);
1941         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1942         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1943
1944         r.in.server = &server;
1945         r.in.account = &account;
1946         r.in.nt_password = &nt_pass;
1947         r.in.nt_verifier = &nt_verifier;
1948         r.in.lm_change = 0;
1949         r.in.lm_password = NULL;
1950         r.in.lm_verifier = NULL;
1951         r.in.password3 = NULL;
1952
1953         unix_to_nt_time(&t, time(NULL));
1954
1955         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1956
1957         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1958                 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1959                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1960                                SAMR_REJECT_OTHER, r.out.reject->reason);
1961                         return false;
1962                 }
1963                 /* Perhaps the server has a 'min password age' set? */
1964
1965         } else if (!NT_STATUS_IS_OK(status)) {
1966                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1967                 ret = false;
1968         }
1969         
1970         newpass = samr_rand_pass(mem_ctx, 128);
1971
1972         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
1973
1974         E_md4hash(newpass, new_nt_hash);
1975
1976         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1977         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1978         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1979
1980         r.in.server = &server;
1981         r.in.account = &account;
1982         r.in.nt_password = &nt_pass;
1983         r.in.nt_verifier = &nt_verifier;
1984         r.in.lm_change = 0;
1985         r.in.lm_password = NULL;
1986         r.in.lm_verifier = NULL;
1987         r.in.password3 = NULL;
1988
1989         unix_to_nt_time(&t, time(NULL));
1990
1991         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1992
1993         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1994                 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1995                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1996                                SAMR_REJECT_OTHER, r.out.reject->reason);
1997                         return false;
1998                 }
1999                 /* Perhaps the server has a 'min password age' set? */
2000
2001         } else if (!NT_STATUS_IS_OK(status)) {
2002                 printf("ChangePasswordUser3 (on second random password) failed - %s\n", nt_errstr(status));
2003                 ret = false;
2004         } else {
2005                 *password = talloc_strdup(mem_ctx, newpass);
2006         }
2007
2008         return ret;
2009 }
2010
2011
2012 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2013                                   struct policy_handle *alias_handle)
2014 {
2015         struct samr_GetMembersInAlias r;
2016         struct lsa_SidArray sids;
2017         NTSTATUS status;
2018         bool     ret = true;
2019
2020         printf("Testing GetMembersInAlias\n");
2021
2022         r.in.alias_handle = alias_handle;
2023         r.out.sids = &sids;
2024
2025         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
2026         if (!NT_STATUS_IS_OK(status)) {
2027                 printf("GetMembersInAlias failed - %s\n",
2028                        nt_errstr(status));
2029                 ret = false;
2030         }
2031
2032         return ret;
2033 }
2034
2035 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2036                                   struct policy_handle *alias_handle,
2037                                   const struct dom_sid *domain_sid)
2038 {
2039         struct samr_AddAliasMember r;
2040         struct samr_DeleteAliasMember d;
2041         NTSTATUS status;
2042         bool ret = true;
2043         struct dom_sid *sid;
2044
2045         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
2046
2047         printf("testing AddAliasMember\n");
2048         r.in.alias_handle = alias_handle;
2049         r.in.sid = sid;
2050
2051         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
2052         if (!NT_STATUS_IS_OK(status)) {
2053                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
2054                 ret = false;
2055         }
2056
2057         d.in.alias_handle = alias_handle;
2058         d.in.sid = sid;
2059
2060         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
2061         if (!NT_STATUS_IS_OK(status)) {
2062                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
2063                 ret = false;
2064         }
2065
2066         return ret;
2067 }
2068
2069 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2070                                            struct policy_handle *alias_handle)
2071 {
2072         struct samr_AddMultipleMembersToAlias a;
2073         struct samr_RemoveMultipleMembersFromAlias r;
2074         NTSTATUS status;
2075         bool ret = true;
2076         struct lsa_SidArray sids;
2077
2078         printf("testing AddMultipleMembersToAlias\n");
2079         a.in.alias_handle = alias_handle;
2080         a.in.sids = &sids;
2081
2082         sids.num_sids = 3;
2083         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
2084
2085         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
2086         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
2087         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
2088
2089         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
2090         if (!NT_STATUS_IS_OK(status)) {
2091                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
2092                 ret = false;
2093         }
2094
2095
2096         printf("testing RemoveMultipleMembersFromAlias\n");
2097         r.in.alias_handle = alias_handle;
2098         r.in.sids = &sids;
2099
2100         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2101         if (!NT_STATUS_IS_OK(status)) {
2102                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2103                 ret = false;
2104         }
2105
2106         /* strange! removing twice doesn't give any error */
2107         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2108         if (!NT_STATUS_IS_OK(status)) {
2109                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2110                 ret = false;
2111         }
2112
2113         /* but removing an alias that isn't there does */
2114         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
2115
2116         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
2117         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
2118                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
2119                 ret = false;
2120         }
2121
2122         return ret;
2123 }
2124
2125 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2126                                             struct policy_handle *user_handle)
2127 {
2128         struct samr_TestPrivateFunctionsUser r;
2129         NTSTATUS status;
2130         bool ret = true;
2131
2132         printf("Testing TestPrivateFunctionsUser\n");
2133
2134         r.in.user_handle = user_handle;
2135
2136         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
2137         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2138                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
2139                 ret = false;
2140         }
2141
2142         return ret;
2143 }
2144
2145
2146 static bool test_user_ops(struct dcerpc_pipe *p, 
2147                           struct torture_context *tctx,
2148                           struct policy_handle *user_handle, 
2149                           struct policy_handle *domain_handle, 
2150                           uint32_t base_acct_flags, 
2151                           const char *base_acct_name, enum torture_samr_choice which_ops)
2152 {
2153         char *password = NULL;
2154         struct samr_QueryUserInfo q;
2155         NTSTATUS status;
2156
2157         bool ret = true;
2158         int i;
2159         uint32_t rid;
2160         const uint32_t password_fields[] = {
2161                 SAMR_FIELD_PASSWORD,
2162                 SAMR_FIELD_PASSWORD2,
2163                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
2164                 0
2165         };
2166         
2167         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2168         if (!NT_STATUS_IS_OK(status)) {
2169                 ret = false;
2170         }
2171
2172         switch (which_ops) {
2173         case TORTURE_SAMR_USER_ATTRIBUTES:
2174                 if (!test_QuerySecurity(p, tctx, user_handle)) {
2175                         ret = false;
2176                 }
2177
2178                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2179                         ret = false;
2180                 }
2181
2182                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2183                         ret = false;
2184                 }
2185
2186                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2187                                       base_acct_name)) {
2188                         ret = false;
2189                 }       
2190
2191                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2192                         ret = false;
2193                 }
2194
2195                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2196                         ret = false;
2197                 }
2198
2199                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2200                         ret = false;
2201                 }
2202                 break;
2203         case TORTURE_SAMR_PASSWORDS:
2204                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2205                         char simple_pass[9];
2206                         char *v = generate_random_str(tctx, 1);
2207                         
2208                         ZERO_STRUCT(simple_pass);
2209                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
2210
2211                         printf("Testing machine account password policy rules\n");
2212
2213                         /* Workstation trust accounts don't seem to need to honour password quality policy */
2214                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2215                                 ret = false;
2216                         }
2217
2218                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2219                                 ret = false;
2220                         }
2221
2222                         /* reset again, to allow another 'user' password change */
2223                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2224                                 ret = false;
2225                         }
2226
2227                         /* Try a 'short' password */
2228                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2229                                 ret = false;
2230                         }
2231
2232                         /* Try a compleatly random password */
2233                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
2234                                 ret = false;
2235                         }
2236                 }
2237                 
2238                 for (i = 0; password_fields[i]; i++) {
2239                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2240                                 ret = false;
2241                         }       
2242                 
2243                         /* check it was set right */
2244                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2245                                 ret = false;
2246                         }
2247                 }               
2248
2249                 for (i = 0; password_fields[i]; i++) {
2250                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2251                                 ret = false;
2252                         }       
2253                 
2254                         /* check it was set right */
2255                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2256                                 ret = false;
2257                         }
2258                 }               
2259
2260                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2261                         ret = false;
2262                 }       
2263
2264                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2265                         ret = false;
2266                 }       
2267
2268                 q.in.user_handle = user_handle;
2269                 q.in.level = 5;
2270                 
2271                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2272                 if (!NT_STATUS_IS_OK(status)) {
2273                         printf("QueryUserInfo level %u failed - %s\n", 
2274                                q.in.level, nt_errstr(status));
2275                         ret = false;
2276                 } else {
2277                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2278                         if ((q.out.info->info5.acct_flags) != expected_flags) {
2279                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2280                                        q.out.info->info5.acct_flags, 
2281                                        expected_flags);
2282                                 ret = false;
2283                         }
2284                         if (q.out.info->info5.rid != rid) {
2285                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2286                                        q.out.info->info5.rid, rid);
2287
2288                         }
2289                 }
2290
2291                 break;
2292         case TORTURE_SAMR_OTHER:
2293                 /* We just need the account to exist */
2294                 break;
2295         }
2296         return ret;
2297 }
2298
2299 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2300                            struct policy_handle *alias_handle,
2301                            const struct dom_sid *domain_sid)
2302 {
2303         bool ret = true;
2304
2305         if (!test_QuerySecurity(p, tctx, alias_handle)) {
2306                 ret = false;
2307         }
2308
2309         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2310                 ret = false;
2311         }
2312
2313         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2314                 ret = false;
2315         }
2316
2317         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2318                 ret = false;
2319         }
2320
2321         if (torture_setting_bool(tctx, "samba4", false)) {
2322                 printf("skipping MultipleMembers Alias tests against Samba4\n");
2323                 return ret;
2324         }
2325
2326         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2327                 ret = false;
2328         }
2329
2330         return ret;
2331 }
2332
2333
2334 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2335                                      struct policy_handle *user_handle)
2336 {
2337         struct samr_DeleteUser d;
2338         NTSTATUS status;
2339         bool ret = true;
2340         printf("Testing DeleteUser\n");
2341
2342         d.in.user_handle = user_handle;
2343         d.out.user_handle = user_handle;
2344
2345         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2346         if (!NT_STATUS_IS_OK(status)) {
2347                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2348                 ret = false;
2349         }
2350
2351         return ret;
2352 }
2353
2354 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2355                             struct policy_handle *handle, const char *name)
2356 {
2357         NTSTATUS status;
2358         struct samr_DeleteUser d;
2359         struct policy_handle user_handle;
2360         uint32_t rid;
2361
2362         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2363         if (!NT_STATUS_IS_OK(status)) {
2364                 goto failed;
2365         }
2366
2367         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2368         if (!NT_STATUS_IS_OK(status)) {
2369                 goto failed;
2370         }
2371
2372         d.in.user_handle = &user_handle;
2373         d.out.user_handle = &user_handle;
2374         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2375         if (!NT_STATUS_IS_OK(status)) {
2376                 goto failed;
2377         }
2378
2379         return true;
2380
2381 failed:
2382         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2383         return false;
2384 }
2385
2386
2387 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2388                                     struct policy_handle *handle, const char *name)
2389 {
2390         NTSTATUS status;
2391         struct samr_OpenGroup r;
2392         struct samr_DeleteDomainGroup d;
2393         struct policy_handle group_handle;
2394         uint32_t rid;
2395
2396         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2397         if (!NT_STATUS_IS_OK(status)) {
2398                 goto failed;
2399         }
2400
2401         r.in.domain_handle = handle;
2402         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2403         r.in.rid = rid;
2404         r.out.group_handle = &group_handle;
2405         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2406         if (!NT_STATUS_IS_OK(status)) {
2407                 goto failed;
2408         }
2409
2410         d.in.group_handle = &group_handle;
2411         d.out.group_handle = &group_handle;
2412         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2413         if (!NT_STATUS_IS_OK(status)) {
2414                 goto failed;
2415         }
2416
2417         return true;
2418
2419 failed:
2420         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2421         return false;
2422 }
2423
2424
2425 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2426                                    struct policy_handle *domain_handle, const char *name)
2427 {
2428         NTSTATUS status;
2429         struct samr_OpenAlias r;
2430         struct samr_DeleteDomAlias d;
2431         struct policy_handle alias_handle;
2432         uint32_t rid;
2433
2434         printf("testing DeleteAlias_byname\n");
2435
2436         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2437         if (!NT_STATUS_IS_OK(status)) {
2438                 goto failed;
2439         }
2440
2441         r.in.domain_handle = domain_handle;
2442         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2443         r.in.rid = rid;
2444         r.out.alias_handle = &alias_handle;
2445         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2446         if (!NT_STATUS_IS_OK(status)) {
2447                 goto failed;
2448         }
2449
2450         d.in.alias_handle = &alias_handle;
2451         d.out.alias_handle = &alias_handle;
2452         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2453         if (!NT_STATUS_IS_OK(status)) {
2454                 goto failed;
2455         }
2456
2457         return true;
2458
2459 failed:
2460         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2461         return false;
2462 }
2463
2464 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2465                                      struct policy_handle *alias_handle)
2466 {
2467         struct samr_DeleteDomAlias d;
2468         NTSTATUS status;
2469         bool ret = true;
2470         printf("Testing DeleteAlias\n");
2471
2472         d.in.alias_handle = alias_handle;
2473         d.out.alias_handle = alias_handle;
2474
2475         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2476         if (!NT_STATUS_IS_OK(status)) {
2477                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2478                 ret = false;
2479         }
2480
2481         return ret;
2482 }
2483
2484 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2485                             struct policy_handle *domain_handle, 
2486                              struct policy_handle *alias_handle, 
2487                              const struct dom_sid *domain_sid)
2488 {
2489         NTSTATUS status;
2490         struct samr_CreateDomAlias r;
2491         struct lsa_String name;
2492         uint32_t rid;
2493         bool ret = true;
2494
2495         init_lsa_String(&name, TEST_ALIASNAME);
2496         r.in.domain_handle = domain_handle;
2497         r.in.alias_name = &name;
2498         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2499         r.out.alias_handle = alias_handle;
2500         r.out.rid = &rid;
2501
2502         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2503
2504         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2505
2506         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2507                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2508                         printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
2509                         return true;
2510                 } else {
2511                         printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string, 
2512                                nt_errstr(status));
2513                         return false;
2514                 }
2515         }
2516
2517         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2518                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2519                         return false;
2520                 }
2521                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2522         }
2523
2524         if (!NT_STATUS_IS_OK(status)) {
2525                 printf("CreateAlias failed - %s\n", nt_errstr(status));
2526                 return false;
2527         }
2528
2529         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2530                 ret = false;
2531         }
2532
2533         return ret;
2534 }
2535
2536 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2537                                 const char *acct_name,
2538                                 struct policy_handle *domain_handle, char **password)
2539 {
2540         bool ret = true;
2541
2542         if (!*password) {
2543                 return false;
2544         }
2545
2546         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2547                 ret = false;
2548         }
2549
2550         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2551                 ret = false;
2552         }
2553
2554         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2555                 ret = false;
2556         }
2557
2558         /* test what happens when setting the old password again */
2559         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2560                 ret = false;
2561         }
2562
2563         {
2564                 char simple_pass[9];
2565                 char *v = generate_random_str(mem_ctx, 1);
2566
2567                 ZERO_STRUCT(simple_pass);
2568                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2569
2570                 /* test what happens when picking a simple password */
2571                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2572                         ret = false;
2573                 }
2574         }
2575
2576         /* set samr_SetDomainInfo level 1 with min_length 5 */
2577         {
2578                 struct samr_QueryDomainInfo r;
2579                 struct samr_SetDomainInfo s;
2580                 uint16_t len_old, len;
2581                 uint32_t pwd_prop_old;
2582                 int64_t min_pwd_age_old;
2583                 NTSTATUS status;
2584
2585                 len = 5;
2586
2587                 r.in.domain_handle = domain_handle;
2588                 r.in.level = 1;
2589
2590                 printf("testing samr_QueryDomainInfo level 1\n");
2591                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2592                 if (!NT_STATUS_IS_OK(status)) {
2593                         return false;
2594                 }
2595
2596                 s.in.domain_handle = domain_handle;
2597                 s.in.level = 1;
2598                 s.in.info = r.out.info;
2599
2600                 /* remember the old min length, so we can reset it */
2601                 len_old = s.in.info->info1.min_password_length;
2602                 s.in.info->info1.min_password_length = len;
2603                 pwd_prop_old = s.in.info->info1.password_properties;
2604                 /* turn off password complexity checks for this test */
2605                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2606
2607                 min_pwd_age_old = s.in.info->info1.min_password_age;
2608                 s.in.info->info1.min_password_age = 0;
2609
2610                 printf("testing samr_SetDomainInfo level 1\n");
2611                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2612                 if (!NT_STATUS_IS_OK(status)) {
2613                         return false;
2614                 }
2615
2616                 printf("calling test_ChangePasswordUser3 with too short password\n");
2617
2618                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2619                         ret = false;
2620                 }
2621
2622                 s.in.info->info1.min_password_length = len_old;
2623                 s.in.info->info1.password_properties = pwd_prop_old;
2624                 s.in.info->info1.min_password_age = min_pwd_age_old;
2625                 
2626                 printf("testing samr_SetDomainInfo level 1\n");
2627                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2628                 if (!NT_STATUS_IS_OK(status)) {
2629                         return false;
2630                 }
2631
2632         }
2633
2634         {
2635                 NTSTATUS status;
2636                 struct samr_OpenUser r;
2637                 struct samr_QueryUserInfo q;
2638                 struct samr_LookupNames n;
2639                 struct policy_handle user_handle;
2640
2641                 n.in.domain_handle = domain_handle;
2642                 n.in.num_names = 1;
2643                 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2644                 n.in.names[0].string = acct_name; 
2645
2646                 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2647                 if (!NT_STATUS_IS_OK(status)) {
2648                         printf("LookupNames failed - %s\n", nt_errstr(status));
2649                         return false;
2650                 }
2651
2652                 r.in.domain_handle = domain_handle;
2653                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2654                 r.in.rid = n.out.rids.ids[0];
2655                 r.out.user_handle = &user_handle;
2656
2657                 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2658                 if (!NT_STATUS_IS_OK(status)) {
2659                         printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2660                         return false;
2661                 }
2662
2663                 q.in.user_handle = &user_handle;
2664                 q.in.level = 5;
2665
2666                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2667                 if (!NT_STATUS_IS_OK(status)) {
2668                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2669                         return false;
2670                 }
2671
2672                 printf("calling test_ChangePasswordUser3 with too early password change\n");
2673
2674                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
2675                                               q.out.info->info5.last_password_change, true)) {
2676                         ret = false;
2677                 }
2678         }
2679
2680         /* we change passwords twice - this has the effect of verifying
2681            they were changed correctly for the final call */
2682         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2683                 ret = false;
2684         }
2685
2686         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2687                 ret = false;
2688         }
2689
2690         return ret;
2691 }
2692
2693 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2694                             struct policy_handle *domain_handle, 
2695                             struct policy_handle *user_handle_out,
2696                             struct dom_sid *domain_sid, 
2697                             enum torture_samr_choice which_ops)
2698 {
2699
2700         TALLOC_CTX *user_ctx;
2701
2702         NTSTATUS status;
2703         struct samr_CreateUser r;
2704         struct samr_QueryUserInfo q;
2705         struct samr_DeleteUser d;
2706         uint32_t rid;
2707
2708         /* This call creates a 'normal' account - check that it really does */
2709         const uint32_t acct_flags = ACB_NORMAL;
2710         struct lsa_String name;
2711         bool ret = true;
2712
2713         struct policy_handle user_handle;
2714         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2715         init_lsa_String(&name, TEST_ACCOUNT_NAME);
2716
2717         r.in.domain_handle = domain_handle;
2718         r.in.account_name = &name;
2719         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2720         r.out.user_handle = &user_handle;
2721         r.out.rid = &rid;
2722
2723         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2724
2725         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2726
2727         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2728                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2729                         printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2730                         return true;
2731                 } else {
2732                         printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
2733                                nt_errstr(status));
2734                         return false;
2735                 }
2736         }
2737
2738         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2739                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2740                         talloc_free(user_ctx);
2741                         return false;
2742                 }
2743                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2744         }
2745         if (!NT_STATUS_IS_OK(status)) {
2746                 talloc_free(user_ctx);
2747                 printf("CreateUser failed - %s\n", nt_errstr(status));
2748                 return false;
2749         } else {
2750                 q.in.user_handle = &user_handle;
2751                 q.in.level = 16;
2752                 
2753                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2754                 if (!NT_STATUS_IS_OK(status)) {
2755                         printf("QueryUserInfo level %u failed - %s\n", 
2756                                q.in.level, nt_errstr(status));
2757                         ret = false;
2758                 } else {
2759                         if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2760                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2761                                        q.out.info->info16.acct_flags, 
2762                                        acct_flags);
2763                                 ret = false;
2764                         }
2765                 }
2766                 
2767                 if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
2768                                    acct_flags, name.string, which_ops)) {
2769                         ret = false;
2770                 }
2771                 
2772                 if (user_handle_out) {
2773                         *user_handle_out = user_handle;
2774                 } else {
2775                         printf("Testing DeleteUser (createuser test)\n");
2776                         
2777                         d.in.user_handle = &user_handle;
2778                         d.out.user_handle = &user_handle;
2779                         
2780                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2781                         if (!NT_STATUS_IS_OK(status)) {
2782                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2783                                 ret = false;
2784                         }
2785                 }
2786                 
2787         }
2788
2789         talloc_free(user_ctx);
2790         
2791         return ret;
2792 }
2793
2794
2795 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2796                              struct policy_handle *domain_handle,
2797                              struct dom_sid *domain_sid,
2798                              enum torture_samr_choice which_ops)
2799 {
2800         NTSTATUS status;
2801         struct samr_CreateUser2 r;
2802         struct samr_QueryUserInfo q;
2803         struct samr_DeleteUser d;
2804         struct policy_handle user_handle;
2805         uint32_t rid;
2806         struct lsa_String name;
2807         bool ret = true;
2808         int i;
2809
2810         struct {
2811                 uint32_t acct_flags;
2812                 const char *account_name;
2813                 NTSTATUS nt_status;
2814         } account_types[] = {
2815                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2816                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2817                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2818                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2819                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2820                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2821                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2822                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2823                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2824                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2825                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2826                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2827                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2828                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2829                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2830         };
2831
2832         for (i = 0; account_types[i].account_name; i++) {
2833                 TALLOC_CTX *user_ctx;
2834                 uint32_t acct_flags = account_types[i].acct_flags;
2835                 uint32_t access_granted;
2836                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2837                 init_lsa_String(&name, account_types[i].account_name);
2838
2839                 r.in.domain_handle = domain_handle;
2840                 r.in.account_name = &name;
2841                 r.in.acct_flags = acct_flags;
2842                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2843                 r.out.user_handle = &user_handle;
2844                 r.out.access_granted = &access_granted;
2845                 r.out.rid = &rid;
2846                 
2847                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2848                 
2849                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2850                 
2851                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
2852                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2853                                 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
2854                                 continue;
2855                         } else {
2856                                 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
2857                                        nt_errstr(status));
2858                                 ret = false;
2859                                 continue;
2860                         }
2861                 }
2862
2863                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2864                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2865                                 talloc_free(user_ctx);
2866                                 ret = false;
2867                                 continue;
2868                         }
2869                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2870
2871                 }
2872                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2873                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
2874                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
2875                         ret = false;
2876                 }
2877                 
2878                 if (NT_STATUS_IS_OK(status)) {
2879                         q.in.user_handle = &user_handle;
2880                         q.in.level = 5;
2881                         
2882                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2883                         if (!NT_STATUS_IS_OK(status)) {
2884                                 printf("QueryUserInfo level %u failed - %s\n", 
2885                                        q.in.level, nt_errstr(status));
2886                                 ret = false;
2887                         } else {
2888                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2889                                 if (acct_flags == ACB_NORMAL) {
2890                                         expected_flags |= ACB_PW_EXPIRED;
2891                                 }
2892                                 if ((q.out.info->info5.acct_flags) != expected_flags) {
2893                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2894                                                q.out.info->info5.acct_flags, 
2895                                                expected_flags);
2896                                         ret = false;
2897                                 } 
2898                                 switch (acct_flags) {
2899                                 case ACB_SVRTRUST:
2900                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2901                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", 
2902                                                        DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2903                                                 ret = false;
2904                                         }
2905                                         break;
2906                                 case ACB_WSTRUST:
2907                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2908                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", 
2909                                                        DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2910                                                 ret = false;
2911                                         }
2912                                         break;
2913                                 case ACB_NORMAL:
2914                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2915                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", 
2916                                                        DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2917                                                 ret = false;
2918                                         }
2919                                         break;
2920                                 }
2921                         }
2922                 
2923                         if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
2924                                            acct_flags, name.string, which_ops)) {
2925                                 ret = false;
2926                         }
2927
2928                         printf("Testing DeleteUser (createuser2 test)\n");
2929                 
2930                         d.in.user_handle = &user_handle;
2931                         d.out.user_handle = &user_handle;
2932                         
2933                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2934                         if (!NT_STATUS_IS_OK(status)) {
2935                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2936                                 ret = false;
2937                         }
2938                 }
2939                 talloc_free(user_ctx);
2940         }
2941
2942         return ret;
2943 }
2944
2945 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2946                                 struct policy_handle *handle)
2947 {
2948         NTSTATUS status;
2949         struct samr_QueryAliasInfo r;
2950         uint16_t levels[] = {1, 2, 3};
2951         int i;
2952         bool ret = true;
2953
2954         for (i=0;i<ARRAY_SIZE(levels);i++) {
2955                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2956
2957                 r.in.alias_handle = handle;
2958                 r.in.level = levels[i];
2959
2960                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2961                 if (!NT_STATUS_IS_OK(status)) {
2962                         printf("QueryAliasInfo level %u failed - %s\n", 
2963                                levels[i], nt_errstr(status));
2964                         ret = false;
2965                 }
2966         }
2967
2968         return ret;
2969 }
2970
2971 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2972                                 struct policy_handle *handle)
2973 {
2974         NTSTATUS status;
2975         struct samr_QueryGroupInfo r;
2976         uint16_t levels[] = {1, 2, 3, 4, 5};
2977         int i;
2978         bool ret = true;
2979
2980         for (i=0;i<ARRAY_SIZE(levels);i++) {
2981                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2982
2983                 r.in.group_handle = handle;
2984                 r.in.level = levels[i];
2985
2986                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2987                 if (!NT_STATUS_IS_OK(status)) {
2988                         printf("QueryGroupInfo level %u failed - %s\n", 
2989                                levels[i], nt_errstr(status));
2990                         ret = false;
2991                 }
2992         }
2993
2994         return ret;
2995 }
2996
2997 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2998                                   struct policy_handle *handle)
2999 {
3000         NTSTATUS status;
3001         struct samr_QueryGroupMember r;
3002         bool ret = true;
3003
3004         printf("Testing QueryGroupMember\n");
3005
3006         r.in.group_handle = handle;
3007
3008         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
3009         if (!NT_STATUS_IS_OK(status)) {
3010                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
3011                 ret = false;
3012         }
3013
3014         return ret;
3015 }
3016
3017
3018 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3019                               struct policy_handle *handle)
3020 {
3021         NTSTATUS status;
3022         struct samr_QueryGroupInfo r;
3023         struct samr_SetGroupInfo s;
3024         uint16_t levels[] = {1, 2, 3, 4};
3025         uint16_t set_ok[] = {0, 1, 1, 1};
3026         int i;
3027         bool ret = true;
3028
3029         for (i=0;i<ARRAY_SIZE(levels);i++) {
3030                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
3031
3032                 r.in.group_handle = handle;
3033                 r.in.level = levels[i];
3034
3035                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
3036                 if (!NT_STATUS_IS_OK(status)) {
3037                         printf("QueryGroupInfo level %u failed - %s\n", 
3038                                levels[i], nt_errstr(status));
3039                         ret = false;
3040                 }
3041
3042                 printf("Testing SetGroupInfo level %u\n", levels[i]);
3043
3044                 s.in.group_handle = handle;
3045                 s.in.level = levels[i];
3046                 s.in.info = r.out.info;
3047
3048 #if 0
3049                 /* disabled this, as it changes the name only from the point of view of samr, 
3050                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
3051                    the name is still reserved, so creating the old name fails, but deleting by the old name
3052                    also fails */
3053                 if (s.in.level == 2) {
3054                         init_lsa_String(&s.in.info->string, "NewName");
3055                 }
3056 #endif
3057
3058                 if (s.in.level == 4) {
3059                         init_lsa_String(&s.in.info->description, "test description");
3060                 }
3061
3062                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
3063                 if (set_ok[i]) {
3064                         if (!NT_STATUS_IS_OK(status)) {
3065                                 printf("SetGroupInfo level %u failed - %s\n", 
3066                                        r.in.level, nt_errstr(status));
3067                                 ret = false;
3068                                 continue;
3069                         }
3070                 } else {
3071                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3072                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
3073                                        r.in.level, nt_errstr(status));
3074                                 ret = false;
3075                                 continue;
3076                         }
3077                 }
3078         }
3079
3080         return ret;
3081 }
3082
3083 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3084                                struct policy_handle *handle)
3085 {
3086         NTSTATUS status;
3087         struct samr_QueryUserInfo r;
3088         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3089                            11, 12, 13, 14, 16, 17, 20, 21};
3090         int i;
3091         bool ret = true;
3092
3093         for (i=0;i<ARRAY_SIZE(levels);i++) {
3094                 printf("Testing QueryUserInfo level %u\n", levels[i]);
3095
3096                 r.in.user_handle = handle;
3097                 r.in.level = levels[i];
3098
3099                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
3100                 if (!NT_STATUS_IS_OK(status)) {
3101                         printf("QueryUserInfo level %u failed - %s\n", 
3102                                levels[i], nt_errstr(status));
3103                         ret = false;
3104                 }
3105         }
3106
3107         return ret;
3108 }
3109
3110 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3111                                 struct policy_handle *handle)
3112 {
3113         NTSTATUS status;
3114         struct samr_QueryUserInfo2 r;
3115         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
3116                            11, 12, 13, 14, 16, 17, 20, 21};
3117         int i;
3118         bool ret = true;
3119
3120         for (i=0;i<ARRAY_SIZE(levels);i++) {
3121                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
3122
3123                 r.in.user_handle = handle;
3124                 r.in.level = levels[i];
3125
3126                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
3127                 if (!NT_STATUS_IS_OK(status)) {
3128                         printf("QueryUserInfo2 level %u failed - %s\n", 
3129                                levels[i], nt_errstr(status));
3130                         ret = false;
3131                 }
3132         }
3133
3134         return ret;
3135 }
3136
3137 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3138                           struct policy_handle *handle, uint32_t rid)
3139 {
3140         NTSTATUS status;
3141         struct samr_OpenUser r;
3142         struct policy_handle user_handle;
3143         bool ret = true;
3144
3145         printf("Testing OpenUser(%u)\n", rid);
3146
3147         r.in.domain_handle = handle;
3148         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3149         r.in.rid = rid;
3150         r.out.user_handle = &user_handle;
3151
3152         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3153         if (!NT_STATUS_IS_OK(status)) {
3154                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3155                 return false;
3156         }
3157
3158         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
3159                 ret = false;
3160         }
3161
3162         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
3163                 ret = false;
3164         }
3165
3166         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
3167                 ret = false;
3168         }
3169
3170         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
3171                 ret = false;
3172         }
3173
3174         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
3175                 ret = false;
3176         }
3177
3178         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3179                 ret = false;
3180         }
3181
3182         return ret;
3183 }
3184
3185 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3186                            struct policy_handle *handle, uint32_t rid)
3187 {
3188         NTSTATUS status;
3189         struct samr_OpenGroup r;
3190         struct policy_handle group_handle;
3191         bool ret = true;
3192
3193         printf("Testing OpenGroup(%u)\n", rid);
3194
3195         r.in.domain_handle = handle;
3196         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3197         r.in.rid = rid;
3198         r.out.group_handle = &group_handle;
3199
3200         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3201         if (!NT_STATUS_IS_OK(status)) {
3202                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3203                 return false;
3204         }
3205
3206         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3207                 ret = false;
3208         }
3209
3210         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3211                 ret = false;
3212         }
3213
3214         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3215                 ret = false;
3216         }
3217
3218         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3219                 ret = false;
3220         }
3221
3222         return ret;
3223 }
3224
3225 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3226                            struct policy_handle *handle, uint32_t rid)
3227 {
3228         NTSTATUS status;
3229         struct samr_OpenAlias r;
3230         struct policy_handle alias_handle;
3231         bool ret = true;
3232
3233         printf("Testing OpenAlias(%u)\n", rid);
3234
3235         r.in.domain_handle = handle;
3236         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3237         r.in.rid = rid;
3238         r.out.alias_handle = &alias_handle;
3239
3240         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3241         if (!NT_STATUS_IS_OK(status)) {
3242                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3243                 return false;
3244         }
3245
3246         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3247                 ret = false;
3248         }
3249
3250         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3251                 ret = false;
3252         }
3253
3254         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3255                 ret = false;
3256         }
3257
3258         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3259                 ret = false;
3260         }
3261
3262         return ret;
3263 }
3264
3265 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3266                        struct policy_handle *handle, uint32_t rid, 
3267                        uint32_t acct_flag_mask)
3268 {
3269         NTSTATUS status;
3270         struct samr_OpenUser r;
3271         struct samr_QueryUserInfo q;
3272         struct policy_handle user_handle;
3273         bool ret = true;
3274
3275         printf("Testing OpenUser(%u)\n", rid);
3276
3277         r.in.domain_handle = handle;
3278         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3279         r.in.rid = rid;
3280         r.out.user_handle = &user_handle;
3281
3282         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3283         if (!NT_STATUS_IS_OK(status)) {
3284                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3285                 return false;
3286         }
3287
3288         q.in.user_handle = &user_handle;
3289         q.in.level = 16;
3290         
3291         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3292         if (!NT_STATUS_IS_OK(status)) {
3293                 printf("QueryUserInfo level 16 failed - %s\n", 
3294                        nt_errstr(status));
3295                 ret = false;
3296         } else {
3297                 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3298                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3299                                acct_flag_mask, q.out.info->info16.acct_flags, rid);
3300                         ret = false;
3301                 }
3302         }
3303         
3304         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3305                 ret = false;
3306         }
3307
3308         return ret;
3309 }
3310
3311 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3312                                  struct policy_handle *handle)
3313 {
3314         NTSTATUS status = STATUS_MORE_ENTRIES;
3315         struct samr_EnumDomainUsers r;
3316         uint32_t mask, resume_handle=0;
3317         int i, mask_idx;
3318         bool ret = true;
3319         struct samr_LookupNames n;
3320         struct samr_LookupRids  lr ;
3321         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
3322                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
3323                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
3324                             ACB_PWNOEXP, 0};
3325
3326         printf("Testing EnumDomainUsers\n");
3327
3328         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3329                 r.in.domain_handle = handle;
3330                 r.in.resume_handle = &resume_handle;
3331                 r.in.acct_flags = mask = masks[mask_idx];
3332                 r.in.max_size = (uint32_t)-1;
3333                 r.out.resume_handle = &resume_handle;
3334
3335                 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3336                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
3337                     !NT_STATUS_IS_OK(status)) {
3338                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3339                         return false;
3340                 }
3341         
3342                 if (!r.out.sam) {
3343                         printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3344                         return false;
3345                 }
3346
3347                 if (r.out.sam->count == 0) {
3348                         continue;
3349                 }
3350
3351                 for (i=0;i<r.out.sam->count;i++) {
3352                         if (mask) {
3353                                 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3354                                         ret = false;
3355                                 }
3356                         } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3357                                 ret = false;
3358                         }
3359                 }
3360         }
3361
3362         printf("Testing LookupNames\n");
3363         n.in.domain_handle = handle;
3364         n.in.num_names = r.out.sam->count;
3365         n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3366         for (i=0;i<r.out.sam->count;i++) {
3367                 n.in.names[i].string = r.out.sam->entries[i].name.string;
3368         }
3369         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3370         if (!NT_STATUS_IS_OK(status)) {
3371                 printf("LookupNames failed - %s\n", nt_errstr(status));
3372                 ret = false;
3373         }
3374
3375
3376         printf("Testing LookupRids\n");
3377         lr.in.domain_handle = handle;
3378         lr.in.num_rids = r.out.sam->count;
3379         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3380         for (i=0;i<r.out.sam->count;i++) {
3381                 lr.in.rids[i] = r.out.sam->entries[i].idx;
3382         }
3383         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3384         if (!NT_STATUS_IS_OK(status)) {
3385                 printf("LookupRids failed - %s\n", nt_errstr(status));
3386                 ret = false;
3387         }
3388
3389         return ret;     
3390 }
3391
3392 /*
3393   try blasting the server with a bunch of sync requests
3394 */
3395 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx, 
3396                                        struct policy_handle *handle)
3397 {
3398         NTSTATUS status;
3399         struct samr_EnumDomainUsers r;
3400         uint32_t resume_handle=0;
3401         int i;
3402 #define ASYNC_COUNT 100
3403         struct rpc_request *req[ASYNC_COUNT];
3404
3405         if (!torture_setting_bool(tctx, "dangerous", false)) {
3406                 printf("samr async test disabled - enable dangerous tests to use\n");
3407                 return true;
3408         }
3409
3410         printf("Testing EnumDomainUsers_async\n");
3411
3412         r.in.domain_handle = handle;
3413         r.in.resume_handle = &resume_handle;
3414         r.in.acct_flags = 0;
3415         r.in.max_size = (uint32_t)-1;
3416         r.out.resume_handle = &resume_handle;
3417
3418         for (i=0;i<ASYNC_COUNT;i++) {
3419                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3420         }
3421
3422         for (i=0;i<ASYNC_COUNT;i++) {
3423                 status = dcerpc_ndr_request_recv(req[i]);
3424                 if (!NT_STATUS_IS_OK(status)) {
3425                         printf("EnumDomainUsers[%d] failed - %s\n", 
3426                                i, nt_errstr(status));
3427                         return false;
3428                 }
3429         }
3430         
3431         printf("%d async requests OK\n", i);
3432
3433         return true;
3434 }
3435
3436 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3437                                   struct policy_handle *handle)
3438 {
3439         NTSTATUS status;
3440         struct samr_EnumDomainGroups r;
3441         uint32_t resume_handle=0;
3442         int i;
3443         bool ret = true;
3444
3445         printf("Testing EnumDomainGroups\n");
3446
3447         r.in.domain_handle = handle;
3448         r.in.resume_handle = &resume_handle;
3449         r.in.max_size = (uint32_t)-1;
3450         r.out.resume_handle = &resume_handle;
3451
3452         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3453         if (!NT_STATUS_IS_OK(status)) {
3454                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3455                 return false;
3456         }
3457         
3458         if (!r.out.sam) {
3459                 return false;
3460         }
3461
3462         for (i=0;i<r.out.sam->count;i++) {
3463                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3464                         ret = false;
3465                 }
3466         }
3467
3468         return ret;
3469 }
3470
3471 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3472                                    struct policy_handle *handle)
3473 {
3474         NTSTATUS status;
3475         struct samr_EnumDomainAliases r;
3476         uint32_t resume_handle=0;
3477         int i;
3478         bool ret = true;
3479
3480         printf("Testing EnumDomainAliases\n");
3481
3482         r.in.domain_handle = handle;
3483         r.in.resume_handle = &resume_handle;
3484         r.in.acct_flags = (uint32_t)-1;
3485         r.out.resume_handle = &resume_handle;
3486
3487         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3488         if (!NT_STATUS_IS_OK(status)) {
3489                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3490                 return false;
3491         }
3492         
3493         if (!r.out.sam) {
3494                 return false;
3495         }
3496
3497         for (i=0;i<r.out.sam->count;i++) {
3498                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3499                         ret = false;
3500                 }
3501         }
3502
3503         return ret;     
3504 }
3505
3506 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3507                                             struct policy_handle *handle)
3508 {
3509         NTSTATUS status;
3510         struct samr_GetDisplayEnumerationIndex r;
3511         bool ret = true;
3512         uint16_t levels[] = {1, 2, 3, 4, 5};
3513         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3514         int i;
3515
3516         for (i=0;i<ARRAY_SIZE(levels);i++) {
3517                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3518
3519                 r.in.domain_handle = handle;
3520                 r.in.level = levels[i];
3521                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3522
3523                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3524
3525                 if (ok_lvl[i] && 
3526                     !NT_STATUS_IS_OK(status) &&
3527                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3528                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3529                                levels[i], nt_errstr(status));
3530                         ret = false;
3531                 }
3532
3533                 init_lsa_String(&r.in.name, "zzzzzzzz");
3534
3535                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3536                 
3537                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3538                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3539                                levels[i], nt_errstr(status));
3540                         ret = false;
3541                 }
3542         }
3543         
3544         return ret;     
3545 }
3546
3547 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3548                                              struct policy_handle *handle)
3549 {
3550         NTSTATUS status;
3551         struct samr_GetDisplayEnumerationIndex2 r;
3552         bool ret = true;
3553         uint16_t levels[] = {1, 2, 3, 4, 5};
3554         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3555         int i;
3556
3557         for (i=0;i<ARRAY_SIZE(levels);i++) {
3558                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3559
3560                 r.in.domain_handle = handle;
3561                 r.in.level = levels[i];
3562                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3563
3564                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3565                 if (ok_lvl[i] && 
3566                     !NT_STATUS_IS_OK(status) && 
3567                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3568                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3569                                levels[i], nt_errstr(status));
3570                         ret = false;
3571                 }
3572
3573                 init_lsa_String(&r.in.name, "zzzzzzzz");
3574
3575                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3576                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3577                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3578                                levels[i], nt_errstr(status));
3579                         ret = false;
3580                 }
3581         }
3582         
3583         return ret;     
3584 }
3585
3586 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
3587         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3588                 /* odd, but valid */                                            \
3589         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3590                         printf("%s mismatch for %s: %s != %s (%s)\n", \
3591                                #s1, user.string,  s1.string, s2.string, __location__);   \
3592                         ret = false; \
3593         }
3594 #define INT_EQUAL_QUERY(s1, s2, user)           \
3595                 if (s1 != s2) { \
3596                         printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3597                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3598                         ret = false; \
3599                 }
3600
3601 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3602                                        struct samr_QueryDisplayInfo *querydisplayinfo,
3603                                        bool *seen_testuser) 
3604 {
3605         struct samr_OpenUser r;
3606         struct samr_QueryUserInfo q;
3607         struct policy_handle user_handle;
3608         int i, ret = true;
3609         NTSTATUS status;
3610         r.in.domain_handle = querydisplayinfo->in.domain_handle;
3611         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3612         for (i = 0; ; i++) {
3613                 switch (querydisplayinfo->in.level) {
3614                 case 1:
3615                         if (i >= querydisplayinfo->out.info.info1.count) {
3616                                 return ret;
3617                         }
3618                         r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3619                         break;
3620                 case 2:
3621                         if (i >= querydisplayinfo->out.info.info2.count) {
3622                                 return ret;
3623                         }
3624                         r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3625                         break;
3626                 case 3:
3627                         /* Groups */
3628                 case 4:
3629                 case 5:
3630                         /* Not interested in validating just the account name */
3631                         return true;
3632                 }
3633                         
3634                 r.out.user_handle = &user_handle;
3635                 
3636                 switch (querydisplayinfo->in.level) {
3637                 case 1:
3638                 case 2:
3639                         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3640                         if (!NT_STATUS_IS_OK(status)) {
3641                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3642                                 return false;
3643                         }
3644                 }
3645                 
3646                 q.in.user_handle = &user_handle;
3647                 q.in.level = 21;
3648                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3649                 if (!NT_STATUS_IS_OK(status)) {
3650                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3651                         return false;
3652                 }
3653                 
3654                 switch (querydisplayinfo->in.level) {
3655                 case 1:
3656                         if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3657                                 *seen_testuser = true;
3658                         }
3659                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name, 
3660                                            q.out.info->info21.full_name, q.out.info->info21.account_name);
3661                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name, 
3662                                            q.out.info->info21.account_name, q.out.info->info21.account_name);
3663                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description, 
3664                                            q.out.info->info21.description, q.out.info->info21.account_name);
3665                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid, 
3666                                         q.out.info->info21.rid, q.out.info->info21.account_name);
3667                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags, 
3668                                         q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3669                         
3670                         break;
3671                 case 2:
3672                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name, 
3673                                            q.out.info->info21.account_name, q.out.info->info21.account_name);
3674                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description, 
3675                                            q.out.info->info21.description, q.out.info->info21.account_name);
3676                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid, 
3677                                         q.out.info->info21.rid, q.out.info->info21.account_name);
3678                         INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL), 
3679                                         q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3680                         
3681                         if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3682                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", 
3683                                        q.out.info->info21.account_name.string);
3684                         }
3685
3686                         if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3687                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3688                                        q.out.info->info21.account_name.string,
3689                                        querydisplayinfo->out.info.info2.entries[i].acct_flags,
3690                                        q.out.info->info21.acct_flags);
3691                                 return false;
3692                         }
3693                         
3694                         break;
3695                 }
3696                 
3697                 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3698                         return false;
3699                 }
3700         }
3701         return ret;
3702 }
3703
3704 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3705                                   struct policy_handle *handle)
3706 {
3707         NTSTATUS status;
3708         struct samr_QueryDisplayInfo r;
3709         struct samr_QueryDomainInfo dom_info;
3710         bool ret = true;
3711         uint16_t levels[] = {1, 2, 3, 4, 5};
3712         int i;
3713         bool seen_testuser = false;
3714
3715         for (i=0;i<ARRAY_SIZE(levels);i++) {
3716                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3717
3718                 r.in.start_idx = 0;
3719                 status = STATUS_MORE_ENTRIES;
3720                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3721                         r.in.domain_handle = handle;
3722                         r.in.level = levels[i];
3723                         r.in.max_entries = 2;
3724                         r.in.buf_size = (uint32_t)-1;
3725                         
3726                         status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3727                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3728                                 printf("QueryDisplayInfo level %u failed - %s\n", 
3729                                        levels[i], nt_errstr(status));
3730                                 ret = false;
3731                         }
3732                         switch (r.in.level) {
3733                         case 1:
3734                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3735                                         ret = false;
3736                                 }
3737                                 r.in.start_idx += r.out.info.info1.count;
3738                                 break;
3739                         case 2:
3740                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3741                                         ret = false;
3742                                 }
3743                                 r.in.start_idx += r.out.info.info2.count;
3744                                 break;
3745                         case 3:
3746                                 r.in.start_idx += r.out.info.info3.count;
3747                                 break;
3748                         case 4:
3749                                 r.in.start_idx += r.out.info.info4.count;
3750                                 break;
3751                         case 5:
3752                                 r.in.start_idx += r.out.info.info5.count;
3753                                 break;
3754                         }
3755                 }
3756                 dom_info.in.domain_handle = handle;
3757                 dom_info.in.level = 2;
3758                 /* Check number of users returned is correct */
3759                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3760                 if (!NT_STATUS_IS_OK(status)) {
3761                         printf("QueryDomainInfo level %u failed - %s\n", 
3762                                r.in.level, nt_errstr(status));
3763                                 ret = false;
3764                                 break;
3765                 }
3766                 switch (r.in.level) {
3767                 case 1:
3768                 case 4:
3769                         if (dom_info.out.info->general.num_users < r.in.start_idx) {
3770                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3771                                        r.in.start_idx, dom_info.out.info->general.num_groups,
3772                                        dom_info.out.info->general.domain_name.string);
3773                                 ret = false;
3774                         }
3775                         if (!seen_testuser) {
3776                                 struct policy_handle user_handle;
3777                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3778                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", 
3779                                                dom_info.out.info->general.domain_name.string);
3780                                         ret = false;
3781                                         test_samr_handle_Close(p, mem_ctx, &user_handle);
3782                                 }
3783                         }
3784                         break;
3785                 case 3:
3786                 case 5:
3787                         if (dom_info.out.info->general.num_groups != r.in.start_idx) {
3788                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3789                                        r.in.start_idx, dom_info.out.info->general.num_groups,
3790                                        dom_info.out.info->general.domain_name.string);
3791                                 ret = false;
3792                         }
3793                         
3794                         break;
3795                 }
3796
3797         }
3798         
3799         return ret;     
3800 }
3801
3802 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3803                                   struct policy_handle *handle)
3804 {
3805         NTSTATUS status;
3806         struct samr_QueryDisplayInfo2 r;
3807         bool ret = true;
3808         uint16_t levels[] = {1, 2, 3, 4, 5};
3809         int i;
3810
3811         for (i=0;i<ARRAY_SIZE(levels);i++) {
3812                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3813
3814                 r.in.domain_handle = handle;
3815                 r.in.level = levels[i];
3816                 r.in.start_idx = 0;
3817                 r.in.max_entries = 1000;
3818                 r.in.buf_size = (uint32_t)-1;
3819
3820                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3821                 if (!NT_STATUS_IS_OK(status)) {
3822                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
3823                                levels[i], nt_errstr(status));
3824                         ret = false;
3825                 }
3826         }
3827         
3828         return ret;     
3829 }
3830
3831 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3832                                   struct policy_handle *handle)
3833 {
3834         NTSTATUS status;
3835         struct samr_QueryDisplayInfo3 r;
3836         bool ret = true;
3837         uint16_t levels[] = {1, 2, 3, 4, 5};
3838         int i;
3839
3840         for (i=0;i<ARRAY_SIZE(levels);i++) {
3841                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3842
3843                 r.in.domain_handle = handle;
3844                 r.in.level = levels[i];
3845                 r.in.start_idx = 0;
3846                 r.in.max_entries = 1000;
3847                 r.in.buf_size = (uint32_t)-1;
3848
3849                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3850                 if (!NT_STATUS_IS_OK(status)) {
3851                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
3852                                levels[i], nt_errstr(status));
3853                         ret = false;
3854                 }
3855         }
3856         
3857         return ret;     
3858 }
3859
3860
3861 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3862                                            struct policy_handle *handle)
3863 {
3864         NTSTATUS status;
3865         struct samr_QueryDisplayInfo r;
3866         bool ret = true;
3867
3868         printf("Testing QueryDisplayInfo continuation\n");
3869
3870         r.in.domain_handle = handle;
3871         r.in.level = 1;
3872         r.in.start_idx = 0;
3873         r.in.max_entries = 1;
3874         r.in.buf_size = (uint32_t)-1;
3875
3876         do {
3877                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3878                 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3879                         if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3880                                 printf("expected idx %d but got %d\n",
3881                                        r.in.start_idx + 1,
3882                                        r.out.info.info1.entries[0].idx);
3883                                 break;
3884                         }
3885                 }
3886                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3887                     !NT_STATUS_IS_OK(status)) {
3888                         printf("QueryDisplayInfo level %u failed - %s\n", 
3889                                r.in.level, nt_errstr(status));
3890                         ret = false;
3891                         break;
3892                 }
3893                 r.in.start_idx++;
3894         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3895                   NT_STATUS_IS_OK(status)) &&
3896                  r.out.returned_size != 0);
3897         
3898         return ret;     
3899 }
3900
3901 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3902                                  struct policy_handle *handle)
3903 {
3904         NTSTATUS status;
3905         struct samr_QueryDomainInfo r;
3906         struct samr_SetDomainInfo s;
3907         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3908         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
3909         int i;
3910         bool ret = true;
3911         const char *domain_comment = talloc_asprintf(mem_ctx, 
3912                                   "Tortured by Samba4 RPC-SAMR: %s", 
3913                                   timestring(mem_ctx, time(NULL)));
3914
3915         s.in.domain_handle = handle;
3916         s.in.level = 4;
3917         s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3918         
3919         s.in.info->oem.oem_information.string = domain_comment;
3920         status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3921         if (!NT_STATUS_IS_OK(status)) {
3922                 printf("SetDomainInfo level %u (set comment) failed - %s\n", 
3923                        r.in.level, nt_errstr(status));
3924                 return false;
3925         }
3926
3927         for (i=0;i<ARRAY_SIZE(levels);i++) {
3928                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3929
3930                 r.in.domain_handle = handle;
3931                 r.in.level = levels[i];
3932
3933                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3934                 if (!NT_STATUS_IS_OK(status)) {
3935                         printf("QueryDomainInfo level %u failed - %s\n", 
3936                                r.in.level, nt_errstr(status));
3937                         ret = false;
3938                         continue;
3939                 }
3940
3941                 switch (levels[i]) {
3942                 case 2:
3943                         if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
3944                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3945                                        levels[i], r.out.info->general.oem_information.string, domain_comment);
3946                                 ret = false;
3947                         }
3948                         if (!r.out.info->general.primary.string) {
3949                                 printf("QueryDomainInfo level %u returned no PDC name\n",
3950                                        levels[i]);
3951                                 ret = false;
3952                         } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
3953                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
3954                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3955                                                levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
3956                                 }
3957                         }
3958                         break;
3959                 case 4:
3960                         if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
3961                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
3962                                        levels[i], r.out.info->oem.oem_information.string, domain_comment);
3963                                 ret = false;
3964                         }
3965                         break;
3966                 case 6:
3967                         if (!r.out.info->info6.primary.string) {
3968                                 printf("QueryDomainInfo level %u returned no PDC name\n",
3969                                        levels[i]);
3970                                 ret = false;
3971                         }
3972                         break;
3973                 case 11:
3974                         if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
3975                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3976                                        levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
3977                                 ret = false;
3978                         }
3979                         break;
3980                 }
3981
3982                 printf("Testing SetDomainInfo level %u\n", levels[i]);
3983
3984                 s.in.domain_handle = handle;
3985                 s.in.level = levels[i];
3986                 s.in.info = r.out.info;
3987
3988                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3989                 if (set_ok[i]) {
3990                         if (!NT_STATUS_IS_OK(status)) {
3991                                 printf("SetDomainInfo level %u failed - %s\n", 
3992                                        r.in.level, nt_errstr(status));
3993                                 ret = false;
3994                                 continue;
3995                         }
3996                 } else {
3997                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3998                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
3999                                        r.in.level, nt_errstr(status));
4000                                 ret = false;
4001                                 continue;
4002                         }
4003                 }
4004
4005                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
4006                 if (!NT_STATUS_IS_OK(status)) {
4007                         printf("QueryDomainInfo level %u failed - %s\n", 
4008                                r.in.level, nt_errstr(status));
4009                         ret = false;
4010                         continue;
4011                 }
4012         }
4013
4014         return ret;     
4015 }
4016
4017
4018 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4019                                   struct policy_handle *handle)
4020 {
4021         NTSTATUS status;
4022         struct samr_QueryDomainInfo2 r;
4023         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
4024         int i;
4025         bool ret = true;
4026
4027         for (i=0;i<ARRAY_SIZE(levels);i++) {
4028                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
4029
4030                 r.in.domain_handle = handle;
4031                 r.in.level = levels[i];
4032
4033                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
4034                 if (!NT_STATUS_IS_OK(status)) {
4035                         printf("QueryDomainInfo2 level %u failed - %s\n", 
4036                                r.in.level, nt_errstr(status));
4037                         ret = false;
4038                         continue;
4039                 }
4040         }
4041
4042         return true;    
4043 }
4044
4045 /* Test whether querydispinfo level 5 and enumdomgroups return the same
4046    set of group names. */
4047 static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4048                            struct policy_handle *handle)
4049 {
4050         struct samr_EnumDomainGroups q1;
4051         struct samr_QueryDisplayInfo q2;
4052         NTSTATUS status;
4053         uint32_t resume_handle=0;
4054         int i;
4055         bool ret = true;
4056
4057         int num_names = 0;
4058         const char **names = NULL;
4059
4060         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
4061
4062         q1.in.domain_handle = handle;
4063         q1.in.resume_handle = &resume_handle;
4064         q1.in.max_size = 5;
4065         q1.out.resume_handle = &resume_handle;
4066
4067         status = STATUS_MORE_ENTRIES;
4068         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4069                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
4070
4071                 if (!NT_STATUS_IS_OK(status) &&
4072                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4073                         break;
4074
4075                 for (i=0; i<q1.out.num_entries; i++) {
4076                         add_string_to_array(mem_ctx,
4077                                             q1.out.sam->entries[i].name.string,
4078                                             &names, &num_names);
4079                 }
4080         }
4081
4082         if (!NT_STATUS_IS_OK(status)) {
4083                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4084                 return false;
4085         }
4086         
4087         if (!q1.out.sam) {
4088                 printf("EnumDomainGroups failed to return q1.out.sam\n");
4089                 return false;
4090         }
4091
4092         q2.in.domain_handle = handle;
4093         q2.in.level = 5;
4094         q2.in.start_idx = 0;
4095         q2.in.max_entries = 5;
4096         q2.in.buf_size = (uint32_t)-1;
4097
4098         status = STATUS_MORE_ENTRIES;
4099         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4100                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
4101
4102                 if (!NT_STATUS_IS_OK(status) &&
4103                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
4104                         break;
4105
4106                 for (i=0; i<q2.out.info.info5.count; i++) {
4107                         int j;
4108                         const char *name = q2.out.info.info5.entries[i].account_name.string;
4109                         bool found = false;
4110                         for (j=0; j<num_names; j++) {
4111                                 if (names[j] == NULL)
4112                                         continue;
4113                                 if (strequal(names[j], name)) {
4114                                         names[j] = NULL;
4115                                         found = true;
4116                                         break;
4117                                 }
4118                         }
4119
4120                         if (!found) {
4121                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
4122                                        name);
4123                                 ret = false;
4124                         }
4125                 }
4126                 q2.in.start_idx += q2.out.info.info5.count;
4127         }
4128
4129         if (!NT_STATUS_IS_OK(status)) {
4130                 printf("QueryDisplayInfo level 5 failed - %s\n",
4131                        nt_errstr(status));
4132                 ret = false;
4133         }
4134
4135         for (i=0; i<num_names; i++) {
4136                 if (names[i] != NULL) {
4137                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
4138                                names[i]);
4139                         ret = false;
4140                 }
4141         }
4142
4143         return ret;
4144 }
4145
4146 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4147                                    struct policy_handle *group_handle)
4148 {
4149         struct samr_DeleteDomainGroup d;
4150         NTSTATUS status;
4151         bool ret = true;
4152
4153         printf("Testing DeleteDomainGroup\n");
4154
4155         d.in.group_handle = group_handle;
4156         d.out.group_handle = group_handle;
4157
4158         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
4159         if (!NT_STATUS_IS_OK(status)) {
4160                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
4161                 ret = false;
4162         }
4163
4164         return ret;
4165 }
4166
4167 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4168                                             struct policy_handle *domain_handle)
4169 {
4170         struct samr_TestPrivateFunctionsDomain r;
4171         NTSTATUS status;
4172         bool ret = true;
4173
4174         printf("Testing TestPrivateFunctionsDomain\n");
4175
4176         r.in.domain_handle = domain_handle;
4177
4178         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
4179         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
4180                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
4181                 ret = false;
4182         }
4183
4184         return ret;
4185 }
4186
4187 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4188                           struct dom_sid *domain_sid,
4189                           struct policy_handle *domain_handle)
4190 {
4191         struct samr_RidToSid r;
4192         NTSTATUS status;
4193         bool ret = true;
4194         struct dom_sid *calc_sid;
4195         int rids[] = { 0, 42, 512, 10200 };
4196         int i;
4197
4198         for (i=0;i<ARRAY_SIZE(rids);i++) {
4199         
4200                 printf("Testing RidToSid\n");
4201                 
4202                 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
4203                 r.in.domain_handle = domain_handle;
4204                 r.in.rid = rids[i];
4205                 
4206                 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
4207                 if (!NT_STATUS_IS_OK(status)) {
4208                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4209                         ret = false;
4210                 } else {
4211                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4212
4213                         if (!dom_sid_equal(calc_sid, r.out.sid)) {
4214                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
4215                                        dom_sid_string(mem_ctx, r.out.sid), 
4216                                        dom_sid_string(mem_ctx, calc_sid));
4217                                 ret = false;
4218                         }
4219                 }
4220         }
4221
4222         return ret;
4223 }
4224
4225 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4226                                        struct policy_handle *domain_handle)
4227 {
4228         struct samr_GetBootKeyInformation r;
4229         NTSTATUS status;
4230         bool ret = true;
4231
4232         printf("Testing GetBootKeyInformation\n");
4233
4234         r.in.domain_handle = domain_handle;
4235
4236         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4237         if (!NT_STATUS_IS_OK(status)) {
4238                 /* w2k3 seems to fail this sometimes and pass it sometimes */
4239                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4240         }
4241
4242         return ret;
4243 }
4244
4245 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx, 
4246                                 struct policy_handle *domain_handle,
4247                                 struct policy_handle *group_handle)
4248 {
4249         NTSTATUS status;
4250         struct samr_AddGroupMember r;
4251         struct samr_DeleteGroupMember d;
4252         struct samr_QueryGroupMember q;
4253         struct samr_SetMemberAttributesOfGroup s;
4254         bool ret = true;
4255         uint32_t rid;
4256
4257         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4258         if (!NT_STATUS_IS_OK(status)) {
4259                 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4260                 return false;
4261         }
4262
4263         r.in.group_handle = group_handle;
4264         r.in.rid = rid;
4265         r.in.flags = 0; /* ??? */
4266
4267         printf("Testing AddGroupMember and DeleteGroupMember\n");
4268
4269         d.in.group_handle = group_handle;
4270         d.in.rid = rid;
4271
4272         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4273         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4274                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
4275                        nt_errstr(status));
4276                 return false;
4277         }
4278
4279         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4280         if (!NT_STATUS_IS_OK(status)) {
4281                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4282                 return false;
4283         }
4284
4285         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4286         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4287                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
4288                        nt_errstr(status));
4289                 return false;
4290         }
4291
4292         if (torture_setting_bool(tctx, "samba4", false)) {
4293                 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4294         } else {
4295                 /* this one is quite strange. I am using random inputs in the
4296                    hope of triggering an error that might give us a clue */
4297
4298                 s.in.group_handle = group_handle;
4299                 s.in.unknown1 = random();
4300                 s.in.unknown2 = random();
4301
4302                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4303                 if (!NT_STATUS_IS_OK(status)) {
4304                         printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4305                         return false;
4306                 }
4307         }
4308
4309         q.in.group_handle = group_handle;
4310
4311         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4312         if (!NT_STATUS_IS_OK(status)) {
4313                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4314                 return false;
4315         }
4316
4317         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4318         if (!NT_STATUS_IS_OK(status)) {
4319                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4320                 return false;
4321         }
4322
4323         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4324         if (!NT_STATUS_IS_OK(status)) {
4325                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4326                 return false;
4327         }
4328
4329         return ret;
4330 }
4331
4332
4333 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4334                                    struct policy_handle *domain_handle, 
4335                                    struct policy_handle *group_handle,
4336                                    struct dom_sid *domain_sid)
4337 {
4338         NTSTATUS status;
4339         struct samr_CreateDomainGroup r;
4340         uint32_t rid;
4341         struct lsa_String name;
4342         bool ret = true;
4343
4344         init_lsa_String(&name, TEST_GROUPNAME);
4345
4346         r.in.domain_handle = domain_handle;
4347         r.in.name = &name;
4348         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4349         r.out.group_handle = group_handle;
4350         r.out.rid = &rid;
4351
4352         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4353
4354         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4355
4356         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
4357                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4358                         printf("Server correctly refused create of '%s'\n", r.in.name->string);
4359                         return true;
4360                 } else {
4361                         printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string, 
4362                                nt_errstr(status));
4363                         return false;
4364                 }
4365         }
4366
4367         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4368                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4369                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string, 
4370                                nt_errstr(status));
4371                         return false;
4372                 }
4373                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4374         }
4375         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4376                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4377                         
4378                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string, 
4379                                nt_errstr(status));
4380                         return false;
4381                 }
4382                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4383         }
4384         if (!NT_STATUS_IS_OK(status)) {
4385                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4386                 return false;
4387         }
4388
4389         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4390                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4391                 ret = false;
4392         }
4393
4394         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4395                 ret = false;
4396         }
4397
4398         return ret;
4399 }
4400
4401
4402 /*
4403   its not totally clear what this does. It seems to accept any sid you like.
4404 */
4405 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
4406                                                TALLOC_CTX *mem_ctx, 
4407                                                struct policy_handle *domain_handle)
4408 {
4409         NTSTATUS status;
4410         struct samr_RemoveMemberFromForeignDomain r;
4411
4412         r.in.domain_handle = domain_handle;
4413         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4414
4415         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4416         if (!NT_STATUS_IS_OK(status)) {
4417                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4418                 return false;
4419         }
4420
4421         return true;
4422 }
4423
4424
4425
4426 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4427                          struct policy_handle *handle);
4428
4429 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, 
4430                             struct policy_handle *handle, struct dom_sid *sid,
4431                             enum torture_samr_choice which_ops)
4432 {
4433         NTSTATUS status;
4434         struct samr_OpenDomain r;
4435         struct policy_handle domain_handle;
4436         struct policy_handle alias_handle;
4437         struct policy_handle user_handle;
4438         struct policy_handle group_handle;
4439         bool ret = true;
4440
4441         ZERO_STRUCT(alias_handle);
4442         ZERO_STRUCT(user_handle);
4443         ZERO_STRUCT(group_handle);
4444         ZERO_STRUCT(domain_handle);
4445
4446         printf("Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
4447
4448         r.in.connect_handle = handle;
4449         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4450         r.in.sid = sid;
4451         r.out.domain_handle = &domain_handle;
4452
4453         status = dcerpc_samr_OpenDomain(p, tctx, &r);
4454         if (!NT_STATUS_IS_OK(status)) {
4455                 printf("OpenDomain failed - %s\n", nt_errstr(status));
4456                 return false;
4457         }
4458
4459         /* run the domain tests with the main handle closed - this tests
4460            the servers reference counting */
4461         ret &= test_samr_handle_Close(p, tctx, handle);
4462
4463         switch (which_ops) {
4464         case TORTURE_SAMR_USER_ATTRIBUTES:
4465         case TORTURE_SAMR_PASSWORDS:
4466                 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
4467                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4468                 /* This test needs 'complex' users to validate */
4469                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4470                 if (!ret) {
4471                         printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
4472                 }
4473                 break;
4474         case TORTURE_SAMR_OTHER:
4475                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
4476                 if (!ret) {
4477                         printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
4478                 }
4479                 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4480                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4481                 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4482                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
4483                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4484                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4485                 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4486                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4487                 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4488                 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4489                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4490                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4491                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4492                 
4493                 if (torture_setting_bool(tctx, "samba4", false)) {
4494                         printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4495                 } else {
4496                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4497                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4498                 }
4499                 ret &= test_GroupList(p, tctx, &domain_handle);
4500                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4501                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4502                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4503                 if (!ret) {
4504                         printf("Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
4505                 }
4506                 break;
4507         }
4508
4509         if (!policy_handle_empty(&user_handle) &&
4510             !test_DeleteUser(p, tctx, &user_handle)) {
4511                 ret = false;
4512         }
4513
4514         if (!policy_handle_empty(&alias_handle) &&
4515             !test_DeleteAlias(p, tctx, &alias_handle)) {
4516                 ret = false;
4517         }
4518
4519         if (!policy_handle_empty(&group_handle) &&
4520             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4521                 ret = false;
4522         }
4523
4524         ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4525
4526         /* reconnect the main handle */
4527         ret &= test_Connect(p, tctx, handle);
4528
4529         if (!ret) {
4530                 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4531         }
4532
4533         return ret;
4534 }
4535
4536 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4537                               struct policy_handle *handle, const char *domain,
4538                               enum torture_samr_choice which_ops)
4539 {
4540         NTSTATUS status;
4541         struct samr_LookupDomain r;
4542         struct lsa_String n1;
4543         struct lsa_String n2;
4544         bool ret = true;
4545
4546         printf("Testing LookupDomain(%s)\n", domain);
4547
4548         /* check for correct error codes */
4549         r.in.connect_handle = handle;
4550         r.in.domain_name = &n2;
4551         n2.string = NULL;
4552
4553         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4554         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4555                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4556                 ret = false;
4557         }
4558
4559         init_lsa_String(&n2, "xxNODOMAINxx");
4560
4561         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4562         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4563                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4564                 ret = false;
4565         }
4566
4567         r.in.connect_handle = handle;
4568
4569         init_lsa_String(&n1, domain);
4570         r.in.domain_name = &n1;
4571
4572         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4573         if (!NT_STATUS_IS_OK(status)) {
4574                 printf("LookupDomain failed - %s\n", nt_errstr(status));
4575                 ret = false;
4576         }
4577
4578         if (!test_GetDomPwInfo(p, tctx, &n1)) {
4579                 ret = false;
4580         }
4581
4582         if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4583                 ret = false;
4584         }
4585
4586         return ret;
4587 }
4588
4589
4590 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4591                              struct policy_handle *handle, enum torture_samr_choice which_ops)
4592 {
4593         NTSTATUS status;
4594         struct samr_EnumDomains r;
4595         uint32_t resume_handle = 0;
4596         int i;
4597         bool ret = true;
4598
4599         r.in.connect_handle = handle;
4600         r.in.resume_handle = &resume_handle;
4601         r.in.buf_size = (uint32_t)-1;
4602         r.out.resume_handle = &resume_handle;
4603
4604         status = dcerpc_samr_EnumDomains(p, tctx, &r);
4605         if (!NT_STATUS_IS_OK(status)) {
4606                 printf("EnumDomains failed - %s\n", nt_errstr(status));
4607                 return false;
4608         }
4609
4610         if (!r.out.sam) {
4611                 return false;
4612         }
4613
4614         for (i=0;i<r.out.sam->count;i++) {
4615                 if (!test_LookupDomain(p, tctx, handle, 
4616                                        r.out.sam->entries[i].name.string, which_ops)) {
4617                         ret = false;
4618                 }
4619         }
4620
4621         status = dcerpc_samr_EnumDomains(p, tctx, &r);
4622         if (!NT_STATUS_IS_OK(status)) {
4623                 printf("EnumDomains failed - %s\n", nt_errstr(status));
4624                 return false;
4625         }
4626
4627         return ret;
4628 }
4629
4630
4631 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4632                          struct policy_handle *handle)
4633 {
4634         NTSTATUS status;
4635         struct samr_Connect r;
4636         struct samr_Connect2 r2;
4637         struct samr_Connect3 r3;
4638         struct samr_Connect4 r4;
4639         struct samr_Connect5 r5;
4640         union samr_ConnectInfo info;
4641         struct policy_handle h;
4642         bool ret = true, got_handle = false;
4643
4644         printf("testing samr_Connect\n");
4645
4646         r.in.system_name = 0;
4647         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4648         r.out.connect_handle = &h;
4649
4650         status = dcerpc_samr_Connect(p, mem_ctx, &r);
4651         if (!NT_STATUS_IS_OK(status)) {
4652                 printf("Connect failed - %s\n", nt_errstr(status));
4653                 ret = false;
4654         } else {
4655                 got_handle = true;
4656                 *handle = h;
4657         }
4658
4659         printf("testing samr_Connect2\n");
4660
4661         r2.in.system_name = NULL;
4662         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4663         r2.out.connect_handle = &h;
4664
4665         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4666         if (!NT_STATUS_IS_OK(status)) {
4667                 printf("Connect2 failed - %s\n", nt_errstr(status));
4668                 ret = false;
4669         } else {
4670                 if (got_handle) {
4671                         test_samr_handle_Close(p, mem_ctx, handle);
4672                 }
4673                 got_handle = true;
4674                 *handle = h;
4675         }
4676
4677         printf("testing samr_Connect3\n");
4678
4679         r3.in.system_name = NULL;
4680         r3.in.unknown = 0;
4681         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4682         r3.out.connect_handle = &h;
4683
4684         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4685         if (!NT_STATUS_IS_OK(status)) {
4686                 printf("Connect3 failed - %s\n", nt_errstr(status));
4687                 ret = false;
4688         } else {
4689                 if (got_handle) {
4690                         test_samr_handle_Close(p, mem_ctx, handle);
4691                 }
4692                 got_handle = true;
4693                 *handle = h;
4694         }
4695
4696         printf("testing samr_Connect4\n");
4697
4698         r4.in.system_name = "";
4699         r4.in.client_version = 0;
4700         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4701         r4.out.connect_handle = &h;
4702
4703         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4704         if (!NT_STATUS_IS_OK(status)) {
4705                 printf("Connect4 failed - %s\n", nt_errstr(status));
4706                 ret = false;
4707         } else {
4708                 if (got_handle) {
4709                         test_samr_handle_Close(p, mem_ctx, handle);
4710                 }
4711                 got_handle = true;
4712                 *handle = h;
4713         }
4714
4715         printf("testing samr_Connect5\n");
4716
4717         info.info1.client_version = 0;
4718         info.info1.unknown2 = 0;
4719
4720         r5.in.system_name = "";
4721         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4722         r5.in.level = 1;
4723         r5.in.info = &info;
4724         r5.out.info = &info;
4725         r5.out.connect_handle = &h;
4726
4727         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4728         if (!NT_STATUS_IS_OK(status)) {
4729                 printf("Connect5 failed - %s\n", nt_errstr(status));
4730                 ret = false;
4731         } else {
4732                 if (got_handle) {
4733                         test_samr_handle_Close(p, mem_ctx, handle);
4734                 }
4735                 got_handle = true;
4736                 *handle = h;
4737         }
4738
4739         return ret;
4740 }
4741
4742
4743 bool torture_rpc_samr(struct torture_context *torture)
4744 {
4745         NTSTATUS status;
4746         struct dcerpc_pipe *p;
4747         bool ret = true;
4748         struct policy_handle handle;
4749
4750         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4751         if (!NT_STATUS_IS_OK(status)) {
4752                 return false;
4753         }
4754
4755         ret &= test_Connect(p, torture, &handle);
4756
4757         ret &= test_QuerySecurity(p, torture, &handle);
4758
4759         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4760
4761         ret &= test_SetDsrmPassword(p, torture, &handle);
4762
4763         ret &= test_Shutdown(p, torture, &handle);
4764
4765         ret &= test_samr_handle_Close(p, torture, &handle);
4766
4767         return ret;
4768 }
4769
4770
4771 bool torture_rpc_samr_users(struct torture_context *torture)
4772 {
4773         NTSTATUS status;
4774         struct dcerpc_pipe *p;
4775         bool ret = true;
4776         struct policy_handle handle;
4777
4778         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4779         if (!NT_STATUS_IS_OK(status)) {
4780                 return false;
4781         }
4782
4783         ret &= test_Connect(p, torture, &handle);
4784
4785         ret &= test_QuerySecurity(p, torture, &handle);
4786
4787         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4788
4789         ret &= test_SetDsrmPassword(p, torture, &handle);
4790
4791         ret &= test_Shutdown(p, torture, &handle);
4792
4793         ret &= test_samr_handle_Close(p, torture, &handle);
4794
4795         return ret;
4796 }
4797
4798
4799 bool torture_rpc_samr_passwords(struct torture_context *torture)
4800 {
4801         NTSTATUS status;
4802         struct dcerpc_pipe *p;
4803         bool ret = true;
4804         struct policy_handle handle;
4805
4806         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4807         if (!NT_STATUS_IS_OK(status)) {
4808                 return false;
4809         }
4810
4811         ret &= test_Connect(p, torture, &handle);
4812
4813         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4814
4815         ret &= test_samr_handle_Close(p, torture, &handle);
4816
4817         return ret;
4818 }
4819