r24971: Test more combinations for resetting the account expiry.
[kai/samba.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "system/time.h"
25 #include "librpc/gen_ndr/lsa.h"
26 #include "librpc/gen_ndr/ndr_samr_c.h"
27 #include "lib/crypto/crypto.h"
28 #include "libcli/auth/libcli_auth.h"
29 #include "libcli/security/security.h"
30 #include "torture/rpc/rpc.h"
31
32 #define TEST_ACCOUNT_NAME "samrtorturetest"
33 #define TEST_ALIASNAME "samrtorturetestalias"
34 #define TEST_GROUPNAME "samrtorturetestgroup"
35 #define TEST_MACHINENAME "samrtestmach$"
36 #define TEST_DOMAINNAME "samrtestdom$"
37
38 enum torture_samr_choice {
39         TORTURE_SAMR_PASSWORDS,
40         TORTURE_SAMR_USER_ATTRIBUTES,
41         TORTURE_SAMR_OTHER
42 };
43
44 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
45                                struct policy_handle *handle);
46
47 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
48                                 struct policy_handle *handle);
49
50 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
51                                struct policy_handle *handle);
52
53 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
54                                 const char *acct_name, 
55                                 struct policy_handle *domain_handle, char **password);
56
57 static void init_lsa_String(struct lsa_String *string, const char *s)
58 {
59         string->string = s;
60 }
61
62 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
63                                    struct policy_handle *handle)
64 {
65         NTSTATUS status;
66         struct samr_Close r;
67
68         r.in.handle = handle;
69         r.out.handle = handle;
70
71         status = dcerpc_samr_Close(p, mem_ctx, &r);
72         if (!NT_STATUS_IS_OK(status)) {
73                 printf("Close handle failed - %s\n", nt_errstr(status));
74                 return False;
75         }
76
77         return True;
78 }
79
80 static BOOL test_Shutdown(struct dcerpc_pipe *p, 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%x - got 0x%x (%s)\n", \
231                                #field, i2, 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
377         TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
378         TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters", 
379                            SAMR_FIELD_PARAMETERS);
380
381         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
382         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
383                           SAMR_FIELD_COUNTRY_CODE);
384
385         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
386         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
387                           SAMR_FIELD_CODE_PAGE);
388
389         TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
390         TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
391         TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__, 
392                           SAMR_FIELD_ACCT_EXPIRY);
393         TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__, 
394                           SAMR_FIELD_ACCT_EXPIRY);
395         TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__, 
396                           SAMR_FIELD_ACCT_EXPIRY);
397
398         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
399         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
400         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
401         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
402                           SAMR_FIELD_LOGON_HOURS);
403
404         if (lp_parm_bool(-1, "torture", "samba4", False)) {
405                 printf("skipping Set Account Flag tests against Samba4\n");
406                 return ret;
407         }
408
409         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
410                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
411                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
412                               0);
413         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
414                               (base_acct_flags  | ACB_DISABLED), 
415                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
416                               0);
417         
418         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
419         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
420                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
421                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
422                               0);
423         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
424                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
425                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
426                               0);
427
428
429         /* The 'autolock' flag doesn't stick - check this */
430         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
431                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
432                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
433                               0);
434 #if 0
435         /* Removing the 'disabled' flag doesn't stick - check this */
436         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
437                               (base_acct_flags), 
438                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
439                               0);
440 #endif
441         /* The 'store plaintext' flag does stick */
442         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
443                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
444                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
445                               0);
446         /* The 'use DES' flag does stick */
447         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
448                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
449                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
450                               0);
451         /* The 'don't require kerberos pre-authentication flag does stick */
452         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
453                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
454                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
455                               0);
456         /* The 'no kerberos PAC required' flag sticks */
457         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
458                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
459                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
460                               0);
461
462         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
463                               (base_acct_flags | ACB_DISABLED), 
464                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
465                               SAMR_FIELD_ACCT_FLAGS);
466
467 #if 0
468         /* these fail with win2003 - it appears you can't set the primary gid?
469            the set succeeds, but the gid isn't changed. Very weird! */
470         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
471         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
472         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
473         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
474 #endif
475
476         return ret;
477 }
478
479 /*
480   generate a random password for password change tests
481 */
482 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
483 {
484         size_t len = MAX(8, min_len) + (random() % 6);
485         char *s = generate_random_str(mem_ctx, len);
486         printf("Generated password '%s'\n", s);
487         return s;
488 }
489
490 /*
491   generate a random password for password change tests (fixed length)
492 */
493 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
494 {
495         char *s = generate_random_str(mem_ctx, len);
496         printf("Generated password '%s'\n", s);
497         return s;
498 }
499
500 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
501                              struct policy_handle *handle, char **password)
502 {
503         NTSTATUS status;
504         struct samr_SetUserInfo s;
505         union samr_UserInfo u;
506         BOOL ret = True;
507         DATA_BLOB session_key;
508         char *newpass;
509         struct samr_GetUserPwInfo pwp;
510         int policy_min_pw_len = 0;
511         pwp.in.user_handle = handle;
512
513         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
514         if (NT_STATUS_IS_OK(status)) {
515                 policy_min_pw_len = pwp.out.info.min_password_length;
516         }
517         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
518
519         s.in.user_handle = handle;
520         s.in.info = &u;
521         s.in.level = 24;
522
523         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
524         /* w2k3 ignores this length */
525         u.info24.pw_len = strlen_m(newpass) * 2;
526
527         status = dcerpc_fetch_session_key(p, &session_key);
528         if (!NT_STATUS_IS_OK(status)) {
529                 printf("SetUserInfo level %u - no session key - %s\n",
530                        s.in.level, nt_errstr(status));
531                 return False;
532         }
533
534         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
535
536         printf("Testing SetUserInfo level 24 (set password)\n");
537
538         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
539         if (!NT_STATUS_IS_OK(status)) {
540                 printf("SetUserInfo level %u failed - %s\n",
541                        s.in.level, nt_errstr(status));
542                 ret = False;
543         } else {
544                 *password = newpass;
545         }
546
547         return ret;
548 }
549
550
551 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
552                                 struct policy_handle *handle, uint32_t fields_present,
553                                 char **password)
554 {
555         NTSTATUS status;
556         struct samr_SetUserInfo s;
557         union samr_UserInfo u;
558         BOOL ret = True;
559         DATA_BLOB session_key;
560         char *newpass;
561         struct samr_GetUserPwInfo pwp;
562         int policy_min_pw_len = 0;
563         pwp.in.user_handle = handle;
564
565         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
566         if (NT_STATUS_IS_OK(status)) {
567                 policy_min_pw_len = pwp.out.info.min_password_length;
568         }
569         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
570
571         s.in.user_handle = handle;
572         s.in.info = &u;
573         s.in.level = 23;
574
575         ZERO_STRUCT(u);
576
577         u.info23.info.fields_present = fields_present;
578
579         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
580
581         status = dcerpc_fetch_session_key(p, &session_key);
582         if (!NT_STATUS_IS_OK(status)) {
583                 printf("SetUserInfo level %u - no session key - %s\n",
584                        s.in.level, nt_errstr(status));
585                 return False;
586         }
587
588         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
589
590         printf("Testing SetUserInfo level 23 (set password)\n");
591
592         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
593         if (!NT_STATUS_IS_OK(status)) {
594                 printf("SetUserInfo level %u failed - %s\n",
595                        s.in.level, nt_errstr(status));
596                 ret = False;
597         } else {
598                 *password = newpass;
599         }
600
601         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
602
603         status = dcerpc_fetch_session_key(p, &session_key);
604         if (!NT_STATUS_IS_OK(status)) {
605                 printf("SetUserInfo level %u - no session key - %s\n",
606                        s.in.level, nt_errstr(status));
607                 return False;
608         }
609
610         /* This should break the key nicely */
611         session_key.length--;
612         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
613
614         printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
615
616         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
617         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
618                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
619                        s.in.level, nt_errstr(status));
620                 ret = False;
621         }
622
623         return ret;
624 }
625
626
627 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
628                                struct policy_handle *handle, bool makeshort, 
629                                char **password)
630 {
631         NTSTATUS status;
632         struct samr_SetUserInfo s;
633         union samr_UserInfo u;
634         BOOL ret = True;
635         DATA_BLOB session_key;
636         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
637         uint8_t confounder[16];
638         char *newpass;
639         struct MD5Context ctx;
640         struct samr_GetUserPwInfo pwp;
641         int policy_min_pw_len = 0;
642         pwp.in.user_handle = handle;
643
644         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
645         if (NT_STATUS_IS_OK(status)) {
646                 policy_min_pw_len = pwp.out.info.min_password_length;
647         }
648         if (makeshort && policy_min_pw_len) {
649                 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
650         } else {
651                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
652         }
653
654         s.in.user_handle = handle;
655         s.in.info = &u;
656         s.in.level = 26;
657
658         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
659         u.info26.pw_len = strlen(newpass);
660
661         status = dcerpc_fetch_session_key(p, &session_key);
662         if (!NT_STATUS_IS_OK(status)) {
663                 printf("SetUserInfo level %u - no session key - %s\n",
664                        s.in.level, nt_errstr(status));
665                 return False;
666         }
667
668         generate_random_buffer((uint8_t *)confounder, 16);
669
670         MD5Init(&ctx);
671         MD5Update(&ctx, confounder, 16);
672         MD5Update(&ctx, session_key.data, session_key.length);
673         MD5Final(confounded_session_key.data, &ctx);
674
675         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
676         memcpy(&u.info26.password.data[516], confounder, 16);
677
678         printf("Testing SetUserInfo level 26 (set password ex)\n");
679
680         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
681         if (!NT_STATUS_IS_OK(status)) {
682                 printf("SetUserInfo level %u failed - %s\n",
683                        s.in.level, nt_errstr(status));
684                 ret = False;
685         } else {
686                 *password = newpass;
687         }
688
689         /* This should break the key nicely */
690         confounded_session_key.data[0]++;
691
692         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
693         memcpy(&u.info26.password.data[516], confounder, 16);
694
695         printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
696
697         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
698         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
699                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
700                        s.in.level, nt_errstr(status));
701                 ret = False;
702         } else {
703                 *password = newpass;
704         }
705
706         return ret;
707 }
708
709 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
710                                 struct policy_handle *handle, uint32_t fields_present,
711                                 char **password)
712 {
713         NTSTATUS status;
714         struct samr_SetUserInfo s;
715         union samr_UserInfo u;
716         BOOL ret = True;
717         DATA_BLOB session_key;
718         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
719         struct MD5Context ctx;
720         uint8_t confounder[16];
721         char *newpass;
722         struct samr_GetUserPwInfo pwp;
723         int policy_min_pw_len = 0;
724         pwp.in.user_handle = handle;
725
726         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
727         if (NT_STATUS_IS_OK(status)) {
728                 policy_min_pw_len = pwp.out.info.min_password_length;
729         }
730         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
731
732         s.in.user_handle = handle;
733         s.in.info = &u;
734         s.in.level = 25;
735
736         ZERO_STRUCT(u);
737
738         u.info25.info.fields_present = fields_present;
739
740         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
741
742         status = dcerpc_fetch_session_key(p, &session_key);
743         if (!NT_STATUS_IS_OK(status)) {
744                 printf("SetUserInfo level %u - no session key - %s\n",
745                        s.in.level, nt_errstr(status));
746                 return False;
747         }
748
749         generate_random_buffer((uint8_t *)confounder, 16);
750
751         MD5Init(&ctx);
752         MD5Update(&ctx, confounder, 16);
753         MD5Update(&ctx, session_key.data, session_key.length);
754         MD5Final(confounded_session_key.data, &ctx);
755
756         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
757         memcpy(&u.info25.password.data[516], confounder, 16);
758
759         printf("Testing SetUserInfo level 25 (set password ex)\n");
760
761         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
762         if (!NT_STATUS_IS_OK(status)) {
763                 printf("SetUserInfo level %u failed - %s\n",
764                        s.in.level, nt_errstr(status));
765                 ret = False;
766         } else {
767                 *password = newpass;
768         }
769
770         /* This should break the key nicely */
771         confounded_session_key.data[0]++;
772
773         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
774         memcpy(&u.info25.password.data[516], confounder, 16);
775
776         printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
777
778         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
779         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
780                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
781                        s.in.level, nt_errstr(status));
782                 ret = False;
783         }
784
785         return ret;
786 }
787
788 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
789                                struct policy_handle *handle)
790 {
791         NTSTATUS status;
792         struct samr_SetAliasInfo r;
793         struct samr_QueryAliasInfo q;
794         uint16_t levels[] = {2, 3};
795         int i;
796         BOOL ret = True;
797
798         /* Ignoring switch level 1, as that includes the number of members for the alias
799          * and setting this to a wrong value might have negative consequences
800          */
801
802         for (i=0;i<ARRAY_SIZE(levels);i++) {
803                 printf("Testing SetAliasInfo level %u\n", levels[i]);
804
805                 r.in.alias_handle = handle;
806                 r.in.level = levels[i];
807                 r.in.info  = talloc(mem_ctx, union samr_AliasInfo);
808                 switch (r.in.level) {
809                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
810                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
811                                 "Test Description, should test I18N as well"); break;
812                 }
813
814                 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
815                 if (!NT_STATUS_IS_OK(status)) {
816                         printf("SetAliasInfo level %u failed - %s\n",
817                                levels[i], nt_errstr(status));
818                         ret = False;
819                 }
820
821                 q.in.alias_handle = handle;
822                 q.in.level = levels[i];
823
824                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
825                 if (!NT_STATUS_IS_OK(status)) {
826                         printf("QueryAliasInfo level %u failed - %s\n",
827                                levels[i], nt_errstr(status));
828                         ret = False;
829                 }
830         }
831
832         return ret;
833 }
834
835 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
836                                   struct policy_handle *user_handle)
837 {
838         struct samr_GetGroupsForUser r;
839         NTSTATUS status;
840         BOOL ret = True;
841
842         printf("testing GetGroupsForUser\n");
843
844         r.in.user_handle = user_handle;
845
846         status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
847         if (!NT_STATUS_IS_OK(status)) {
848                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
849                 ret = False;
850         }
851
852         return ret;
853
854 }
855
856 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
857                               struct lsa_String *domain_name)
858 {
859         NTSTATUS status;
860         struct samr_GetDomPwInfo r;
861         BOOL ret = True;
862
863         r.in.domain_name = domain_name;
864         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
865
866         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
867         if (!NT_STATUS_IS_OK(status)) {
868                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
869                 ret = False;
870         }
871
872         r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
873         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
874
875         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
876         if (!NT_STATUS_IS_OK(status)) {
877                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
878                 ret = False;
879         }
880
881         r.in.domain_name->string = "\\\\__NONAME__";
882         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
883
884         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
885         if (!NT_STATUS_IS_OK(status)) {
886                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
887                 ret = False;
888         }
889
890         r.in.domain_name->string = "\\\\Builtin";
891         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
892
893         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
894         if (!NT_STATUS_IS_OK(status)) {
895                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
896                 ret = False;
897         }
898
899
900         return ret;
901 }
902
903 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
904                                struct policy_handle *handle)
905 {
906         NTSTATUS status;
907         struct samr_GetUserPwInfo r;
908         BOOL ret = True;
909
910         printf("Testing GetUserPwInfo\n");
911
912         r.in.user_handle = handle;
913
914         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
915         if (!NT_STATUS_IS_OK(status)) {
916                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
917                 ret = False;
918         }
919
920         return ret;
921 }
922
923 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
924                                 struct policy_handle *domain_handle, const char *name,
925                                 uint32_t *rid)
926 {
927         NTSTATUS status;
928         struct samr_LookupNames n;
929         struct lsa_String sname[2];
930
931         init_lsa_String(&sname[0], name);
932
933         n.in.domain_handle = domain_handle;
934         n.in.num_names = 1;
935         n.in.names = sname;
936         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
937         if (NT_STATUS_IS_OK(status)) {
938                 *rid = n.out.rids.ids[0];
939         } else {
940                 return status;
941         }
942
943         init_lsa_String(&sname[1], "xxNONAMExx");
944         n.in.num_names = 2;
945         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
946         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
947                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
948                 if (NT_STATUS_IS_OK(status)) {
949                         return NT_STATUS_UNSUCCESSFUL;
950                 }
951                 return status;
952         }
953
954         n.in.num_names = 0;
955         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
956         if (!NT_STATUS_IS_OK(status)) {
957                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
958                 return status;
959         }
960
961         init_lsa_String(&sname[0], "xxNONAMExx");
962         n.in.num_names = 1;
963         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
964         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
965                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
966                 if (NT_STATUS_IS_OK(status)) {
967                         return NT_STATUS_UNSUCCESSFUL;
968                 }
969                 return status;
970         }
971
972         init_lsa_String(&sname[0], "xxNONAMExx");
973         init_lsa_String(&sname[1], "xxNONAME2xx");
974         n.in.num_names = 2;
975         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
976         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
977                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
978                 if (NT_STATUS_IS_OK(status)) {
979                         return NT_STATUS_UNSUCCESSFUL;
980                 }
981                 return status;
982         }
983
984         return NT_STATUS_OK;
985 }
986
987 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
988                                      struct policy_handle *domain_handle,
989                                      const char *name, struct policy_handle *user_handle)
990 {
991         NTSTATUS status;
992         struct samr_OpenUser r;
993         uint32_t rid;
994
995         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
996         if (!NT_STATUS_IS_OK(status)) {
997                 return status;
998         }
999
1000         r.in.domain_handle = domain_handle;
1001         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1002         r.in.rid = rid;
1003         r.out.user_handle = user_handle;
1004         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1005         if (!NT_STATUS_IS_OK(status)) {
1006                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1007         }
1008
1009         return status;
1010 }
1011
1012 #if 0
1013 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1014                                    struct policy_handle *handle)
1015 {
1016         NTSTATUS status;
1017         struct samr_ChangePasswordUser r;
1018         BOOL ret = True;
1019         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1020         struct policy_handle user_handle;
1021         char *oldpass = "test";
1022         char *newpass = "test2";
1023         uint8_t old_nt_hash[16], new_nt_hash[16];
1024         uint8_t old_lm_hash[16], new_lm_hash[16];
1025
1026         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1027         if (!NT_STATUS_IS_OK(status)) {
1028                 return False;
1029         }
1030
1031         printf("Testing ChangePasswordUser for user 'testuser'\n");
1032
1033         printf("old password: %s\n", oldpass);
1034         printf("new password: %s\n", newpass);
1035
1036         E_md4hash(oldpass, old_nt_hash);
1037         E_md4hash(newpass, new_nt_hash);
1038         E_deshash(oldpass, old_lm_hash);
1039         E_deshash(newpass, new_lm_hash);
1040
1041         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1042         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1043         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1044         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1045         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1046         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1047
1048         r.in.handle = &user_handle;
1049         r.in.lm_present = 1;
1050         r.in.old_lm_crypted = &hash1;
1051         r.in.new_lm_crypted = &hash2;
1052         r.in.nt_present = 1;
1053         r.in.old_nt_crypted = &hash3;
1054         r.in.new_nt_crypted = &hash4;
1055         r.in.cross1_present = 1;
1056         r.in.nt_cross = &hash5;
1057         r.in.cross2_present = 1;
1058         r.in.lm_cross = &hash6;
1059
1060         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1061         if (!NT_STATUS_IS_OK(status)) {
1062                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1063                 ret = False;
1064         }
1065
1066         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1067                 ret = False;
1068         }
1069
1070         return ret;
1071 }
1072 #endif
1073
1074 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1075                                     const char *acct_name, 
1076                                     struct policy_handle *handle, char **password)
1077 {
1078         NTSTATUS status;
1079         struct samr_ChangePasswordUser r;
1080         BOOL ret = True;
1081         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1082         struct policy_handle user_handle;
1083         char *oldpass;
1084         uint8_t old_nt_hash[16], new_nt_hash[16];
1085         uint8_t old_lm_hash[16], new_lm_hash[16];
1086         BOOL changed = True;
1087
1088         char *newpass;
1089         struct samr_GetUserPwInfo pwp;
1090         int policy_min_pw_len = 0;
1091
1092         status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1093         if (!NT_STATUS_IS_OK(status)) {
1094                 return False;
1095         }
1096         pwp.in.user_handle = &user_handle;
1097
1098         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1099         if (NT_STATUS_IS_OK(status)) {
1100                 policy_min_pw_len = pwp.out.info.min_password_length;
1101         }
1102         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1103
1104         printf("Testing ChangePasswordUser\n");
1105
1106         if (!*password) {
1107                 printf("Failing ChangePasswordUser as old password was NULL.  Previous test failed?\n");
1108                 return False;
1109         }
1110
1111         oldpass = *password;
1112
1113         E_md4hash(oldpass, old_nt_hash);
1114         E_md4hash(newpass, new_nt_hash);
1115         E_deshash(oldpass, old_lm_hash);
1116         E_deshash(newpass, new_lm_hash);
1117
1118         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1119         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1120         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1121         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1122         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1123         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1124
1125         r.in.user_handle = &user_handle;
1126         r.in.lm_present = 1;
1127         /* Break the LM hash */
1128         hash1.hash[0]++;
1129         r.in.old_lm_crypted = &hash1;
1130         r.in.new_lm_crypted = &hash2;
1131         r.in.nt_present = 1;
1132         r.in.old_nt_crypted = &hash3;
1133         r.in.new_nt_crypted = &hash4;
1134         r.in.cross1_present = 1;
1135         r.in.nt_cross = &hash5;
1136         r.in.cross2_present = 1;
1137         r.in.lm_cross = &hash6;
1138
1139         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1140         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1141                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1142                 ret = False;
1143         }
1144
1145         /* Unbreak the LM hash */
1146         hash1.hash[0]--;
1147
1148         r.in.user_handle = &user_handle;
1149         r.in.lm_present = 1;
1150         r.in.old_lm_crypted = &hash1;
1151         r.in.new_lm_crypted = &hash2;
1152         /* Break the NT hash */
1153         hash3.hash[0]--;
1154         r.in.nt_present = 1;
1155         r.in.old_nt_crypted = &hash3;
1156         r.in.new_nt_crypted = &hash4;
1157         r.in.cross1_present = 1;
1158         r.in.nt_cross = &hash5;
1159         r.in.cross2_present = 1;
1160         r.in.lm_cross = &hash6;
1161
1162         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1163         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1164                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1165                 ret = False;
1166         }
1167
1168         /* Unbreak the NT hash */
1169         hash3.hash[0]--;
1170
1171         r.in.user_handle = &user_handle;
1172         r.in.lm_present = 1;
1173         r.in.old_lm_crypted = &hash1;
1174         r.in.new_lm_crypted = &hash2;
1175         r.in.nt_present = 1;
1176         r.in.old_nt_crypted = &hash3;
1177         r.in.new_nt_crypted = &hash4;
1178         r.in.cross1_present = 1;
1179         r.in.nt_cross = &hash5;
1180         r.in.cross2_present = 1;
1181         /* Break the LM cross */
1182         hash6.hash[0]++;
1183         r.in.lm_cross = &hash6;
1184
1185         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1186         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1187                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1188                 ret = False;
1189         }
1190
1191         /* Unbreak the LM cross */
1192         hash6.hash[0]--;
1193
1194         r.in.user_handle = &user_handle;
1195         r.in.lm_present = 1;
1196         r.in.old_lm_crypted = &hash1;
1197         r.in.new_lm_crypted = &hash2;
1198         r.in.nt_present = 1;
1199         r.in.old_nt_crypted = &hash3;
1200         r.in.new_nt_crypted = &hash4;
1201         r.in.cross1_present = 1;
1202         /* Break the NT cross */
1203         hash5.hash[0]++;
1204         r.in.nt_cross = &hash5;
1205         r.in.cross2_present = 1;
1206         r.in.lm_cross = &hash6;
1207
1208         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1209         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1210                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1211                 ret = False;
1212         }
1213
1214         /* Unbreak the NT cross */
1215         hash5.hash[0]--;
1216
1217
1218         /* Reset the hashes to not broken values */
1219         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1220         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1221         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1222         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1223         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1224         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1225
1226         r.in.user_handle = &user_handle;
1227         r.in.lm_present = 1;
1228         r.in.old_lm_crypted = &hash1;
1229         r.in.new_lm_crypted = &hash2;
1230         r.in.nt_present = 1;
1231         r.in.old_nt_crypted = &hash3;
1232         r.in.new_nt_crypted = &hash4;
1233         r.in.cross1_present = 1;
1234         r.in.nt_cross = &hash5;
1235         r.in.cross2_present = 0;
1236         r.in.lm_cross = NULL;
1237
1238         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1239         if (NT_STATUS_IS_OK(status)) {
1240                 changed = True;
1241                 *password = newpass;
1242         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1243                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1244                 ret = False;
1245         }
1246
1247         oldpass = newpass;
1248         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1249
1250         E_md4hash(oldpass, old_nt_hash);
1251         E_md4hash(newpass, new_nt_hash);
1252         E_deshash(oldpass, old_lm_hash);
1253         E_deshash(newpass, new_lm_hash);
1254
1255
1256         /* Reset the hashes to not broken values */
1257         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1258         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1259         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1260         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1261         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1262         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1263
1264         r.in.user_handle = &user_handle;
1265         r.in.lm_present = 1;
1266         r.in.old_lm_crypted = &hash1;
1267         r.in.new_lm_crypted = &hash2;
1268         r.in.nt_present = 1;
1269         r.in.old_nt_crypted = &hash3;
1270         r.in.new_nt_crypted = &hash4;
1271         r.in.cross1_present = 0;
1272         r.in.nt_cross = NULL;
1273         r.in.cross2_present = 1;
1274         r.in.lm_cross = &hash6;
1275
1276         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1277         if (NT_STATUS_IS_OK(status)) {
1278                 changed = True;
1279                 *password = newpass;
1280         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1281                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1282                 ret = False;
1283         }
1284
1285         oldpass = newpass;
1286         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1287
1288         E_md4hash(oldpass, old_nt_hash);
1289         E_md4hash(newpass, new_nt_hash);
1290         E_deshash(oldpass, old_lm_hash);
1291         E_deshash(newpass, new_lm_hash);
1292
1293
1294         /* Reset the hashes to not broken values */
1295         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1296         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1297         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1298         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1299         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1300         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1301
1302         r.in.user_handle = &user_handle;
1303         r.in.lm_present = 1;
1304         r.in.old_lm_crypted = &hash1;
1305         r.in.new_lm_crypted = &hash2;
1306         r.in.nt_present = 1;
1307         r.in.old_nt_crypted = &hash3;
1308         r.in.new_nt_crypted = &hash4;
1309         r.in.cross1_present = 1;
1310         r.in.nt_cross = &hash5;
1311         r.in.cross2_present = 1;
1312         r.in.lm_cross = &hash6;
1313
1314         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1315         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1316                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1317         } else  if (!NT_STATUS_IS_OK(status)) {
1318                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1319                 ret = False;
1320         } else {
1321                 changed = True;
1322                 *password = newpass;
1323         }
1324
1325         r.in.user_handle = &user_handle;
1326         r.in.lm_present = 1;
1327         r.in.old_lm_crypted = &hash1;
1328         r.in.new_lm_crypted = &hash2;
1329         r.in.nt_present = 1;
1330         r.in.old_nt_crypted = &hash3;
1331         r.in.new_nt_crypted = &hash4;
1332         r.in.cross1_present = 1;
1333         r.in.nt_cross = &hash5;
1334         r.in.cross2_present = 1;
1335         r.in.lm_cross = &hash6;
1336
1337         if (changed) {
1338                 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1339                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1340                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1341                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1342                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1343                         ret = False;
1344                 }
1345         }
1346
1347         
1348         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1349                 ret = False;
1350         }
1351
1352         return ret;
1353 }
1354
1355
1356 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1357                                         const char *acct_name,
1358                                         struct policy_handle *handle, char **password)
1359 {
1360         NTSTATUS status;
1361         struct samr_OemChangePasswordUser2 r;
1362         BOOL ret = True;
1363         struct samr_Password lm_verifier;
1364         struct samr_CryptPassword lm_pass;
1365         struct lsa_AsciiString server, account, account_bad;
1366         char *oldpass;
1367         char *newpass;
1368         uint8_t old_lm_hash[16], new_lm_hash[16];
1369
1370         struct samr_GetDomPwInfo dom_pw_info;
1371         int policy_min_pw_len = 0;
1372
1373         struct lsa_String domain_name;
1374
1375         domain_name.string = "";
1376         dom_pw_info.in.domain_name = &domain_name;
1377
1378         printf("Testing OemChangePasswordUser2\n");
1379
1380         if (!*password) {
1381                 printf("Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?\n");
1382                 return False;
1383         }
1384
1385         oldpass = *password;
1386
1387         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1388         if (NT_STATUS_IS_OK(status)) {
1389                 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1390         }
1391
1392         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1393
1394         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1395         account.string = acct_name;
1396
1397         E_deshash(oldpass, old_lm_hash);
1398         E_deshash(newpass, new_lm_hash);
1399
1400         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1401         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1402         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1403
1404         r.in.server = &server;
1405         r.in.account = &account;
1406         r.in.password = &lm_pass;
1407         r.in.hash = &lm_verifier;
1408
1409         /* Break the verification */
1410         lm_verifier.hash[0]++;
1411
1412         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1413
1414         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1415             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1416                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1417                         nt_errstr(status));
1418                 ret = False;
1419         }
1420
1421         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1422         /* Break the old password */
1423         old_lm_hash[0]++;
1424         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1425         /* unbreak it for the next operation */
1426         old_lm_hash[0]--;
1427         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1428
1429         r.in.server = &server;
1430         r.in.account = &account;
1431         r.in.password = &lm_pass;
1432         r.in.hash = &lm_verifier;
1433
1434         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1435
1436         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1437             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1438                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1439                         nt_errstr(status));
1440                 ret = False;
1441         }
1442
1443         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1444         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1445
1446         r.in.server = &server;
1447         r.in.account = &account;
1448         r.in.password = &lm_pass;
1449         r.in.hash = NULL;
1450
1451         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1452
1453         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1454             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1455                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1456                         nt_errstr(status));
1457                 ret = False;
1458         }
1459
1460         /* This shouldn't be a valid name */
1461         account_bad.string = TEST_ACCOUNT_NAME "XX";
1462         r.in.account = &account_bad;
1463
1464         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1465
1466         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1467                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1468                         nt_errstr(status));
1469                 ret = False;
1470         }
1471
1472         /* This shouldn't be a valid name */
1473         account_bad.string = TEST_ACCOUNT_NAME "XX";
1474         r.in.account = &account_bad;
1475         r.in.password = &lm_pass;
1476         r.in.hash = &lm_verifier;
1477
1478         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1479
1480         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1481                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1482                         nt_errstr(status));
1483                 ret = False;
1484         }
1485
1486         /* This shouldn't be a valid name */
1487         account_bad.string = TEST_ACCOUNT_NAME "XX";
1488         r.in.account = &account_bad;
1489         r.in.password = NULL;
1490         r.in.hash = &lm_verifier;
1491
1492         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1493
1494         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1495                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1496                         nt_errstr(status));
1497                 ret = False;
1498         }
1499
1500         E_deshash(oldpass, old_lm_hash);
1501         E_deshash(newpass, new_lm_hash);
1502
1503         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1504         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1505         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1506
1507         r.in.server = &server;
1508         r.in.account = &account;
1509         r.in.password = &lm_pass;
1510         r.in.hash = &lm_verifier;
1511
1512         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1513         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1514                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1515         } else if (!NT_STATUS_IS_OK(status)) {
1516                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1517                 ret = False;
1518         } else {
1519                 *password = newpass;
1520         }
1521
1522         return ret;
1523 }
1524
1525
1526 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1527                                      const char *acct_name,
1528                                      char **password,
1529                                      char *newpass, bool allow_password_restriction)
1530 {
1531         NTSTATUS status;
1532         struct samr_ChangePasswordUser2 r;
1533         BOOL ret = True;
1534         struct lsa_String server, account;
1535         struct samr_CryptPassword nt_pass, lm_pass;
1536         struct samr_Password nt_verifier, lm_verifier;
1537         char *oldpass;
1538         uint8_t old_nt_hash[16], new_nt_hash[16];
1539         uint8_t old_lm_hash[16], new_lm_hash[16];
1540
1541         struct samr_GetDomPwInfo dom_pw_info;
1542
1543         struct lsa_String domain_name;
1544
1545         domain_name.string = "";
1546         dom_pw_info.in.domain_name = &domain_name;
1547
1548         printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1549
1550         if (!*password) {
1551                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1552                 return False;
1553         }
1554         oldpass = *password;
1555
1556         if (!newpass) {
1557                 int policy_min_pw_len = 0;
1558                 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1559                 if (NT_STATUS_IS_OK(status)) {
1560                         policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1561                 }
1562
1563                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1564         } 
1565
1566         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1567         init_lsa_String(&account, acct_name);
1568
1569         E_md4hash(oldpass, old_nt_hash);
1570         E_md4hash(newpass, new_nt_hash);
1571
1572         E_deshash(oldpass, old_lm_hash);
1573         E_deshash(newpass, new_lm_hash);
1574
1575         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1576         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1577         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1578
1579         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1580         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1581         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1582
1583         r.in.server = &server;
1584         r.in.account = &account;
1585         r.in.nt_password = &nt_pass;
1586         r.in.nt_verifier = &nt_verifier;
1587         r.in.lm_change = 1;
1588         r.in.lm_password = &lm_pass;
1589         r.in.lm_verifier = &lm_verifier;
1590
1591         status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1592         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1593                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1594         } else if (!NT_STATUS_IS_OK(status)) {
1595                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1596                 ret = False;
1597         } else {
1598                 *password = newpass;
1599         }
1600
1601         return ret;
1602 }
1603
1604
1605 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1606                               const char *account_string,
1607                               int policy_min_pw_len,
1608                               char **password,
1609                               const char *newpass,
1610                               NTTIME last_password_change,
1611                               BOOL handle_reject_reason)
1612 {
1613         NTSTATUS status;
1614         struct samr_ChangePasswordUser3 r;
1615         BOOL ret = True;
1616         struct lsa_String server, account, account_bad;
1617         struct samr_CryptPassword nt_pass, lm_pass;
1618         struct samr_Password nt_verifier, lm_verifier;
1619         char *oldpass;
1620         uint8_t old_nt_hash[16], new_nt_hash[16];
1621         uint8_t old_lm_hash[16], new_lm_hash[16];
1622         NTTIME t;
1623
1624         printf("Testing ChangePasswordUser3\n");
1625
1626         if (newpass == NULL) {
1627                 do {
1628                         if (policy_min_pw_len == 0) {
1629                                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1630                         } else {
1631                                 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1632                         }
1633                 } while (check_password_quality(newpass) == False);
1634         } else {
1635                 printf("Using password '%s'\n", newpass);
1636         }
1637
1638         if (!*password) {
1639                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1640                 return False;
1641         }
1642
1643         oldpass = *password;
1644         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1645         init_lsa_String(&account, account_string);
1646
1647         E_md4hash(oldpass, old_nt_hash);
1648         E_md4hash(newpass, new_nt_hash);
1649
1650         E_deshash(oldpass, old_lm_hash);
1651         E_deshash(newpass, new_lm_hash);
1652
1653         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1654         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1655         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1656
1657         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1658         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1659         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1660         
1661         /* Break the verification */
1662         nt_verifier.hash[0]++;
1663
1664         r.in.server = &server;
1665         r.in.account = &account;
1666         r.in.nt_password = &nt_pass;
1667         r.in.nt_verifier = &nt_verifier;
1668         r.in.lm_change = 1;
1669         r.in.lm_password = &lm_pass;
1670         r.in.lm_verifier = &lm_verifier;
1671         r.in.password3 = NULL;
1672
1673         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1674         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1675             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1676                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1677                         nt_errstr(status));
1678                 ret = False;
1679         }
1680         
1681         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1682         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1683         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1684
1685         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1686         /* Break the NT hash */
1687         old_nt_hash[0]++;
1688         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1689         /* Unbreak it again */
1690         old_nt_hash[0]--;
1691         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1692         
1693         r.in.server = &server;
1694         r.in.account = &account;
1695         r.in.nt_password = &nt_pass;
1696         r.in.nt_verifier = &nt_verifier;
1697         r.in.lm_change = 1;
1698         r.in.lm_password = &lm_pass;
1699         r.in.lm_verifier = &lm_verifier;
1700         r.in.password3 = NULL;
1701
1702         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1703         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1704             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1705                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1706                         nt_errstr(status));
1707                 ret = False;
1708         }
1709         
1710         /* This shouldn't be a valid name */
1711         init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1712
1713         r.in.account = &account_bad;
1714         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1715         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1716                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1717                         nt_errstr(status));
1718                 ret = False;
1719         }
1720
1721         E_md4hash(oldpass, old_nt_hash);
1722         E_md4hash(newpass, new_nt_hash);
1723
1724         E_deshash(oldpass, old_lm_hash);
1725         E_deshash(newpass, new_lm_hash);
1726
1727         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1728         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1729         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1730
1731         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1732         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1733         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1734
1735         r.in.server = &server;
1736         r.in.account = &account;
1737         r.in.nt_password = &nt_pass;
1738         r.in.nt_verifier = &nt_verifier;
1739         r.in.lm_change = 1;
1740         r.in.lm_password = &lm_pass;
1741         r.in.lm_verifier = &lm_verifier;
1742         r.in.password3 = NULL;
1743
1744         unix_to_nt_time(&t, time(NULL));
1745
1746         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1747
1748         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1749             && r.out.dominfo
1750             && r.out.reject
1751             && handle_reject_reason
1752             && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1753                 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1754
1755                         if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1756                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1757                                         SAMR_REJECT_OTHER, r.out.reject->reason);
1758                                 return False;
1759                         }
1760                 }
1761
1762                 /* We tested the order of precendence which is as follows:
1763                 
1764                 * pwd min_age 
1765                 * pwd length
1766                 * pwd complexity
1767                 * pwd history
1768
1769                 Guenther */
1770
1771                 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) && 
1772                            (last_password_change + r.out.dominfo->min_password_age > t)) {
1773
1774                         if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1775                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1776                                         SAMR_REJECT_OTHER, r.out.reject->reason);
1777                                 return False;
1778                         }
1779
1780                 } else if ((r.out.dominfo->min_password_length > 0) && 
1781                            (strlen(newpass) < r.out.dominfo->min_password_length)) {
1782
1783                         if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1784                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
1785                                         SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1786                                 return False;
1787                         }
1788
1789                 } else if ((r.out.dominfo->password_history_length > 0) && 
1790                             strequal(oldpass, newpass)) {
1791
1792                         if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1793                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
1794                                         SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1795                                 return False;
1796                         }
1797                 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1798
1799                         if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1800                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
1801                                         SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1802                                 return False;
1803                         }
1804
1805                 }
1806
1807                 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1808                         /* retry with adjusted size */
1809                         return test_ChangePasswordUser3(p, mem_ctx, account_string, 
1810                                                         r.out.dominfo->min_password_length, 
1811                                                         password, NULL, 0, False); 
1812
1813                 }
1814
1815         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1816                 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1817                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1818                                SAMR_REJECT_OTHER, r.out.reject->reason);
1819                         return False;
1820                 }
1821                 /* Perhaps the server has a 'min password age' set? */
1822
1823         } else if (!NT_STATUS_IS_OK(status)) {
1824                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1825                 ret = False;
1826         } else {
1827                 *password = talloc_strdup(mem_ctx, newpass);
1828         }
1829
1830         return ret;
1831 }
1832
1833
1834 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1835                                   struct policy_handle *alias_handle)
1836 {
1837         struct samr_GetMembersInAlias r;
1838         struct lsa_SidArray sids;
1839         NTSTATUS status;
1840         BOOL     ret = True;
1841
1842         printf("Testing GetMembersInAlias\n");
1843
1844         r.in.alias_handle = alias_handle;
1845         r.out.sids = &sids;
1846
1847         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1848         if (!NT_STATUS_IS_OK(status)) {
1849                 printf("GetMembersInAlias failed - %s\n",
1850                        nt_errstr(status));
1851                 ret = False;
1852         }
1853
1854         return ret;
1855 }
1856
1857 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1858                                   struct policy_handle *alias_handle,
1859                                   const struct dom_sid *domain_sid)
1860 {
1861         struct samr_AddAliasMember r;
1862         struct samr_DeleteAliasMember d;
1863         NTSTATUS status;
1864         BOOL ret = True;
1865         struct dom_sid *sid;
1866
1867         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1868
1869         printf("testing AddAliasMember\n");
1870         r.in.alias_handle = alias_handle;
1871         r.in.sid = sid;
1872
1873         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1874         if (!NT_STATUS_IS_OK(status)) {
1875                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1876                 ret = False;
1877         }
1878
1879         d.in.alias_handle = alias_handle;
1880         d.in.sid = sid;
1881
1882         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1883         if (!NT_STATUS_IS_OK(status)) {
1884                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1885                 ret = False;
1886         }
1887
1888         return ret;
1889 }
1890
1891 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1892                                            struct policy_handle *alias_handle)
1893 {
1894         struct samr_AddMultipleMembersToAlias a;
1895         struct samr_RemoveMultipleMembersFromAlias r;
1896         NTSTATUS status;
1897         BOOL ret = True;
1898         struct lsa_SidArray sids;
1899
1900         printf("testing AddMultipleMembersToAlias\n");
1901         a.in.alias_handle = alias_handle;
1902         a.in.sids = &sids;
1903
1904         sids.num_sids = 3;
1905         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1906
1907         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1908         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1909         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1910
1911         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1912         if (!NT_STATUS_IS_OK(status)) {
1913                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1914                 ret = False;
1915         }
1916
1917
1918         printf("testing RemoveMultipleMembersFromAlias\n");
1919         r.in.alias_handle = alias_handle;
1920         r.in.sids = &sids;
1921
1922         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1923         if (!NT_STATUS_IS_OK(status)) {
1924                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1925                 ret = False;
1926         }
1927
1928         /* strange! removing twice doesn't give any error */
1929         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1930         if (!NT_STATUS_IS_OK(status)) {
1931                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1932                 ret = False;
1933         }
1934
1935         /* but removing an alias that isn't there does */
1936         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1937
1938         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1939         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1940                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1941                 ret = False;
1942         }
1943
1944         return ret;
1945 }
1946
1947 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1948                                             struct policy_handle *user_handle)
1949 {
1950         struct samr_TestPrivateFunctionsUser r;
1951         NTSTATUS status;
1952         BOOL ret = True;
1953
1954         printf("Testing TestPrivateFunctionsUser\n");
1955
1956         r.in.user_handle = user_handle;
1957
1958         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1959         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1960                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1961                 ret = False;
1962         }
1963
1964         return ret;
1965 }
1966
1967
1968 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1969                           struct policy_handle *user_handle, 
1970                           struct policy_handle *domain_handle, 
1971                           uint32_t base_acct_flags, 
1972                           const char *base_acct_name, enum torture_samr_choice which_ops)
1973 {
1974         TALLOC_CTX *user_ctx;
1975         char *password = NULL;
1976
1977         BOOL ret = True;
1978         int i;
1979         const uint32_t password_fields[] = {
1980                 SAMR_FIELD_PASSWORD,
1981                 SAMR_FIELD_PASSWORD2,
1982                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1983                 0
1984         };
1985         
1986         user_ctx = talloc_named(mem_ctx, 0, "test_user_ops per-user context");
1987         switch (which_ops) {
1988         case TORTURE_SAMR_USER_ATTRIBUTES:
1989                 if (!test_QuerySecurity(p, user_ctx, user_handle)) {
1990                         ret = False;
1991                 }
1992
1993                 if (!test_QueryUserInfo(p, user_ctx, user_handle)) {
1994                         ret = False;
1995                 }
1996
1997                 if (!test_QueryUserInfo2(p, user_ctx, user_handle)) {
1998                         ret = False;
1999                 }
2000
2001                 if (!test_SetUserInfo(p, user_ctx, user_handle, base_acct_flags,
2002                                       base_acct_name)) {
2003                         ret = False;
2004                 }       
2005
2006                 if (!test_GetUserPwInfo(p, user_ctx, user_handle)) {
2007                         ret = False;
2008                 }
2009
2010                 if (!test_TestPrivateFunctionsUser(p, user_ctx, user_handle)) {
2011                         ret = False;
2012                 }
2013
2014                 if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
2015                         ret = False;
2016                 }
2017                 break;
2018         case TORTURE_SAMR_PASSWORDS:
2019                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2020                         char simple_pass[9];
2021                         char *v = generate_random_str(mem_ctx, 1);
2022                         
2023                         ZERO_STRUCT(simple_pass);
2024                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
2025
2026                         printf("Testing machine account password policy rules\n");
2027
2028                         /* Workstation trust accounts don't seem to need to honour password quality policy */
2029                         if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2030                                 ret = False;
2031                         }
2032
2033                         if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, simple_pass, False)) {
2034                                 ret = False;
2035                         }
2036
2037                         /* reset again, to allow another 'user' password change */
2038                         if (!test_SetUserPassEx(p, user_ctx, user_handle, true, &password)) {
2039                                 ret = False;
2040                         }
2041
2042                         /* Try a 'short' password */
2043                         if (!test_ChangePasswordUser2(p, user_ctx, base_acct_name, &password, samr_rand_pass(mem_ctx, 4), False)) {
2044                                 ret = False;
2045                         }
2046                         
2047                 }
2048                 
2049                 for (i = 0; password_fields[i]; i++) {
2050                         if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
2051                                 ret = False;
2052                         }       
2053                 
2054                         /* check it was set right */
2055                         if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2056                                 ret = False;
2057                         }
2058                 }               
2059
2060                 for (i = 0; password_fields[i]; i++) {
2061                         if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
2062                                 ret = False;
2063                         }       
2064                 
2065                         /* check it was set right */
2066                         if (!test_ChangePasswordUser3(p, user_ctx, base_acct_name, 0, &password, NULL, 0, False)) {
2067                                 ret = False;
2068                         }
2069                 }               
2070
2071                 if (!test_SetUserPassEx(p, user_ctx, user_handle, false, &password)) {
2072                         ret = False;
2073                 }       
2074
2075                 if (!test_ChangePassword(p, user_ctx, base_acct_name, domain_handle, &password)) {
2076                         ret = False;
2077                 }       
2078
2079                 break;
2080         case TORTURE_SAMR_OTHER:
2081                 /* We just need the account to exist */
2082                 break;
2083         }
2084         talloc_free(user_ctx);
2085         return ret;
2086 }
2087
2088 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2089                            struct policy_handle *alias_handle,
2090                            const struct dom_sid *domain_sid)
2091 {
2092         BOOL ret = True;
2093
2094         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
2095                 ret = False;
2096         }
2097
2098         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
2099                 ret = False;
2100         }
2101
2102         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
2103                 ret = False;
2104         }
2105
2106         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
2107                 ret = False;
2108         }
2109
2110         if (lp_parm_bool(-1, "torture", "samba4", False)) {
2111                 printf("skipping MultipleMembers Alias tests against Samba4\n");
2112                 return ret;
2113         }
2114
2115         if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
2116                 ret = False;
2117         }
2118
2119         return ret;
2120 }
2121
2122
2123 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2124                                      struct policy_handle *user_handle)
2125 {
2126         struct samr_DeleteUser d;
2127         NTSTATUS status;
2128         BOOL ret = True;
2129         printf("Testing DeleteUser\n");
2130
2131         d.in.user_handle = user_handle;
2132         d.out.user_handle = user_handle;
2133
2134         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2135         if (!NT_STATUS_IS_OK(status)) {
2136                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2137                 ret = False;
2138         }
2139
2140         return ret;
2141 }
2142
2143 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2144                             struct policy_handle *handle, const char *name)
2145 {
2146         NTSTATUS status;
2147         struct samr_DeleteUser d;
2148         struct policy_handle user_handle;
2149         uint32_t rid;
2150
2151         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2152         if (!NT_STATUS_IS_OK(status)) {
2153                 goto failed;
2154         }
2155
2156         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2157         if (!NT_STATUS_IS_OK(status)) {
2158                 goto failed;
2159         }
2160
2161         d.in.user_handle = &user_handle;
2162         d.out.user_handle = &user_handle;
2163         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2164         if (!NT_STATUS_IS_OK(status)) {
2165                 goto failed;
2166         }
2167
2168         return True;
2169
2170 failed:
2171         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2172         return False;
2173 }
2174
2175
2176 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2177                                     struct policy_handle *handle, const char *name)
2178 {
2179         NTSTATUS status;
2180         struct samr_OpenGroup r;
2181         struct samr_DeleteDomainGroup d;
2182         struct policy_handle group_handle;
2183         uint32_t rid;
2184
2185         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2186         if (!NT_STATUS_IS_OK(status)) {
2187                 goto failed;
2188         }
2189
2190         r.in.domain_handle = handle;
2191         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2192         r.in.rid = rid;
2193         r.out.group_handle = &group_handle;
2194         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2195         if (!NT_STATUS_IS_OK(status)) {
2196                 goto failed;
2197         }
2198
2199         d.in.group_handle = &group_handle;
2200         d.out.group_handle = &group_handle;
2201         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2202         if (!NT_STATUS_IS_OK(status)) {
2203                 goto failed;
2204         }
2205
2206         return True;
2207
2208 failed:
2209         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2210         return False;
2211 }
2212
2213
2214 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2215                                    struct policy_handle *domain_handle, const char *name)
2216 {
2217         NTSTATUS status;
2218         struct samr_OpenAlias r;
2219         struct samr_DeleteDomAlias d;
2220         struct policy_handle alias_handle;
2221         uint32_t rid;
2222
2223         printf("testing DeleteAlias_byname\n");
2224
2225         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2226         if (!NT_STATUS_IS_OK(status)) {
2227                 goto failed;
2228         }
2229
2230         r.in.domain_handle = domain_handle;
2231         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2232         r.in.rid = rid;
2233         r.out.alias_handle = &alias_handle;
2234         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2235         if (!NT_STATUS_IS_OK(status)) {
2236                 goto failed;
2237         }
2238
2239         d.in.alias_handle = &alias_handle;
2240         d.out.alias_handle = &alias_handle;
2241         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2242         if (!NT_STATUS_IS_OK(status)) {
2243                 goto failed;
2244         }
2245
2246         return True;
2247
2248 failed:
2249         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2250         return False;
2251 }
2252
2253 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2254                                      struct policy_handle *alias_handle)
2255 {
2256         struct samr_DeleteDomAlias d;
2257         NTSTATUS status;
2258         BOOL ret = True;
2259         printf("Testing DeleteAlias\n");
2260
2261         d.in.alias_handle = alias_handle;
2262         d.out.alias_handle = alias_handle;
2263
2264         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2265         if (!NT_STATUS_IS_OK(status)) {
2266                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2267                 ret = False;
2268         }
2269
2270         return ret;
2271 }
2272
2273 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2274                             struct policy_handle *domain_handle, 
2275                              struct policy_handle *alias_handle, 
2276                              const struct dom_sid *domain_sid)
2277 {
2278         NTSTATUS status;
2279         struct samr_CreateDomAlias r;
2280         struct lsa_String name;
2281         uint32_t rid;
2282         BOOL ret = True;
2283
2284         init_lsa_String(&name, TEST_ALIASNAME);
2285         r.in.domain_handle = domain_handle;
2286         r.in.alias_name = &name;
2287         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2288         r.out.alias_handle = alias_handle;
2289         r.out.rid = &rid;
2290
2291         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2292
2293         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2294
2295         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2296                 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2297                 return True;
2298         }
2299
2300         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2301                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
2302                         return False;
2303                 }
2304                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
2305         }
2306
2307         if (!NT_STATUS_IS_OK(status)) {
2308                 printf("CreateAlias failed - %s\n", nt_errstr(status));
2309                 return False;
2310         }
2311
2312         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
2313                 ret = False;
2314         }
2315
2316         return ret;
2317 }
2318
2319 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2320                                 const char *acct_name,
2321                                 struct policy_handle *domain_handle, char **password)
2322 {
2323         BOOL ret = True;
2324
2325         if (!*password) {
2326                 return False;
2327         }
2328
2329         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2330                 ret = False;
2331         }
2332
2333         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, True)) {
2334                 ret = False;
2335         }
2336
2337         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2338                 ret = False;
2339         }
2340
2341         /* test what happens when setting the old password again */
2342         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, True)) {
2343                 ret = False;
2344         }
2345
2346         {
2347                 char simple_pass[9];
2348                 char *v = generate_random_str(mem_ctx, 1);
2349
2350                 ZERO_STRUCT(simple_pass);
2351                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2352
2353                 /* test what happens when picking a simple password */
2354                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, True)) {
2355                         ret = False;
2356                 }
2357         }
2358
2359         /* set samr_SetDomainInfo level 1 with min_length 5 */
2360         {
2361                 struct samr_QueryDomainInfo r;
2362                 struct samr_SetDomainInfo s;
2363                 uint16_t len_old, len;
2364                 uint32_t pwd_prop_old;
2365                 int64_t min_pwd_age_old;
2366                 NTSTATUS status;
2367
2368                 len = 5;
2369
2370                 r.in.domain_handle = domain_handle;
2371                 r.in.level = 1;
2372
2373                 printf("testing samr_QueryDomainInfo level 1\n");
2374                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2375                 if (!NT_STATUS_IS_OK(status)) {
2376                         return False;
2377                 }
2378
2379                 s.in.domain_handle = domain_handle;
2380                 s.in.level = 1;
2381                 s.in.info = r.out.info;
2382
2383                 /* remember the old min length, so we can reset it */
2384                 len_old = s.in.info->info1.min_password_length;
2385                 s.in.info->info1.min_password_length = len;
2386                 pwd_prop_old = s.in.info->info1.password_properties;
2387                 /* turn off password complexity checks for this test */
2388                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2389
2390                 min_pwd_age_old = s.in.info->info1.min_password_age;
2391                 s.in.info->info1.min_password_age = 0;
2392
2393                 printf("testing samr_SetDomainInfo level 1\n");
2394                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2395                 if (!NT_STATUS_IS_OK(status)) {
2396                         return False;
2397                 }
2398
2399                 printf("calling test_ChangePasswordUser3 with too short password\n");
2400
2401                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, True)) {
2402                         ret = False;
2403                 }
2404
2405                 s.in.info->info1.min_password_length = len_old;
2406                 s.in.info->info1.password_properties = pwd_prop_old;
2407                 s.in.info->info1.min_password_age = min_pwd_age_old;
2408                 
2409                 printf("testing samr_SetDomainInfo level 1\n");
2410                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2411                 if (!NT_STATUS_IS_OK(status)) {
2412                         return False;
2413                 }
2414
2415         }
2416
2417         {
2418                 NTSTATUS status;
2419                 struct samr_OpenUser r;
2420                 struct samr_QueryUserInfo q;
2421                 struct samr_LookupNames n;
2422                 struct policy_handle user_handle;
2423
2424                 n.in.domain_handle = domain_handle;
2425                 n.in.num_names = 1;
2426                 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2427                 n.in.names[0].string = acct_name; 
2428
2429                 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2430                 if (!NT_STATUS_IS_OK(status)) {
2431                         printf("LookupNames failed - %s\n", nt_errstr(status));
2432                         return False;
2433                 }
2434
2435                 r.in.domain_handle = domain_handle;
2436                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2437                 r.in.rid = n.out.rids.ids[0];
2438                 r.out.user_handle = &user_handle;
2439
2440                 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2441                 if (!NT_STATUS_IS_OK(status)) {
2442                         printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2443                         return False;
2444                 }
2445
2446                 q.in.user_handle = &user_handle;
2447                 q.in.level = 5;
2448
2449                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2450                 if (!NT_STATUS_IS_OK(status)) {
2451                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2452                         return False;
2453                 }
2454
2455                 printf("calling test_ChangePasswordUser3 with too early password change\n");
2456
2457                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
2458                                               q.out.info->info5.last_password_change, True)) {
2459                         ret = False;
2460                 }
2461         }
2462
2463         /* we change passwords twice - this has the effect of verifying
2464            they were changed correctly for the final call */
2465         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2466                 ret = False;
2467         }
2468
2469         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, True)) {
2470                 ret = False;
2471         }
2472
2473         return ret;
2474 }
2475
2476 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2477                             struct policy_handle *domain_handle, 
2478                             struct policy_handle *user_handle_out, 
2479                             enum torture_samr_choice which_ops)
2480 {
2481
2482         TALLOC_CTX *user_ctx;
2483
2484         NTSTATUS status;
2485         struct samr_CreateUser r;
2486         struct samr_QueryUserInfo q;
2487         struct samr_DeleteUser d;
2488         uint32_t rid;
2489
2490         /* This call creates a 'normal' account - check that it really does */
2491         const uint32_t acct_flags = ACB_NORMAL;
2492         struct lsa_String name;
2493         BOOL ret = True;
2494
2495         struct policy_handle user_handle;
2496         user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2497         init_lsa_String(&name, TEST_ACCOUNT_NAME);
2498
2499         r.in.domain_handle = domain_handle;
2500         r.in.account_name = &name;
2501         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2502         r.out.user_handle = &user_handle;
2503         r.out.rid = &rid;
2504
2505         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2506
2507         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2508
2509         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2510                 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2511                 talloc_free(user_ctx);
2512                 return True;
2513         }
2514
2515         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2516                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2517                         talloc_free(user_ctx);
2518                         return False;
2519                 }
2520                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2521         }
2522         if (!NT_STATUS_IS_OK(status)) {
2523                 talloc_free(user_ctx);
2524                 printf("CreateUser failed - %s\n", nt_errstr(status));
2525                 return False;
2526         } else {
2527                 q.in.user_handle = &user_handle;
2528                 q.in.level = 16;
2529                 
2530                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2531                 if (!NT_STATUS_IS_OK(status)) {
2532                         printf("QueryUserInfo level %u failed - %s\n", 
2533                                q.in.level, nt_errstr(status));
2534                         ret = False;
2535                 } else {
2536                         if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2537                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2538                                        q.out.info->info16.acct_flags, 
2539                                        acct_flags);
2540                                 ret = False;
2541                         }
2542                 }
2543                 
2544                 if (!test_user_ops(p, user_ctx, &user_handle, domain_handle, 
2545                                    acct_flags, name.string, which_ops)) {
2546                         ret = False;
2547                 }
2548                 
2549                 if (user_handle_out) {
2550                         *user_handle_out = user_handle;
2551                 } else {
2552                         printf("Testing DeleteUser (createuser test)\n");
2553                         
2554                         d.in.user_handle = &user_handle;
2555                         d.out.user_handle = &user_handle;
2556                         
2557                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2558                         if (!NT_STATUS_IS_OK(status)) {
2559                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2560                                 ret = False;
2561                         }
2562                 }
2563                 
2564         }
2565
2566         talloc_free(user_ctx);
2567         
2568         return ret;
2569 }
2570
2571
2572 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2573                              struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2574 {
2575         NTSTATUS status;
2576         struct samr_CreateUser2 r;
2577         struct samr_QueryUserInfo q;
2578         struct samr_DeleteUser d;
2579         struct policy_handle user_handle;
2580         uint32_t rid;
2581         struct lsa_String name;
2582         BOOL ret = True;
2583         int i;
2584
2585         struct {
2586                 uint32_t acct_flags;
2587                 const char *account_name;
2588                 NTSTATUS nt_status;
2589         } account_types[] = {
2590                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2591                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2592                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2593                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2594                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2595                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2596                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2597                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2598                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2599                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2600                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2601                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2602                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2603                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2604                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2605         };
2606
2607         for (i = 0; account_types[i].account_name; i++) {
2608                 TALLOC_CTX *user_ctx;
2609                 uint32_t acct_flags = account_types[i].acct_flags;
2610                 uint32_t access_granted;
2611                 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
2612                 init_lsa_String(&name, account_types[i].account_name);
2613
2614                 r.in.domain_handle = domain_handle;
2615                 r.in.account_name = &name;
2616                 r.in.acct_flags = acct_flags;
2617                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2618                 r.out.user_handle = &user_handle;
2619                 r.out.access_granted = &access_granted;
2620                 r.out.rid = &rid;
2621                 
2622                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2623                 
2624                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2625                 
2626                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2627                         talloc_free(user_ctx);
2628                         printf("Server refused create of '%s'\n", r.in.account_name->string);
2629                         continue;
2630
2631                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2632                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2633                                 talloc_free(user_ctx);
2634                                 ret = False;
2635                                 continue;
2636                         }
2637                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2638
2639                 }
2640                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2641                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
2642                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
2643                         ret = False;
2644                 }
2645                 
2646                 if (NT_STATUS_IS_OK(status)) {
2647                         q.in.user_handle = &user_handle;
2648                         q.in.level = 5;
2649                         
2650                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2651                         if (!NT_STATUS_IS_OK(status)) {
2652                                 printf("QueryUserInfo level %u failed - %s\n", 
2653                                        q.in.level, nt_errstr(status));
2654                                 ret = False;
2655                         } else {
2656                                 if ((q.out.info->info5.acct_flags & acct_flags) != acct_flags) {
2657                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2658                                                q.out.info->info5.acct_flags, 
2659                                                acct_flags);
2660                                         ret = False;
2661                                 } 
2662                                 switch (acct_flags) {
2663                                 case ACB_SVRTRUST:
2664                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2665                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", 
2666                                                        DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2667                                                 ret = False;
2668                                         }
2669                                         break;
2670                                 case ACB_WSTRUST:
2671                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2672                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", 
2673                                                        DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2674                                                 ret = False;
2675                                         }
2676                                         break;
2677                                 case ACB_NORMAL:
2678                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2679                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", 
2680                                                        DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2681                                                 ret = False;
2682                                         }
2683                                         break;
2684                                 }
2685                         }
2686                 
2687                         if (!test_user_ops(p, user_ctx, &user_handle, domain_handle, 
2688                                            acct_flags, name.string, which_ops)) {
2689                                 ret = False;
2690                         }
2691
2692                         printf("Testing DeleteUser (createuser2 test)\n");
2693                 
2694                         d.in.user_handle = &user_handle;
2695                         d.out.user_handle = &user_handle;
2696                         
2697                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2698                         if (!NT_STATUS_IS_OK(status)) {
2699                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2700                                 ret = False;
2701                         }
2702                 }
2703                 talloc_free(user_ctx);
2704         }
2705
2706         return ret;
2707 }
2708
2709 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2710                                 struct policy_handle *handle)
2711 {
2712         NTSTATUS status;
2713         struct samr_QueryAliasInfo r;
2714         uint16_t levels[] = {1, 2, 3};
2715         int i;
2716         BOOL ret = True;
2717
2718         for (i=0;i<ARRAY_SIZE(levels);i++) {
2719                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2720
2721                 r.in.alias_handle = handle;
2722                 r.in.level = levels[i];
2723
2724                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2725                 if (!NT_STATUS_IS_OK(status)) {
2726                         printf("QueryAliasInfo level %u failed - %s\n", 
2727                                levels[i], nt_errstr(status));
2728                         ret = False;
2729                 }
2730         }
2731
2732         return ret;
2733 }
2734
2735 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2736                                 struct policy_handle *handle)
2737 {
2738         NTSTATUS status;
2739         struct samr_QueryGroupInfo r;
2740         uint16_t levels[] = {1, 2, 3, 4, 5};
2741         int i;
2742         BOOL ret = True;
2743
2744         for (i=0;i<ARRAY_SIZE(levels);i++) {
2745                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2746
2747                 r.in.group_handle = handle;
2748                 r.in.level = levels[i];
2749
2750                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2751                 if (!NT_STATUS_IS_OK(status)) {
2752                         printf("QueryGroupInfo level %u failed - %s\n", 
2753                                levels[i], nt_errstr(status));
2754                         ret = False;
2755                 }
2756         }
2757
2758         return ret;
2759 }
2760
2761 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2762                                   struct policy_handle *handle)
2763 {
2764         NTSTATUS status;
2765         struct samr_QueryGroupMember r;
2766         BOOL ret = True;
2767
2768         printf("Testing QueryGroupMember\n");
2769
2770         r.in.group_handle = handle;
2771
2772         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2773         if (!NT_STATUS_IS_OK(status)) {
2774                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2775                 ret = False;
2776         }
2777
2778         return ret;
2779 }
2780
2781
2782 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2783                               struct policy_handle *handle)
2784 {
2785         NTSTATUS status;
2786         struct samr_QueryGroupInfo r;
2787         struct samr_SetGroupInfo s;
2788         uint16_t levels[] = {1, 2, 3, 4};
2789         uint16_t set_ok[] = {0, 1, 1, 1};
2790         int i;
2791         BOOL ret = True;
2792
2793         for (i=0;i<ARRAY_SIZE(levels);i++) {
2794                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2795
2796                 r.in.group_handle = handle;
2797                 r.in.level = levels[i];
2798
2799                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2800                 if (!NT_STATUS_IS_OK(status)) {
2801                         printf("QueryGroupInfo level %u failed - %s\n", 
2802                                levels[i], nt_errstr(status));
2803                         ret = False;
2804                 }
2805
2806                 printf("Testing SetGroupInfo level %u\n", levels[i]);
2807
2808                 s.in.group_handle = handle;
2809                 s.in.level = levels[i];
2810                 s.in.info = r.out.info;
2811
2812 #if 0
2813                 /* disabled this, as it changes the name only from the point of view of samr, 
2814                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
2815                    the name is still reserved, so creating the old name fails, but deleting by the old name
2816                    also fails */
2817                 if (s.in.level == 2) {
2818                         init_lsa_String(&s.in.info->string, "NewName");
2819                 }
2820 #endif
2821
2822                 if (s.in.level == 4) {
2823                         init_lsa_String(&s.in.info->description, "test description");
2824                 }
2825
2826                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2827                 if (set_ok[i]) {
2828                         if (!NT_STATUS_IS_OK(status)) {
2829                                 printf("SetGroupInfo level %u failed - %s\n", 
2830                                        r.in.level, nt_errstr(status));
2831                                 ret = False;
2832                                 continue;
2833                         }
2834                 } else {
2835                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2836                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2837                                        r.in.level, nt_errstr(status));
2838                                 ret = False;
2839                                 continue;
2840                         }
2841                 }
2842         }
2843
2844         return ret;
2845 }
2846
2847 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2848                                struct policy_handle *handle)
2849 {
2850         NTSTATUS status;
2851         struct samr_QueryUserInfo r;
2852         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2853                            11, 12, 13, 14, 16, 17, 20, 21};
2854         int i;
2855         BOOL ret = True;
2856
2857         for (i=0;i<ARRAY_SIZE(levels);i++) {
2858                 printf("Testing QueryUserInfo level %u\n", levels[i]);
2859
2860                 r.in.user_handle = handle;
2861                 r.in.level = levels[i];
2862
2863                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2864                 if (!NT_STATUS_IS_OK(status)) {
2865                         printf("QueryUserInfo level %u failed - %s\n", 
2866                                levels[i], nt_errstr(status));
2867                         ret = False;
2868                 }
2869         }
2870
2871         return ret;
2872 }
2873
2874 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2875                                 struct policy_handle *handle)
2876 {
2877         NTSTATUS status;
2878         struct samr_QueryUserInfo2 r;
2879         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2880                            11, 12, 13, 14, 16, 17, 20, 21};
2881         int i;
2882         BOOL ret = True;
2883
2884         for (i=0;i<ARRAY_SIZE(levels);i++) {
2885                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2886
2887                 r.in.user_handle = handle;
2888                 r.in.level = levels[i];
2889
2890                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2891                 if (!NT_STATUS_IS_OK(status)) {
2892                         printf("QueryUserInfo2 level %u failed - %s\n", 
2893                                levels[i], nt_errstr(status));
2894                         ret = False;
2895                 }
2896         }
2897
2898         return ret;
2899 }
2900
2901 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2902                           struct policy_handle *handle, uint32_t rid)
2903 {
2904         NTSTATUS status;
2905         struct samr_OpenUser r;
2906         struct policy_handle user_handle;
2907         BOOL ret = True;
2908
2909         printf("Testing OpenUser(%u)\n", rid);
2910
2911         r.in.domain_handle = handle;
2912         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2913         r.in.rid = rid;
2914         r.out.user_handle = &user_handle;
2915
2916         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2917         if (!NT_STATUS_IS_OK(status)) {
2918                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2919                 return False;
2920         }
2921
2922         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2923                 ret = False;
2924         }
2925
2926         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2927                 ret = False;
2928         }
2929
2930         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2931                 ret = False;
2932         }
2933
2934         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2935                 ret = False;
2936         }
2937
2938         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2939                 ret = False;
2940         }
2941
2942         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2943                 ret = False;
2944         }
2945
2946         return ret;
2947 }
2948
2949 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2950                            struct policy_handle *handle, uint32_t rid)
2951 {
2952         NTSTATUS status;
2953         struct samr_OpenGroup r;
2954         struct policy_handle group_handle;
2955         BOOL ret = True;
2956
2957         printf("Testing OpenGroup(%u)\n", rid);
2958
2959         r.in.domain_handle = handle;
2960         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2961         r.in.rid = rid;
2962         r.out.group_handle = &group_handle;
2963
2964         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2965         if (!NT_STATUS_IS_OK(status)) {
2966                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2967                 return False;
2968         }
2969
2970         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2971                 ret = False;
2972         }
2973
2974         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2975                 ret = False;
2976         }
2977
2978         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2979                 ret = False;
2980         }
2981
2982         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2983                 ret = False;
2984         }
2985
2986         return ret;
2987 }
2988
2989 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2990                            struct policy_handle *handle, uint32_t rid)
2991 {
2992         NTSTATUS status;
2993         struct samr_OpenAlias r;
2994         struct policy_handle alias_handle;
2995         BOOL ret = True;
2996
2997         printf("Testing OpenAlias(%u)\n", rid);
2998
2999         r.in.domain_handle = handle;
3000         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3001         r.in.rid = rid;
3002         r.out.alias_handle = &alias_handle;
3003
3004         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3005         if (!NT_STATUS_IS_OK(status)) {
3006                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3007                 return False;
3008         }
3009
3010         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3011                 ret = False;
3012         }
3013
3014         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3015                 ret = False;
3016         }
3017
3018         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3019                 ret = False;
3020         }
3021
3022         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3023                 ret = False;
3024         }
3025
3026         return ret;
3027 }
3028
3029 static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3030                        struct policy_handle *handle, uint32_t rid, 
3031                        uint32_t acct_flag_mask)
3032 {
3033         NTSTATUS status;
3034         struct samr_OpenUser r;
3035         struct samr_QueryUserInfo q;
3036         struct policy_handle user_handle;
3037         BOOL ret = True;
3038
3039         printf("Testing OpenUser(%u)\n", rid);
3040
3041         r.in.domain_handle = handle;
3042         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3043         r.in.rid = rid;
3044         r.out.user_handle = &user_handle;
3045
3046         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3047         if (!NT_STATUS_IS_OK(status)) {
3048                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3049                 return False;
3050         }
3051
3052         q.in.user_handle = &user_handle;
3053         q.in.level = 16;
3054         
3055         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3056         if (!NT_STATUS_IS_OK(status)) {
3057                 printf("QueryUserInfo level 16 failed - %s\n", 
3058                        nt_errstr(status));
3059                 ret = False;
3060         } else {
3061                 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3062                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3063                                acct_flag_mask, q.out.info->info16.acct_flags, rid);
3064                         ret = False;
3065                 }
3066         }
3067         
3068         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3069                 ret = False;
3070         }
3071
3072         return ret;
3073 }
3074
3075 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3076                                  struct policy_handle *handle)
3077 {
3078         NTSTATUS status = STATUS_MORE_ENTRIES;
3079         struct samr_EnumDomainUsers r;
3080         uint32_t mask, resume_handle=0;
3081         int i, mask_idx;
3082         BOOL ret = True;
3083         struct samr_LookupNames n;
3084         struct samr_LookupRids  lr ;
3085         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
3086                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
3087                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
3088                             ACB_PWNOEXP, 0};
3089
3090         printf("Testing EnumDomainUsers\n");
3091
3092         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3093                 r.in.domain_handle = handle;
3094                 r.in.resume_handle = &resume_handle;
3095                 r.in.acct_flags = mask = masks[mask_idx];
3096                 r.in.max_size = (uint32_t)-1;
3097                 r.out.resume_handle = &resume_handle;
3098
3099                 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3100                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
3101                     !NT_STATUS_IS_OK(status)) {
3102                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3103                         return False;
3104                 }
3105         
3106                 if (!r.out.sam) {
3107                         printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3108                         return False;
3109                 }
3110
3111                 if (r.out.sam->count == 0) {
3112                         continue;
3113                 }
3114
3115                 for (i=0;i<r.out.sam->count;i++) {
3116                         if (mask) {
3117                                 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3118                                         ret = False;
3119                                 }
3120                         } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3121                                 ret = False;
3122                         }
3123                 }
3124         }
3125
3126         printf("Testing LookupNames\n");
3127         n.in.domain_handle = handle;
3128         n.in.num_names = r.out.sam->count;
3129         n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3130         for (i=0;i<r.out.sam->count;i++) {
3131                 n.in.names[i].string = r.out.sam->entries[i].name.string;
3132         }
3133         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3134         if (!NT_STATUS_IS_OK(status)) {
3135                 printf("LookupNames failed - %s\n", nt_errstr(status));
3136                 ret = False;
3137         }
3138
3139
3140         printf("Testing LookupRids\n");
3141         lr.in.domain_handle = handle;
3142         lr.in.num_rids = r.out.sam->count;
3143         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3144         for (i=0;i<r.out.sam->count;i++) {
3145                 lr.in.rids[i] = r.out.sam->entries[i].idx;
3146         }
3147         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3148         if (!NT_STATUS_IS_OK(status)) {
3149                 printf("LookupRids failed - %s\n", nt_errstr(status));
3150                 ret = False;
3151         }
3152
3153         return ret;     
3154 }
3155
3156 /*
3157   try blasting the server with a bunch of sync requests
3158 */
3159 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3160                                        struct policy_handle *handle)
3161 {
3162         NTSTATUS status;
3163         struct samr_EnumDomainUsers r;
3164         uint32_t resume_handle=0;
3165         int i;
3166 #define ASYNC_COUNT 100
3167         struct rpc_request *req[ASYNC_COUNT];
3168
3169         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
3170                 printf("samr async test disabled - enable dangerous tests to use\n");
3171                 return True;
3172         }
3173
3174         printf("Testing EnumDomainUsers_async\n");
3175
3176         r.in.domain_handle = handle;
3177         r.in.resume_handle = &resume_handle;
3178         r.in.acct_flags = 0;
3179         r.in.max_size = (uint32_t)-1;
3180         r.out.resume_handle = &resume_handle;
3181
3182         for (i=0;i<ASYNC_COUNT;i++) {
3183                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
3184         }
3185
3186         for (i=0;i<ASYNC_COUNT;i++) {
3187                 status = dcerpc_ndr_request_recv(req[i]);
3188                 if (!NT_STATUS_IS_OK(status)) {
3189                         printf("EnumDomainUsers[%d] failed - %s\n", 
3190                                i, nt_errstr(status));
3191                         return False;
3192                 }
3193         }
3194         
3195         printf("%d async requests OK\n", i);
3196