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