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