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