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