s3-samr: more accurateness in _samr_SetDomainInfo().
[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_netlogon.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "libcli/security/security.h"
32 #include "torture/rpc/rpc.h"
33 #include "param/param.h"
34
35 #include <unistd.h>
36
37 #define TEST_ACCOUNT_NAME "samrtorturetest"
38 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
39 #define TEST_ALIASNAME "samrtorturetestalias"
40 #define TEST_GROUPNAME "samrtorturetestgroup"
41 #define TEST_MACHINENAME "samrtestmach$"
42 #define TEST_DOMAINNAME "samrtestdom$"
43
44 enum torture_samr_choice {
45         TORTURE_SAMR_PASSWORDS,
46         TORTURE_SAMR_PASSWORDS_PWDLASTSET,
47         TORTURE_SAMR_USER_ATTRIBUTES,
48         TORTURE_SAMR_OTHER
49 };
50
51 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
52                                struct policy_handle *handle);
53
54 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
55                                 struct policy_handle *handle);
56
57 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
58                                struct policy_handle *handle);
59
60 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
61                                 const char *acct_name, 
62                                 struct policy_handle *domain_handle, char **password);
63
64 static void init_lsa_String(struct lsa_String *string, const char *s)
65 {
66         string->string = s;
67 }
68
69 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
70 {
71         string->length = length;
72         string->size = length;
73         string->array = (uint16_t *)discard_const(s);
74 }
75
76 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
77                                    struct policy_handle *handle)
78 {
79         NTSTATUS status;
80         struct samr_Close r;
81
82         r.in.handle = handle;
83         r.out.handle = handle;
84
85         status = dcerpc_samr_Close(p, tctx, &r);
86         torture_assert_ntstatus_ok(tctx, status, "Close");
87
88         return true;
89 }
90
91 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
92                        struct policy_handle *handle)
93 {
94         NTSTATUS status;
95         struct samr_Shutdown r;
96
97         if (!torture_setting_bool(tctx, "dangerous", false)) {
98                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
99                 return true;
100         }
101
102         r.in.connect_handle = handle;
103
104         torture_comment(tctx, "testing samr_Shutdown\n");
105
106         status = dcerpc_samr_Shutdown(p, tctx, &r);
107         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
108
109         return true;
110 }
111
112 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
113                                  struct policy_handle *handle)
114 {
115         NTSTATUS status;
116         struct samr_SetDsrmPassword r;
117         struct lsa_String string;
118         struct samr_Password hash;
119
120         if (!torture_setting_bool(tctx, "dangerous", false)) {
121                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
122         }
123
124         E_md4hash("TeSTDSRM123", hash.hash);
125
126         init_lsa_String(&string, "Administrator");
127
128         r.in.name = &string;
129         r.in.unknown = 0;
130         r.in.hash = &hash;
131
132         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
133
134         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
135         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
136
137         return true;
138 }
139
140
141 static bool test_QuerySecurity(struct dcerpc_pipe *p, 
142                                struct torture_context *tctx, 
143                                struct policy_handle *handle)
144 {
145         NTSTATUS status;
146         struct samr_QuerySecurity r;
147         struct samr_SetSecurity s;
148         struct sec_desc_buf *sdbuf = NULL;
149
150         r.in.handle = handle;
151         r.in.sec_info = 7;
152         r.out.sdbuf = &sdbuf;
153
154         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
155         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
156
157         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
158
159         s.in.handle = handle;
160         s.in.sec_info = 7;
161         s.in.sdbuf = sdbuf;
162
163         if (torture_setting_bool(tctx, "samba4", false)) {
164                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
165         }
166
167         status = dcerpc_samr_SetSecurity(p, tctx, &s);
168         torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
169
170         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
171         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
172
173         return true;
174 }
175
176
177 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx, 
178                              struct policy_handle *handle, uint32_t base_acct_flags,
179                              const char *base_account_name)
180 {
181         NTSTATUS status;
182         struct samr_SetUserInfo s;
183         struct samr_SetUserInfo2 s2;
184         struct samr_QueryUserInfo q;
185         struct samr_QueryUserInfo q0;
186         union samr_UserInfo u;
187         union samr_UserInfo *info;
188         bool ret = true;
189         const char *test_account_name;
190
191         uint32_t user_extra_flags = 0;
192         if (base_acct_flags == ACB_NORMAL) {
193                 /* When created, accounts are expired by default */
194                 user_extra_flags = ACB_PW_EXPIRED;
195         }
196
197         s.in.user_handle = handle;
198         s.in.info = &u;
199
200         s2.in.user_handle = handle;
201         s2.in.info = &u;
202
203         q.in.user_handle = handle;
204         q.out.info = &info;
205         q0 = q;
206
207 #define TESTCALL(call, r) \
208                 status = dcerpc_samr_ ##call(p, tctx, &r); \
209                 if (!NT_STATUS_IS_OK(status)) { \
210                         torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
211                                r.in.level, nt_errstr(status), __location__); \
212                         ret = false; \
213                         break; \
214                 }
215
216 #define STRING_EQUAL(s1, s2, field) \
217                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
218                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
219                                #field, s2, __location__); \
220                         ret = false; \
221                         break; \
222                 }
223
224 #define MEM_EQUAL(s1, s2, length, field) \
225                 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
226                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
227                                #field, (const char *)s2, __location__); \
228                         ret = false; \
229                         break; \
230                 }
231
232 #define INT_EQUAL(i1, i2, field) \
233                 if (i1 != i2) { \
234                         torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
235                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
236                         ret = false; \
237                         break; \
238                 }
239
240 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
241                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
242                 q.in.level = lvl1; \
243                 TESTCALL(QueryUserInfo, q) \
244                 s.in.level = lvl1; \
245                 s2.in.level = lvl1; \
246                 u = *info; \
247                 if (lvl1 == 21) { \
248                         ZERO_STRUCT(u.info21); \
249                         u.info21.fields_present = fpval; \
250                 } \
251                 init_lsa_String(&u.info ## lvl1.field1, value); \
252                 TESTCALL(SetUserInfo, s) \
253                 TESTCALL(SetUserInfo2, s2) \
254                 init_lsa_String(&u.info ## lvl1.field1, ""); \
255                 TESTCALL(QueryUserInfo, q); \
256                 u = *info; \
257                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
258                 q.in.level = lvl2; \
259                 TESTCALL(QueryUserInfo, q) \
260                 u = *info; \
261                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
262         } while (0)
263
264 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
265                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
266                 q.in.level = lvl1; \
267                 TESTCALL(QueryUserInfo, q) \
268                 s.in.level = lvl1; \
269                 s2.in.level = lvl1; \
270                 u = *info; \
271                 if (lvl1 == 21) { \
272                         ZERO_STRUCT(u.info21); \
273                         u.info21.fields_present = fpval; \
274                 } \
275                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
276                 TESTCALL(SetUserInfo, s) \
277                 TESTCALL(SetUserInfo2, s2) \
278                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
279                 TESTCALL(QueryUserInfo, q); \
280                 u = *info; \
281                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
282                 q.in.level = lvl2; \
283                 TESTCALL(QueryUserInfo, q) \
284                 u = *info; \
285                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
286         } while (0)
287
288 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
289                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
290                 q.in.level = lvl1; \
291                 TESTCALL(QueryUserInfo, q) \
292                 s.in.level = lvl1; \
293                 s2.in.level = lvl1; \
294                 u = *info; \
295                 if (lvl1 == 21) { \
296                         uint8_t *bits = u.info21.logon_hours.bits; \
297                         ZERO_STRUCT(u.info21); \
298                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
299                                 u.info21.logon_hours.units_per_week = 168; \
300                                 u.info21.logon_hours.bits = bits; \
301                         } \
302                         u.info21.fields_present = fpval; \
303                 } \
304                 u.info ## lvl1.field1 = value; \
305                 TESTCALL(SetUserInfo, s) \
306                 TESTCALL(SetUserInfo2, s2) \
307                 u.info ## lvl1.field1 = 0; \
308                 TESTCALL(QueryUserInfo, q); \
309                 u = *info; \
310                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
311                 q.in.level = lvl2; \
312                 TESTCALL(QueryUserInfo, q) \
313                 u = *info; \
314                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
315         } while (0)
316
317 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
318         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
319         } while (0)
320
321         q0.in.level = 12;
322         do { TESTCALL(QueryUserInfo, q0) } while (0);
323
324         /* Samba 3 cannot store comment fields atm. - gd */
325         if (!torture_setting_bool(tctx, "samba3", false)) {
326                 TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
327                 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
328                 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
329                                    SAMR_FIELD_COMMENT);
330         }
331
332         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
333         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
334         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
335         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
336         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
337         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
338         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
339         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
340         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
341         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
342         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
343         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
344         test_account_name = base_account_name;
345         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name, 
346                            SAMR_FIELD_ACCOUNT_NAME);
347
348         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
349         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
350         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
351         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
352         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
353         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
354         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
355         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name", 
356                            SAMR_FIELD_FULL_NAME);
357
358         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
359         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
360         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
361         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
362         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
363         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
364         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
365         TEST_USERINFO_STRING(21, full_name, 21, full_name, "", 
366                            SAMR_FIELD_FULL_NAME);
367
368         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
369         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
370         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
371         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
372                            SAMR_FIELD_LOGON_SCRIPT);
373
374         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
375         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
376         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
377         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
378                            SAMR_FIELD_PROFILE_PATH);
379
380         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
381         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
382         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
383         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
384                              SAMR_FIELD_HOME_DIRECTORY);
385         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
386                              SAMR_FIELD_HOME_DIRECTORY);
387
388         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
389         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
390         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
391         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
392                              SAMR_FIELD_HOME_DRIVE);
393         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
394                              SAMR_FIELD_HOME_DRIVE);
395         
396         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
397         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
398         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
399         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
400                            SAMR_FIELD_DESCRIPTION);
401
402         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
403         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
404         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
405         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
406                            SAMR_FIELD_WORKSTATIONS);
407         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3", 
408                            SAMR_FIELD_WORKSTATIONS);
409         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5", 
410                            SAMR_FIELD_WORKSTATIONS);
411         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", 
412                            SAMR_FIELD_WORKSTATIONS);
413
414         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
415         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
416                            SAMR_FIELD_PARAMETERS);
417         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
418                            SAMR_FIELD_PARAMETERS);
419         /* also empty user parameters are allowed */
420         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
421         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
422                            SAMR_FIELD_PARAMETERS);
423         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
424                            SAMR_FIELD_PARAMETERS);
425
426         /* Samba 3 cannot store country_code and copy_page atm. - gd */
427         if (!torture_setting_bool(tctx, "samba3", false)) {
428                 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
429                 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
430                 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
431                                   SAMR_FIELD_COUNTRY_CODE);
432                 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
433                                   SAMR_FIELD_COUNTRY_CODE);
434
435                 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
436                 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
437                                   SAMR_FIELD_CODE_PAGE);
438                 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
439                                   SAMR_FIELD_CODE_PAGE);
440         }
441
442         if (!torture_setting_bool(tctx, "samba3", false)) {
443                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
444                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
445                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
446                                   SAMR_FIELD_ACCT_EXPIRY);
447                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
448                                   SAMR_FIELD_ACCT_EXPIRY);
449                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
450                                   SAMR_FIELD_ACCT_EXPIRY);
451         } else {
452                 /* Samba 3 can only store seconds / time_t in passdb - gd */
453                 NTTIME nt;
454                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
455                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
456                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
457                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
458                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
459                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
460                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
461                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
462                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
463                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
464         }
465
466         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
467         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
468         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
469         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
470                           SAMR_FIELD_LOGON_HOURS);
471
472         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
473                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
474                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
475                               0);
476         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
477                               (base_acct_flags  | ACB_DISABLED), 
478                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
479                               0);
480         
481         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
482         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
483                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
484                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
485                               0);
486         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
487                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
488                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
489                               0);
490
491
492         /* The 'autolock' flag doesn't stick - check this */
493         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
494                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
495                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
496                               0);
497 #if 0
498         /* Removing the 'disabled' flag doesn't stick - check this */
499         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
500                               (base_acct_flags), 
501                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
502                               0);
503 #endif
504         /* The 'store plaintext' flag does stick */
505         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
506                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
507                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
508                               0);
509         /* The 'use DES' flag does stick */
510         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
511                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
512                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
513                               0);
514         /* The 'don't require kerberos pre-authentication flag does stick */
515         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
516                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
517                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
518                               0);
519         /* The 'no kerberos PAC required' flag sticks */
520         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
521                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
522                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
523                               0);
524
525         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
526                               (base_acct_flags | ACB_DISABLED), 
527                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
528                               SAMR_FIELD_ACCT_FLAGS);
529
530 #if 0
531         /* these fail with win2003 - it appears you can't set the primary gid?
532            the set succeeds, but the gid isn't changed. Very weird! */
533         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
534         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
535         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
536         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
537 #endif
538
539         return ret;
540 }
541
542 /*
543   generate a random password for password change tests
544 */
545 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
546 {
547         size_t len = MAX(8, min_len) + (random() % 6);
548         char *s = generate_random_str(mem_ctx, len);
549         return s;
550 }
551
552 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
553 {
554         char *s = samr_rand_pass_silent(mem_ctx, min_len);
555         printf("Generated password '%s'\n", s);
556         return s;
557
558 }
559
560 /*
561   generate a random password for password change tests
562 */
563 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
564 {
565         int i;
566         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
567         generate_random_buffer(password.data, password.length);
568
569         for (i=0; i < len; i++) {
570                 if (((uint16_t *)password.data)[i] == 0) {
571                         ((uint16_t *)password.data)[i] = 1;
572                 }
573         }
574
575         return password;
576 }
577
578 /*
579   generate a random password for password change tests (fixed length)
580 */
581 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
582 {
583         char *s = generate_random_str(mem_ctx, len);
584         printf("Generated password '%s'\n", s);
585         return s;
586 }
587
588 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
589                              struct policy_handle *handle, char **password)
590 {
591         NTSTATUS status;
592         struct samr_SetUserInfo s;
593         union samr_UserInfo u;
594         bool ret = true;
595         DATA_BLOB session_key;
596         char *newpass;
597         struct samr_GetUserPwInfo pwp;
598         struct samr_PwInfo info;
599         int policy_min_pw_len = 0;
600         pwp.in.user_handle = handle;
601         pwp.out.info = &info;
602
603         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
604         if (NT_STATUS_IS_OK(status)) {
605                 policy_min_pw_len = pwp.out.info->min_password_length;
606         }
607         newpass = samr_rand_pass(tctx, policy_min_pw_len);
608
609         s.in.user_handle = handle;
610         s.in.info = &u;
611         s.in.level = 24;
612
613         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
614         u.info24.password_expired = 0;
615
616         status = dcerpc_fetch_session_key(p, &session_key);
617         if (!NT_STATUS_IS_OK(status)) {
618                 printf("SetUserInfo level %u - no session key - %s\n",
619                        s.in.level, nt_errstr(status));
620                 return false;
621         }
622
623         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
624
625         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
626
627         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
628         if (!NT_STATUS_IS_OK(status)) {
629                 printf("SetUserInfo level %u failed - %s\n",
630                        s.in.level, nt_errstr(status));
631                 ret = false;
632         } else {
633                 *password = newpass;
634         }
635
636         return ret;
637 }
638
639
640 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
641                                 struct policy_handle *handle, uint32_t fields_present,
642                                 char **password)
643 {
644         NTSTATUS status;
645         struct samr_SetUserInfo s;
646         union samr_UserInfo u;
647         bool ret = true;
648         DATA_BLOB session_key;
649         char *newpass;
650         struct samr_GetUserPwInfo pwp;
651         struct samr_PwInfo info;
652         int policy_min_pw_len = 0;
653         pwp.in.user_handle = handle;
654         pwp.out.info = &info;
655
656         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
657         if (NT_STATUS_IS_OK(status)) {
658                 policy_min_pw_len = pwp.out.info->min_password_length;
659         }
660         newpass = samr_rand_pass(tctx, policy_min_pw_len);
661
662         s.in.user_handle = handle;
663         s.in.info = &u;
664         s.in.level = 23;
665
666         ZERO_STRUCT(u);
667
668         u.info23.info.fields_present = fields_present;
669
670         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
671
672         status = dcerpc_fetch_session_key(p, &session_key);
673         if (!NT_STATUS_IS_OK(status)) {
674                 printf("SetUserInfo level %u - no session key - %s\n",
675                        s.in.level, nt_errstr(status));
676                 return false;
677         }
678
679         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
680
681         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
682
683         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
684         if (!NT_STATUS_IS_OK(status)) {
685                 printf("SetUserInfo level %u failed - %s\n",
686                        s.in.level, nt_errstr(status));
687                 ret = false;
688         } else {
689                 *password = newpass;
690         }
691
692         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
693
694         status = dcerpc_fetch_session_key(p, &session_key);
695         if (!NT_STATUS_IS_OK(status)) {
696                 printf("SetUserInfo level %u - no session key - %s\n",
697                        s.in.level, nt_errstr(status));
698                 return false;
699         }
700
701         /* This should break the key nicely */
702         session_key.length--;
703         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
704
705         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
706
707         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
708         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
709                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
710                        s.in.level, nt_errstr(status));
711                 ret = false;
712         }
713
714         return ret;
715 }
716
717
718 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
719                                struct policy_handle *handle, bool makeshort, 
720                                char **password)
721 {
722         NTSTATUS status;
723         struct samr_SetUserInfo s;
724         union samr_UserInfo u;
725         bool ret = true;
726         DATA_BLOB session_key;
727         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
728         uint8_t confounder[16];
729         char *newpass;
730         struct MD5Context ctx;
731         struct samr_GetUserPwInfo pwp;
732         struct samr_PwInfo info;
733         int policy_min_pw_len = 0;
734         pwp.in.user_handle = handle;
735         pwp.out.info = &info;
736
737         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
738         if (NT_STATUS_IS_OK(status)) {
739                 policy_min_pw_len = pwp.out.info->min_password_length;
740         }
741         if (makeshort && policy_min_pw_len) {
742                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
743         } else {
744                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
745         }
746
747         s.in.user_handle = handle;
748         s.in.info = &u;
749         s.in.level = 26;
750
751         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
752         u.info26.password_expired = 0;
753
754         status = dcerpc_fetch_session_key(p, &session_key);
755         if (!NT_STATUS_IS_OK(status)) {
756                 printf("SetUserInfo level %u - no session key - %s\n",
757                        s.in.level, nt_errstr(status));
758                 return false;
759         }
760
761         generate_random_buffer((uint8_t *)confounder, 16);
762
763         MD5Init(&ctx);
764         MD5Update(&ctx, confounder, 16);
765         MD5Update(&ctx, session_key.data, session_key.length);
766         MD5Final(confounded_session_key.data, &ctx);
767
768         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
769         memcpy(&u.info26.password.data[516], confounder, 16);
770
771         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
772
773         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
774         if (!NT_STATUS_IS_OK(status)) {
775                 printf("SetUserInfo level %u failed - %s\n",
776                        s.in.level, nt_errstr(status));
777                 ret = false;
778         } else {
779                 *password = newpass;
780         }
781
782         /* This should break the key nicely */
783         confounded_session_key.data[0]++;
784
785         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
786         memcpy(&u.info26.password.data[516], confounder, 16);
787
788         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
789
790         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
791         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
792                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
793                        s.in.level, nt_errstr(status));
794                 ret = false;
795         } else {
796                 *password = newpass;
797         }
798
799         return ret;
800 }
801
802 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
803                                 struct policy_handle *handle, uint32_t fields_present,
804                                 char **password)
805 {
806         NTSTATUS status;
807         struct samr_SetUserInfo s;
808         union samr_UserInfo u;
809         bool ret = true;
810         DATA_BLOB session_key;
811         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
812         struct MD5Context ctx;
813         uint8_t confounder[16];
814         char *newpass;
815         struct samr_GetUserPwInfo pwp;
816         struct samr_PwInfo info;
817         int policy_min_pw_len = 0;
818         pwp.in.user_handle = handle;
819         pwp.out.info = &info;
820
821         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
822         if (NT_STATUS_IS_OK(status)) {
823                 policy_min_pw_len = pwp.out.info->min_password_length;
824         }
825         newpass = samr_rand_pass(tctx, policy_min_pw_len);
826
827         s.in.user_handle = handle;
828         s.in.info = &u;
829         s.in.level = 25;
830
831         ZERO_STRUCT(u);
832
833         u.info25.info.fields_present = fields_present;
834
835         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
836
837         status = dcerpc_fetch_session_key(p, &session_key);
838         if (!NT_STATUS_IS_OK(status)) {
839                 printf("SetUserInfo level %u - no session key - %s\n",
840                        s.in.level, nt_errstr(status));
841                 return false;
842         }
843
844         generate_random_buffer((uint8_t *)confounder, 16);
845
846         MD5Init(&ctx);
847         MD5Update(&ctx, confounder, 16);
848         MD5Update(&ctx, session_key.data, session_key.length);
849         MD5Final(confounded_session_key.data, &ctx);
850
851         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
852         memcpy(&u.info25.password.data[516], confounder, 16);
853
854         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
855
856         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
857         if (!NT_STATUS_IS_OK(status)) {
858                 printf("SetUserInfo level %u failed - %s\n",
859                        s.in.level, nt_errstr(status));
860                 ret = false;
861         } else {
862                 *password = newpass;
863         }
864
865         /* This should break the key nicely */
866         confounded_session_key.data[0]++;
867
868         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
869         memcpy(&u.info25.password.data[516], confounder, 16);
870
871         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
872
873         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
874         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
875                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
876                        s.in.level, nt_errstr(status));
877                 ret = false;
878         }
879
880         return ret;
881 }
882
883 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
884                                 struct policy_handle *handle, char **password)
885 {
886         NTSTATUS status;
887         struct samr_SetUserInfo s;
888         union samr_UserInfo u;
889         bool ret = true;
890         DATA_BLOB session_key;
891         char *newpass;
892         struct samr_GetUserPwInfo pwp;
893         struct samr_PwInfo info;
894         int policy_min_pw_len = 0;
895         uint8_t lm_hash[16], nt_hash[16];
896
897         pwp.in.user_handle = handle;
898         pwp.out.info = &info;
899
900         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
901         if (NT_STATUS_IS_OK(status)) {
902                 policy_min_pw_len = pwp.out.info->min_password_length;
903         }
904         newpass = samr_rand_pass(tctx, policy_min_pw_len);
905
906         s.in.user_handle = handle;
907         s.in.info = &u;
908         s.in.level = 18;
909
910         ZERO_STRUCT(u);
911
912         u.info18.nt_pwd_active = true;
913         u.info18.lm_pwd_active = true;
914
915         E_md4hash(newpass, nt_hash);
916         E_deshash(newpass, lm_hash);
917
918         status = dcerpc_fetch_session_key(p, &session_key);
919         if (!NT_STATUS_IS_OK(status)) {
920                 printf("SetUserInfo level %u - no session key - %s\n",
921                        s.in.level, nt_errstr(status));
922                 return false;
923         }
924
925         {
926                 DATA_BLOB in,out;
927                 in = data_blob_const(nt_hash, 16);
928                 out = data_blob_talloc_zero(tctx, 16);
929                 sess_crypt_blob(&out, &in, &session_key, true);
930                 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
931         }
932         {
933                 DATA_BLOB in,out;
934                 in = data_blob_const(lm_hash, 16);
935                 out = data_blob_talloc_zero(tctx, 16);
936                 sess_crypt_blob(&out, &in, &session_key, true);
937                 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
938         }
939
940         torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
941
942         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
943         if (!NT_STATUS_IS_OK(status)) {
944                 printf("SetUserInfo level %u failed - %s\n",
945                        s.in.level, nt_errstr(status));
946                 ret = false;
947         } else {
948                 *password = newpass;
949         }
950
951         return ret;
952 }
953
954 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
955                                 struct policy_handle *handle, uint32_t fields_present,
956                                 char **password)
957 {
958         NTSTATUS status;
959         struct samr_SetUserInfo s;
960         union samr_UserInfo u;
961         bool ret = true;
962         DATA_BLOB session_key;
963         char *newpass;
964         struct samr_GetUserPwInfo pwp;
965         struct samr_PwInfo info;
966         int policy_min_pw_len = 0;
967         uint8_t lm_hash[16], nt_hash[16];
968
969         pwp.in.user_handle = handle;
970         pwp.out.info = &info;
971
972         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
973         if (NT_STATUS_IS_OK(status)) {
974                 policy_min_pw_len = pwp.out.info->min_password_length;
975         }
976         newpass = samr_rand_pass(tctx, policy_min_pw_len);
977
978         s.in.user_handle = handle;
979         s.in.info = &u;
980         s.in.level = 21;
981
982         E_md4hash(newpass, nt_hash);
983         E_deshash(newpass, lm_hash);
984
985         ZERO_STRUCT(u);
986
987         u.info21.fields_present = fields_present;
988
989         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
990                 u.info21.lm_owf_password.length = 16;
991                 u.info21.lm_owf_password.size = 16;
992                 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
993                 u.info21.lm_password_set = true;
994         }
995
996         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
997                 u.info21.nt_owf_password.length = 16;
998                 u.info21.nt_owf_password.size = 16;
999                 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1000                 u.info21.nt_password_set = true;
1001         }
1002
1003         status = dcerpc_fetch_session_key(p, &session_key);
1004         if (!NT_STATUS_IS_OK(status)) {
1005                 printf("SetUserInfo level %u - no session key - %s\n",
1006                        s.in.level, nt_errstr(status));
1007                 return false;
1008         }
1009
1010         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1011                 DATA_BLOB in,out;
1012                 in = data_blob_const(u.info21.lm_owf_password.array,
1013                                      u.info21.lm_owf_password.length);
1014                 out = data_blob_talloc_zero(tctx, 16);
1015                 sess_crypt_blob(&out, &in, &session_key, true);
1016                 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1017         }
1018
1019         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1020                 DATA_BLOB in,out;
1021                 in = data_blob_const(u.info21.nt_owf_password.array,
1022                                      u.info21.nt_owf_password.length);
1023                 out = data_blob_talloc_zero(tctx, 16);
1024                 sess_crypt_blob(&out, &in, &session_key, true);
1025                 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1026         }
1027
1028         torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1029
1030         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1031         if (!NT_STATUS_IS_OK(status)) {
1032                 printf("SetUserInfo level %u failed - %s\n",
1033                        s.in.level, nt_errstr(status));
1034                 ret = false;
1035         } else {
1036                 *password = newpass;
1037         }
1038
1039         /* try invalid length */
1040         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1041
1042                 u.info21.nt_owf_password.length++;
1043
1044                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1045
1046                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1047                         printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1048                                s.in.level, nt_errstr(status));
1049                         ret = false;
1050                 }
1051         }
1052
1053         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1054
1055                 u.info21.lm_owf_password.length++;
1056
1057                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1058
1059                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1060                         printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1061                                s.in.level, nt_errstr(status));
1062                         ret = false;
1063                 }
1064         }
1065
1066         return ret;
1067 }
1068
1069 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1070                                       struct torture_context *tctx,
1071                                       struct policy_handle *handle,
1072                                       uint16_t level,
1073                                       uint32_t fields_present,
1074                                       char **password, uint8_t password_expired,
1075                                       bool use_setinfo2,
1076                                       bool *matched_expected_error)
1077 {
1078         NTSTATUS status;
1079         NTSTATUS expected_error = NT_STATUS_OK;
1080         struct samr_SetUserInfo s;
1081         struct samr_SetUserInfo2 s2;
1082         union samr_UserInfo u;
1083         bool ret = true;
1084         DATA_BLOB session_key;
1085         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1086         struct MD5Context ctx;
1087         uint8_t confounder[16];
1088         char *newpass;
1089         struct samr_GetUserPwInfo pwp;
1090         struct samr_PwInfo info;
1091         int policy_min_pw_len = 0;
1092         const char *comment = NULL;
1093         uint8_t lm_hash[16], nt_hash[16];
1094
1095         pwp.in.user_handle = handle;
1096         pwp.out.info = &info;
1097
1098         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1099         if (NT_STATUS_IS_OK(status)) {
1100                 policy_min_pw_len = pwp.out.info->min_password_length;
1101         }
1102         newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1103
1104         if (use_setinfo2) {
1105                 s2.in.user_handle = handle;
1106                 s2.in.info = &u;
1107                 s2.in.level = level;
1108         } else {
1109                 s.in.user_handle = handle;
1110                 s.in.info = &u;
1111                 s.in.level = level;
1112         }
1113
1114         if (fields_present & SAMR_FIELD_COMMENT) {
1115                 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1116         }
1117
1118         ZERO_STRUCT(u);
1119
1120         switch (level) {
1121         case 18:
1122                 E_md4hash(newpass, nt_hash);
1123                 E_deshash(newpass, lm_hash);
1124
1125                 u.info18.nt_pwd_active = true;
1126                 u.info18.lm_pwd_active = true;
1127                 u.info18.password_expired = password_expired;
1128
1129                 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1130                 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1131
1132                 break;
1133         case 21:
1134                 E_md4hash(newpass, nt_hash);
1135                 E_deshash(newpass, lm_hash);
1136
1137                 u.info21.fields_present = fields_present;
1138                 u.info21.password_expired = password_expired;
1139                 u.info21.comment.string = comment;
1140
1141                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1142                         u.info21.lm_owf_password.length = 16;
1143                         u.info21.lm_owf_password.size = 16;
1144                         u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1145                         u.info21.lm_password_set = true;
1146                 }
1147
1148                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1149                         u.info21.nt_owf_password.length = 16;
1150                         u.info21.nt_owf_password.size = 16;
1151                         u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1152                         u.info21.nt_password_set = true;
1153                 }
1154
1155                 break;
1156         case 23:
1157                 u.info23.info.fields_present = fields_present;
1158                 u.info23.info.password_expired = password_expired;
1159                 u.info23.info.comment.string = comment;
1160
1161                 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1162
1163                 break;
1164         case 24:
1165                 u.info24.password_expired = password_expired;
1166
1167                 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1168
1169                 break;
1170         case 25:
1171                 u.info25.info.fields_present = fields_present;
1172                 u.info25.info.password_expired = password_expired;
1173                 u.info25.info.comment.string = comment;
1174
1175                 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1176
1177                 break;
1178         case 26:
1179                 u.info26.password_expired = password_expired;
1180
1181                 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1182
1183                 break;
1184         }
1185
1186         status = dcerpc_fetch_session_key(p, &session_key);
1187         if (!NT_STATUS_IS_OK(status)) {
1188                 printf("SetUserInfo level %u - no session key - %s\n",
1189                        s.in.level, nt_errstr(status));
1190                 return false;
1191         }
1192
1193         generate_random_buffer((uint8_t *)confounder, 16);
1194
1195         MD5Init(&ctx);
1196         MD5Update(&ctx, confounder, 16);
1197         MD5Update(&ctx, session_key.data, session_key.length);
1198         MD5Final(confounded_session_key.data, &ctx);
1199
1200         switch (level) {
1201         case 18:
1202                 {
1203                         DATA_BLOB in,out;
1204                         in = data_blob_const(u.info18.nt_pwd.hash, 16);
1205                         out = data_blob_talloc_zero(tctx, 16);
1206                         sess_crypt_blob(&out, &in, &session_key, true);
1207                         memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1208                 }
1209                 {
1210                         DATA_BLOB in,out;
1211                         in = data_blob_const(u.info18.lm_pwd.hash, 16);
1212                         out = data_blob_talloc_zero(tctx, 16);
1213                         sess_crypt_blob(&out, &in, &session_key, true);
1214                         memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1215                 }
1216
1217                 break;
1218         case 21:
1219                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1220                         DATA_BLOB in,out;
1221                         in = data_blob_const(u.info21.lm_owf_password.array,
1222                                              u.info21.lm_owf_password.length);
1223                         out = data_blob_talloc_zero(tctx, 16);
1224                         sess_crypt_blob(&out, &in, &session_key, true);
1225                         u.info21.lm_owf_password.array = (uint16_t *)out.data;
1226                 }
1227                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1228                         DATA_BLOB in,out;
1229                         in = data_blob_const(u.info21.nt_owf_password.array,
1230                                              u.info21.nt_owf_password.length);
1231                         out = data_blob_talloc_zero(tctx, 16);
1232                         sess_crypt_blob(&out, &in, &session_key, true);
1233                         u.info21.nt_owf_password.array = (uint16_t *)out.data;
1234                 }
1235                 break;
1236         case 23:
1237                 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1238                 break;
1239         case 24:
1240                 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1241                 break;
1242         case 25:
1243                 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1244                 memcpy(&u.info25.password.data[516], confounder, 16);
1245                 break;
1246         case 26:
1247                 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1248                 memcpy(&u.info26.password.data[516], confounder, 16);
1249                 break;
1250         }
1251
1252         if (use_setinfo2) {
1253                 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1254         } else {
1255                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1256         }
1257
1258         if (!NT_STATUS_IS_OK(status)) {
1259                 if (fields_present == 0) {
1260                         expected_error = NT_STATUS_INVALID_PARAMETER;
1261                 }
1262                 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1263                         expected_error = NT_STATUS_ACCESS_DENIED;
1264                 }
1265         }
1266
1267         if (!NT_STATUS_IS_OK(expected_error)) {
1268                 if (use_setinfo2) {
1269                         torture_assert_ntstatus_equal(tctx,
1270                                 s2.out.result,
1271                                 expected_error, "SetUserInfo2 failed");
1272                 } else {
1273                         torture_assert_ntstatus_equal(tctx,
1274                                 s.out.result,
1275                                 expected_error, "SetUserInfo failed");
1276                 }
1277                 *matched_expected_error = true;
1278                 return true;
1279         }
1280
1281         if (!NT_STATUS_IS_OK(status)) {
1282                 printf("SetUserInfo%s level %u failed - %s\n",
1283                        use_setinfo2 ? "2":"", level, nt_errstr(status));
1284                 ret = false;
1285         } else {
1286                 *password = newpass;
1287         }
1288
1289         return ret;
1290 }
1291
1292 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1293                                struct policy_handle *handle)
1294 {
1295         NTSTATUS status;
1296         struct samr_SetAliasInfo r;
1297         struct samr_QueryAliasInfo q;
1298         union samr_AliasInfo *info;
1299         uint16_t levels[] = {2, 3};
1300         int i;
1301         bool ret = true;
1302
1303         /* Ignoring switch level 1, as that includes the number of members for the alias
1304          * and setting this to a wrong value might have negative consequences
1305          */
1306
1307         for (i=0;i<ARRAY_SIZE(levels);i++) {
1308                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1309
1310                 r.in.alias_handle = handle;
1311                 r.in.level = levels[i];
1312                 r.in.info  = talloc(tctx, union samr_AliasInfo);
1313                 switch (r.in.level) {
1314                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1315                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1316                                 "Test Description, should test I18N as well"); break;
1317                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1318                 }
1319
1320                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1321                 if (!NT_STATUS_IS_OK(status)) {
1322                         printf("SetAliasInfo level %u failed - %s\n",
1323                                levels[i], nt_errstr(status));
1324                         ret = false;
1325                 }
1326
1327                 q.in.alias_handle = handle;
1328                 q.in.level = levels[i];
1329                 q.out.info = &info;
1330
1331                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1332                 if (!NT_STATUS_IS_OK(status)) {
1333                         printf("QueryAliasInfo level %u failed - %s\n",
1334                                levels[i], nt_errstr(status));
1335                         ret = false;
1336                 }
1337         }
1338
1339         return ret;
1340 }
1341
1342 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1343                                   struct policy_handle *user_handle)
1344 {
1345         struct samr_GetGroupsForUser r;
1346         struct samr_RidWithAttributeArray *rids = NULL;
1347         NTSTATUS status;
1348
1349         torture_comment(tctx, "testing GetGroupsForUser\n");
1350
1351         r.in.user_handle = user_handle;
1352         r.out.rids = &rids;
1353
1354         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1355         torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1356
1357         return true;
1358
1359 }
1360
1361 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1362                               struct lsa_String *domain_name)
1363 {
1364         NTSTATUS status;
1365         struct samr_GetDomPwInfo r;
1366         struct samr_PwInfo info;
1367
1368         r.in.domain_name = domain_name;
1369         r.out.info = &info;
1370
1371         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1372
1373         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1374         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1375
1376         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1377         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1378
1379         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1380         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1381
1382         r.in.domain_name->string = "\\\\__NONAME__";
1383         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1384
1385         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1386         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1387
1388         r.in.domain_name->string = "\\\\Builtin";
1389         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1390
1391         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1392         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1393
1394         return true;
1395 }
1396
1397 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1398                                struct policy_handle *handle)
1399 {
1400         NTSTATUS status;
1401         struct samr_GetUserPwInfo r;
1402         struct samr_PwInfo info;
1403
1404         torture_comment(tctx, "Testing GetUserPwInfo\n");
1405
1406         r.in.user_handle = handle;
1407         r.out.info = &info;
1408
1409         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1410         torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1411
1412         return true;
1413 }
1414
1415 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1416                                 struct policy_handle *domain_handle, const char *name,
1417                                 uint32_t *rid)
1418 {
1419         NTSTATUS status;
1420         struct samr_LookupNames n;
1421         struct lsa_String sname[2];
1422         struct samr_Ids rids, types;
1423
1424         init_lsa_String(&sname[0], name);
1425
1426         n.in.domain_handle = domain_handle;
1427         n.in.num_names = 1;
1428         n.in.names = sname;
1429         n.out.rids = &rids;
1430         n.out.types = &types;
1431         status = dcerpc_samr_LookupNames(p, tctx, &n);
1432         if (NT_STATUS_IS_OK(status)) {
1433                 *rid = n.out.rids->ids[0];
1434         } else {
1435                 return status;
1436         }
1437
1438         init_lsa_String(&sname[1], "xxNONAMExx");
1439         n.in.num_names = 2;
1440         status = dcerpc_samr_LookupNames(p, tctx, &n);
1441         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1442                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
1443                 if (NT_STATUS_IS_OK(status)) {
1444                         return NT_STATUS_UNSUCCESSFUL;
1445                 }
1446                 return status;
1447         }
1448
1449         n.in.num_names = 0;
1450         status = dcerpc_samr_LookupNames(p, tctx, &n);
1451         if (!NT_STATUS_IS_OK(status)) {
1452                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
1453                 return status;
1454         }
1455
1456         init_lsa_String(&sname[0], "xxNONAMExx");
1457         n.in.num_names = 1;
1458         status = dcerpc_samr_LookupNames(p, tctx, &n);
1459         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1460                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
1461                 if (NT_STATUS_IS_OK(status)) {
1462                         return NT_STATUS_UNSUCCESSFUL;
1463                 }
1464                 return status;
1465         }
1466
1467         init_lsa_String(&sname[0], "xxNONAMExx");
1468         init_lsa_String(&sname[1], "xxNONAME2xx");
1469         n.in.num_names = 2;
1470         status = dcerpc_samr_LookupNames(p, tctx, &n);
1471         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1472                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
1473                 if (NT_STATUS_IS_OK(status)) {
1474                         return NT_STATUS_UNSUCCESSFUL;
1475                 }
1476                 return status;
1477         }
1478
1479         return NT_STATUS_OK;
1480 }
1481
1482 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1483                                      struct policy_handle *domain_handle,
1484                                      const char *name, struct policy_handle *user_handle)
1485 {
1486         NTSTATUS status;
1487         struct samr_OpenUser r;
1488         uint32_t rid;
1489
1490         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1491         if (!NT_STATUS_IS_OK(status)) {
1492                 return status;
1493         }
1494
1495         r.in.domain_handle = domain_handle;
1496         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1497         r.in.rid = rid;
1498         r.out.user_handle = user_handle;
1499         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1500         if (!NT_STATUS_IS_OK(status)) {
1501                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1502         }
1503
1504         return status;
1505 }
1506
1507 #if 0
1508 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1509                                    struct policy_handle *handle)
1510 {
1511         NTSTATUS status;
1512         struct samr_ChangePasswordUser r;
1513         bool ret = true;
1514         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1515         struct policy_handle user_handle;
1516         char *oldpass = "test";
1517         char *newpass = "test2";
1518         uint8_t old_nt_hash[16], new_nt_hash[16];
1519         uint8_t old_lm_hash[16], new_lm_hash[16];
1520
1521         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1522         if (!NT_STATUS_IS_OK(status)) {
1523                 return false;
1524         }
1525
1526         printf("Testing ChangePasswordUser for user 'testuser'\n");
1527
1528         printf("old password: %s\n", oldpass);
1529         printf("new password: %s\n", newpass);
1530
1531         E_md4hash(oldpass, old_nt_hash);
1532         E_md4hash(newpass, new_nt_hash);
1533         E_deshash(oldpass, old_lm_hash);
1534         E_deshash(newpass, new_lm_hash);
1535
1536         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1537         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1538         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1539         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1540         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1541         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1542
1543         r.in.handle = &user_handle;
1544         r.in.lm_present = 1;
1545         r.in.old_lm_crypted = &hash1;
1546         r.in.new_lm_crypted = &hash2;
1547         r.in.nt_present = 1;
1548         r.in.old_nt_crypted = &hash3;
1549         r.in.new_nt_crypted = &hash4;
1550         r.in.cross1_present = 1;
1551         r.in.nt_cross = &hash5;
1552         r.in.cross2_present = 1;
1553         r.in.lm_cross = &hash6;
1554
1555         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1556         if (!NT_STATUS_IS_OK(status)) {
1557                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1558                 ret = false;
1559         }
1560
1561         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1562                 ret = false;
1563         }
1564
1565         return ret;
1566 }
1567 #endif
1568
1569 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1570                                     const char *acct_name, 
1571                                     struct policy_handle *handle, char **password)
1572 {
1573         NTSTATUS status;
1574         struct samr_ChangePasswordUser r;
1575         bool ret = true;
1576         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1577         struct policy_handle user_handle;
1578         char *oldpass;
1579         uint8_t old_nt_hash[16], new_nt_hash[16];
1580         uint8_t old_lm_hash[16], new_lm_hash[16];
1581         bool changed = true;
1582
1583         char *newpass;
1584         struct samr_GetUserPwInfo pwp;
1585         struct samr_PwInfo info;
1586         int policy_min_pw_len = 0;
1587
1588         status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1589         if (!NT_STATUS_IS_OK(status)) {
1590                 return false;
1591         }
1592         pwp.in.user_handle = &user_handle;
1593         pwp.out.info = &info;
1594
1595         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1596         if (NT_STATUS_IS_OK(status)) {
1597                 policy_min_pw_len = pwp.out.info->min_password_length;
1598         }
1599         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1600
1601         torture_comment(tctx, "Testing ChangePasswordUser\n");
1602
1603         torture_assert(tctx, *password != NULL, 
1604                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
1605
1606         oldpass = *password;
1607
1608         E_md4hash(oldpass, old_nt_hash);
1609         E_md4hash(newpass, new_nt_hash);
1610         E_deshash(oldpass, old_lm_hash);
1611         E_deshash(newpass, new_lm_hash);
1612
1613         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1614         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1615         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1616         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1617         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1618         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1619
1620         r.in.user_handle = &user_handle;
1621         r.in.lm_present = 1;
1622         /* Break the LM hash */
1623         hash1.hash[0]++;
1624         r.in.old_lm_crypted = &hash1;
1625         r.in.new_lm_crypted = &hash2;
1626         r.in.nt_present = 1;
1627         r.in.old_nt_crypted = &hash3;
1628         r.in.new_nt_crypted = &hash4;
1629         r.in.cross1_present = 1;
1630         r.in.nt_cross = &hash5;
1631         r.in.cross2_present = 1;
1632         r.in.lm_cross = &hash6;
1633
1634         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1635         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1636                 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1637
1638         /* Unbreak the LM hash */
1639         hash1.hash[0]--;
1640
1641         r.in.user_handle = &user_handle;
1642         r.in.lm_present = 1;
1643         r.in.old_lm_crypted = &hash1;
1644         r.in.new_lm_crypted = &hash2;
1645         /* Break the NT hash */
1646         hash3.hash[0]--;
1647         r.in.nt_present = 1;
1648         r.in.old_nt_crypted = &hash3;
1649         r.in.new_nt_crypted = &hash4;
1650         r.in.cross1_present = 1;
1651         r.in.nt_cross = &hash5;
1652         r.in.cross2_present = 1;
1653         r.in.lm_cross = &hash6;
1654
1655         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1656         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD, 
1657                 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1658
1659         /* Unbreak the NT hash */
1660         hash3.hash[0]--;
1661
1662         r.in.user_handle = &user_handle;
1663         r.in.lm_present = 1;
1664         r.in.old_lm_crypted = &hash1;
1665         r.in.new_lm_crypted = &hash2;
1666         r.in.nt_present = 1;
1667         r.in.old_nt_crypted = &hash3;
1668         r.in.new_nt_crypted = &hash4;
1669         r.in.cross1_present = 1;
1670         r.in.nt_cross = &hash5;
1671         r.in.cross2_present = 1;
1672         /* Break the LM cross */
1673         hash6.hash[0]++;
1674         r.in.lm_cross = &hash6;
1675
1676         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1677         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1678                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1679                 ret = false;
1680         }
1681
1682         /* Unbreak the LM cross */
1683         hash6.hash[0]--;
1684
1685         r.in.user_handle = &user_handle;
1686         r.in.lm_present = 1;
1687         r.in.old_lm_crypted = &hash1;
1688         r.in.new_lm_crypted = &hash2;
1689         r.in.nt_present = 1;
1690         r.in.old_nt_crypted = &hash3;
1691         r.in.new_nt_crypted = &hash4;
1692         r.in.cross1_present = 1;
1693         /* Break the NT cross */
1694         hash5.hash[0]++;
1695         r.in.nt_cross = &hash5;
1696         r.in.cross2_present = 1;
1697         r.in.lm_cross = &hash6;
1698
1699         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1700         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1701                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1702                 ret = false;
1703         }
1704
1705         /* Unbreak the NT cross */
1706         hash5.hash[0]--;
1707
1708
1709         /* Reset the hashes to not broken values */
1710         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1711         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1712         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1713         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1714         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1715         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1716
1717         r.in.user_handle = &user_handle;
1718         r.in.lm_present = 1;
1719         r.in.old_lm_crypted = &hash1;
1720         r.in.new_lm_crypted = &hash2;
1721         r.in.nt_present = 1;
1722         r.in.old_nt_crypted = &hash3;
1723         r.in.new_nt_crypted = &hash4;
1724         r.in.cross1_present = 1;
1725         r.in.nt_cross = &hash5;
1726         r.in.cross2_present = 0;
1727         r.in.lm_cross = NULL;
1728
1729         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1730         if (NT_STATUS_IS_OK(status)) {
1731                 changed = true;
1732                 *password = newpass;
1733         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1734                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1735                 ret = false;
1736         }
1737
1738         oldpass = newpass;
1739         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1740
1741         E_md4hash(oldpass, old_nt_hash);
1742         E_md4hash(newpass, new_nt_hash);
1743         E_deshash(oldpass, old_lm_hash);
1744         E_deshash(newpass, new_lm_hash);
1745
1746
1747         /* Reset the hashes to not broken values */
1748         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1749         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1750         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1751         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1752         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1753         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1754
1755         r.in.user_handle = &user_handle;
1756         r.in.lm_present = 1;
1757         r.in.old_lm_crypted = &hash1;
1758         r.in.new_lm_crypted = &hash2;
1759         r.in.nt_present = 1;
1760         r.in.old_nt_crypted = &hash3;
1761         r.in.new_nt_crypted = &hash4;
1762         r.in.cross1_present = 0;
1763         r.in.nt_cross = NULL;
1764         r.in.cross2_present = 1;
1765         r.in.lm_cross = &hash6;
1766
1767         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1768         if (NT_STATUS_IS_OK(status)) {
1769                 changed = true;
1770                 *password = newpass;
1771         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1772                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1773                 ret = false;
1774         }
1775
1776         oldpass = newpass;
1777         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1778
1779         E_md4hash(oldpass, old_nt_hash);
1780         E_md4hash(newpass, new_nt_hash);
1781         E_deshash(oldpass, old_lm_hash);
1782         E_deshash(newpass, new_lm_hash);
1783
1784
1785         /* Reset the hashes to not broken values */
1786         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1787         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1788         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1789         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1790         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1791         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1792
1793         r.in.user_handle = &user_handle;
1794         r.in.lm_present = 1;
1795         r.in.old_lm_crypted = &hash1;
1796         r.in.new_lm_crypted = &hash2;
1797         r.in.nt_present = 1;
1798         r.in.old_nt_crypted = &hash3;
1799         r.in.new_nt_crypted = &hash4;
1800         r.in.cross1_present = 1;
1801         r.in.nt_cross = &hash5;
1802         r.in.cross2_present = 1;
1803         r.in.lm_cross = &hash6;
1804
1805         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1806         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1807                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1808         } else  if (!NT_STATUS_IS_OK(status)) {
1809                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1810                 ret = false;
1811         } else {
1812                 changed = true;
1813                 *password = newpass;
1814         }
1815
1816         r.in.user_handle = &user_handle;
1817         r.in.lm_present = 1;
1818         r.in.old_lm_crypted = &hash1;
1819         r.in.new_lm_crypted = &hash2;
1820         r.in.nt_present = 1;
1821         r.in.old_nt_crypted = &hash3;
1822         r.in.new_nt_crypted = &hash4;
1823         r.in.cross1_present = 1;
1824         r.in.nt_cross = &hash5;
1825         r.in.cross2_present = 1;
1826         r.in.lm_cross = &hash6;
1827
1828         if (changed) {
1829                 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1830                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1831                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1832                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1833                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1834                         ret = false;
1835                 }
1836         }
1837
1838         
1839         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1840                 ret = false;
1841         }
1842
1843         return ret;
1844 }
1845
1846
1847 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1848                                         const char *acct_name,
1849                                         struct policy_handle *handle, char **password)
1850 {
1851         NTSTATUS status;
1852         struct samr_OemChangePasswordUser2 r;
1853         bool ret = true;
1854         struct samr_Password lm_verifier;
1855         struct samr_CryptPassword lm_pass;
1856         struct lsa_AsciiString server, account, account_bad;
1857         char *oldpass;
1858         char *newpass;
1859         uint8_t old_lm_hash[16], new_lm_hash[16];
1860
1861         struct samr_GetDomPwInfo dom_pw_info;
1862         struct samr_PwInfo info;
1863         int policy_min_pw_len = 0;
1864
1865         struct lsa_String domain_name;
1866
1867         domain_name.string = "";
1868         dom_pw_info.in.domain_name = &domain_name;
1869         dom_pw_info.out.info = &info;
1870
1871         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1872
1873         torture_assert(tctx, *password != NULL, 
1874                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
1875
1876         oldpass = *password;
1877
1878         status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1879         if (NT_STATUS_IS_OK(status)) {
1880                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1881         }
1882
1883         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1884
1885         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1886         account.string = acct_name;
1887
1888         E_deshash(oldpass, old_lm_hash);
1889         E_deshash(newpass, new_lm_hash);
1890
1891         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1892         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1893         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1894
1895         r.in.server = &server;
1896         r.in.account = &account;
1897         r.in.password = &lm_pass;
1898         r.in.hash = &lm_verifier;
1899
1900         /* Break the verification */
1901         lm_verifier.hash[0]++;
1902
1903         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1904
1905         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1906             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1907                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1908                         nt_errstr(status));
1909                 ret = false;
1910         }
1911
1912         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1913         /* Break the old password */
1914         old_lm_hash[0]++;
1915         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1916         /* unbreak it for the next operation */
1917         old_lm_hash[0]--;
1918         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1919
1920         r.in.server = &server;
1921         r.in.account = &account;
1922         r.in.password = &lm_pass;
1923         r.in.hash = &lm_verifier;
1924
1925         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1926
1927         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1928             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1929                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1930                         nt_errstr(status));
1931                 ret = false;
1932         }
1933
1934         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1935         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1936
1937         r.in.server = &server;
1938         r.in.account = &account;
1939         r.in.password = &lm_pass;
1940         r.in.hash = NULL;
1941
1942         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1943
1944         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1945             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1946                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1947                         nt_errstr(status));
1948                 ret = false;
1949         }
1950
1951         /* This shouldn't be a valid name */
1952         account_bad.string = TEST_ACCOUNT_NAME "XX";
1953         r.in.account = &account_bad;
1954
1955         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1956
1957         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1958                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1959                         nt_errstr(status));
1960                 ret = false;
1961         }
1962
1963         /* This shouldn't be a valid name */
1964         account_bad.string = TEST_ACCOUNT_NAME "XX";
1965         r.in.account = &account_bad;
1966         r.in.password = &lm_pass;
1967         r.in.hash = &lm_verifier;
1968
1969         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1970
1971         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1972                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1973                         nt_errstr(status));
1974                 ret = false;
1975         }
1976
1977         /* This shouldn't be a valid name */
1978         account_bad.string = TEST_ACCOUNT_NAME "XX";
1979         r.in.account = &account_bad;
1980         r.in.password = NULL;
1981         r.in.hash = &lm_verifier;
1982
1983         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1984
1985         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1986                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1987                         nt_errstr(status));
1988                 ret = false;
1989         }
1990
1991         E_deshash(oldpass, old_lm_hash);
1992         E_deshash(newpass, new_lm_hash);
1993
1994         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1995         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1996         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1997
1998         r.in.server = &server;
1999         r.in.account = &account;
2000         r.in.password = &lm_pass;
2001         r.in.hash = &lm_verifier;
2002
2003         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2004         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2005                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2006         } else if (!NT_STATUS_IS_OK(status)) {
2007                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2008                 ret = false;
2009         } else {
2010                 *password = newpass;
2011         }
2012
2013         return ret;
2014 }
2015
2016
2017 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2018                                      const char *acct_name,
2019                                      char **password,
2020                                      char *newpass, bool allow_password_restriction)
2021 {
2022         NTSTATUS status;
2023         struct samr_ChangePasswordUser2 r;
2024         bool ret = true;
2025         struct lsa_String server, account;
2026         struct samr_CryptPassword nt_pass, lm_pass;
2027         struct samr_Password nt_verifier, lm_verifier;
2028         char *oldpass;
2029         uint8_t old_nt_hash[16], new_nt_hash[16];
2030         uint8_t old_lm_hash[16], new_lm_hash[16];
2031
2032         struct samr_GetDomPwInfo dom_pw_info;
2033         struct samr_PwInfo info;
2034
2035         struct lsa_String domain_name;
2036
2037         domain_name.string = "";
2038         dom_pw_info.in.domain_name = &domain_name;
2039         dom_pw_info.out.info = &info;
2040
2041         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2042
2043         torture_assert(tctx, *password != NULL, 
2044                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
2045         oldpass = *password;
2046
2047         if (!newpass) {
2048                 int policy_min_pw_len = 0;
2049                 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2050                 if (NT_STATUS_IS_OK(status)) {
2051                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2052                 }
2053
2054                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2055         } 
2056
2057         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2058         init_lsa_String(&account, acct_name);
2059
2060         E_md4hash(oldpass, old_nt_hash);
2061         E_md4hash(newpass, new_nt_hash);
2062
2063         E_deshash(oldpass, old_lm_hash);
2064         E_deshash(newpass, new_lm_hash);
2065
2066         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2067         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2068         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2069
2070         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2071         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2072         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2073
2074         r.in.server = &server;
2075         r.in.account = &account;
2076         r.in.nt_password = &nt_pass;
2077         r.in.nt_verifier = &nt_verifier;
2078         r.in.lm_change = 1;
2079         r.in.lm_password = &lm_pass;
2080         r.in.lm_verifier = &lm_verifier;
2081
2082         status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2083         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2084                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2085         } else if (!NT_STATUS_IS_OK(status)) {
2086                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2087                 ret = false;
2088         } else {
2089                 *password = newpass;
2090         }
2091
2092         return ret;
2093 }
2094
2095
2096 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx, 
2097                               const char *account_string,
2098                               int policy_min_pw_len,
2099                               char **password,
2100                               const char *newpass,
2101                               NTTIME last_password_change,
2102                               bool handle_reject_reason)
2103 {
2104         NTSTATUS status;
2105         struct samr_ChangePasswordUser3 r;
2106         bool ret = true;
2107         struct lsa_String server, account, account_bad;
2108         struct samr_CryptPassword nt_pass, lm_pass;
2109         struct samr_Password nt_verifier, lm_verifier;
2110         char *oldpass;
2111         uint8_t old_nt_hash[16], new_nt_hash[16];
2112         uint8_t old_lm_hash[16], new_lm_hash[16];
2113         NTTIME t;
2114         struct samr_DomInfo1 *dominfo = NULL;
2115         struct samr_ChangeReject *reject = NULL;
2116
2117         torture_comment(tctx, "Testing ChangePasswordUser3\n");
2118
2119         if (newpass == NULL) {
2120                 do {
2121                         if (policy_min_pw_len == 0) {
2122                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2123                         } else {
2124                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2125                         }
2126                 } while (check_password_quality(newpass) == false);
2127         } else {
2128                 torture_comment(tctx, "Using password '%s'\n", newpass);
2129         }
2130
2131         torture_assert(tctx, *password != NULL, 
2132                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2133
2134         oldpass = *password;
2135         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2136         init_lsa_String(&account, account_string);
2137
2138         E_md4hash(oldpass, old_nt_hash);
2139         E_md4hash(newpass, new_nt_hash);
2140
2141         E_deshash(oldpass, old_lm_hash);
2142         E_deshash(newpass, new_lm_hash);
2143
2144         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2145         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2146         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2147
2148         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2149         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2150         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2151         
2152         /* Break the verification */
2153         nt_verifier.hash[0]++;
2154
2155         r.in.server = &server;
2156         r.in.account = &account;
2157         r.in.nt_password = &nt_pass;
2158         r.in.nt_verifier = &nt_verifier;
2159         r.in.lm_change = 1;
2160         r.in.lm_password = &lm_pass;
2161         r.in.lm_verifier = &lm_verifier;
2162         r.in.password3 = NULL;
2163         r.out.dominfo = &dominfo;
2164         r.out.reject = &reject;
2165
2166         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2167         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2168             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2169                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2170                         nt_errstr(status));
2171                 ret = false;
2172         }
2173         
2174         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2175         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2176         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2177
2178         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2179         /* Break the NT hash */
2180         old_nt_hash[0]++;
2181         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2182         /* Unbreak it again */
2183         old_nt_hash[0]--;
2184         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2185         
2186         r.in.server = &server;
2187         r.in.account = &account;
2188         r.in.nt_password = &nt_pass;
2189         r.in.nt_verifier = &nt_verifier;
2190         r.in.lm_change = 1;
2191         r.in.lm_password = &lm_pass;
2192         r.in.lm_verifier = &lm_verifier;
2193         r.in.password3 = NULL;
2194         r.out.dominfo = &dominfo;
2195         r.out.reject = &reject;
2196
2197         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2198         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2199             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2200                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2201                         nt_errstr(status));
2202                 ret = false;
2203         }
2204         
2205         /* This shouldn't be a valid name */
2206         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2207
2208         r.in.account = &account_bad;
2209         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2210         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2211                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2212                         nt_errstr(status));
2213                 ret = false;
2214         }
2215
2216         E_md4hash(oldpass, old_nt_hash);
2217         E_md4hash(newpass, new_nt_hash);
2218
2219         E_deshash(oldpass, old_lm_hash);
2220         E_deshash(newpass, new_lm_hash);
2221
2222         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2223         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2224         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2225
2226         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2227         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2228         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2229
2230         r.in.server = &server;
2231         r.in.account = &account;
2232         r.in.nt_password = &nt_pass;
2233         r.in.nt_verifier = &nt_verifier;
2234         r.in.lm_change = 1;
2235         r.in.lm_password = &lm_pass;
2236         r.in.lm_verifier = &lm_verifier;
2237         r.in.password3 = NULL;
2238         r.out.dominfo = &dominfo;
2239         r.out.reject = &reject;
2240
2241         unix_to_nt_time(&t, time(NULL));
2242
2243         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2244
2245         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2246             && dominfo
2247             && reject
2248             && handle_reject_reason
2249             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2250                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2251
2252                         if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2253                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2254                                         SAMR_REJECT_OTHER, reject->reason);
2255                                 return false;
2256                         }
2257                 }
2258
2259                 /* We tested the order of precendence which is as follows:
2260                 
2261                 * pwd min_age 
2262                 * pwd length
2263                 * pwd complexity
2264                 * pwd history
2265
2266                 Guenther */
2267
2268                 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2269                            (last_password_change + dominfo->min_password_age > t)) {
2270
2271                         if (reject->reason != SAMR_REJECT_OTHER) {
2272                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2273                                         SAMR_REJECT_OTHER, reject->reason);
2274                                 return false;
2275                         }
2276
2277                 } else if ((dominfo->min_password_length > 0) &&
2278                            (strlen(newpass) < dominfo->min_password_length)) {
2279
2280                         if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2281                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
2282                                         SAMR_REJECT_TOO_SHORT, reject->reason);
2283                                 return false;
2284                         }
2285
2286                 } else if ((dominfo->password_history_length > 0) &&
2287                             strequal(oldpass, newpass)) {
2288
2289                         if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2290                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
2291                                         SAMR_REJECT_IN_HISTORY, reject->reason);
2292                                 return false;
2293                         }
2294                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2295
2296                         if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2297                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
2298                                         SAMR_REJECT_COMPLEXITY, reject->reason);
2299                                 return false;
2300                         }
2301
2302                 }
2303
2304                 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2305                         /* retry with adjusted size */
2306                         return test_ChangePasswordUser3(p, tctx, account_string, 
2307                                                         dominfo->min_password_length,
2308                                                         password, NULL, 0, false); 
2309
2310                 }
2311
2312         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2313                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2314                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2315                                SAMR_REJECT_OTHER, reject->reason);
2316                         return false;
2317                 }
2318                 /* Perhaps the server has a 'min password age' set? */
2319
2320         } else { 
2321                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2322                 *password = talloc_strdup(tctx, newpass);
2323         }
2324
2325         return ret;
2326 }
2327
2328 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2329                                     const char *account_string,
2330                                     struct policy_handle *handle, 
2331                                     char **password)
2332 {
2333         NTSTATUS status;
2334         struct samr_ChangePasswordUser3 r;
2335         struct samr_SetUserInfo s;
2336         union samr_UserInfo u;
2337         DATA_BLOB session_key;
2338         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2339         uint8_t confounder[16];
2340         struct MD5Context ctx;
2341
2342         bool ret = true;
2343         struct lsa_String server, account;
2344         struct samr_CryptPassword nt_pass;
2345         struct samr_Password nt_verifier;
2346         DATA_BLOB new_random_pass;
2347         char *newpass;
2348         char *oldpass;
2349         uint8_t old_nt_hash[16], new_nt_hash[16];
2350         NTTIME t;
2351         struct samr_DomInfo1 *dominfo = NULL;
2352         struct samr_ChangeReject *reject = NULL;
2353
2354         new_random_pass = samr_very_rand_pass(tctx, 128);
2355
2356         torture_assert(tctx, *password != NULL, 
2357                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2358
2359         oldpass = *password;
2360         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2361         init_lsa_String(&account, account_string);
2362
2363         s.in.user_handle = handle;
2364         s.in.info = &u;
2365         s.in.level = 25;
2366
2367         ZERO_STRUCT(u);
2368
2369         u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2370
2371         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2372
2373         status = dcerpc_fetch_session_key(p, &session_key);
2374         if (!NT_STATUS_IS_OK(status)) {
2375                 printf("SetUserInfo level %u - no session key - %s\n",
2376                        s.in.level, nt_errstr(status));
2377                 return false;
2378         }
2379
2380         generate_random_buffer((uint8_t *)confounder, 16);
2381
2382         MD5Init(&ctx);
2383         MD5Update(&ctx, confounder, 16);
2384         MD5Update(&ctx, session_key.data, session_key.length);
2385         MD5Final(confounded_session_key.data, &ctx);
2386
2387         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2388         memcpy(&u.info25.password.data[516], confounder, 16);
2389
2390         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2391
2392         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2393         if (!NT_STATUS_IS_OK(status)) {
2394                 printf("SetUserInfo level %u failed - %s\n",
2395                        s.in.level, nt_errstr(status));
2396                 ret = false;
2397         }
2398
2399         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2400
2401         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2402
2403         new_random_pass = samr_very_rand_pass(tctx, 128);
2404
2405         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2406
2407         set_pw_in_buffer(nt_pass.data, &new_random_pass);
2408         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2409         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2410
2411         r.in.server = &server;
2412         r.in.account = &account;
2413         r.in.nt_password = &nt_pass;
2414         r.in.nt_verifier = &nt_verifier;
2415         r.in.lm_change = 0;
2416         r.in.lm_password = NULL;
2417         r.in.lm_verifier = NULL;
2418         r.in.password3 = NULL;
2419         r.out.dominfo = &dominfo;
2420         r.out.reject = &reject;
2421
2422         unix_to_nt_time(&t, time(NULL));
2423
2424         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2425
2426         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2427                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2428                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2429                                SAMR_REJECT_OTHER, reject->reason);
2430                         return false;
2431                 }
2432                 /* Perhaps the server has a 'min password age' set? */
2433
2434         } else if (!NT_STATUS_IS_OK(status)) {
2435                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2436                 ret = false;
2437         }
2438         
2439         newpass = samr_rand_pass(tctx, 128);
2440
2441         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2442
2443         E_md4hash(newpass, new_nt_hash);
2444
2445         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2446         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2447         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2448
2449         r.in.server = &server;
2450         r.in.account = &account;
2451         r.in.nt_password = &nt_pass;
2452         r.in.nt_verifier = &nt_verifier;
2453         r.in.lm_change = 0;
2454         r.in.lm_password = NULL;
2455         r.in.lm_verifier = NULL;
2456         r.in.password3 = NULL;
2457         r.out.dominfo = &dominfo;
2458         r.out.reject = &reject;
2459
2460         unix_to_nt_time(&t, time(NULL));
2461
2462         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2463
2464         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2465                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2466                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
2467                                SAMR_REJECT_OTHER, reject->reason);
2468                         return false;
2469                 }
2470                 /* Perhaps the server has a 'min password age' set? */
2471
2472         } else {
2473                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2474                 *password = talloc_strdup(tctx, newpass);
2475         }
2476
2477         return ret;
2478 }
2479
2480
2481 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2482                                   struct policy_handle *alias_handle)
2483 {
2484         struct samr_GetMembersInAlias r;
2485         struct lsa_SidArray sids;
2486         NTSTATUS status;
2487
2488         torture_comment(tctx, "Testing GetMembersInAlias\n");
2489
2490         r.in.alias_handle = alias_handle;
2491         r.out.sids = &sids;
2492
2493         status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2494         torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2495
2496         return true;
2497 }
2498
2499 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2500                                   struct policy_handle *alias_handle,
2501                                   const struct dom_sid *domain_sid)
2502 {
2503         struct samr_AddAliasMember r;
2504         struct samr_DeleteAliasMember d;
2505         NTSTATUS status;
2506         struct dom_sid *sid;
2507
2508         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2509
2510         torture_comment(tctx, "testing AddAliasMember\n");
2511         r.in.alias_handle = alias_handle;
2512         r.in.sid = sid;
2513
2514         status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2515         torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2516
2517         d.in.alias_handle = alias_handle;
2518         d.in.sid = sid;
2519
2520         status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2521         torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2522
2523         return true;
2524 }
2525
2526 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2527                                            struct policy_handle *alias_handle)
2528 {
2529         struct samr_AddMultipleMembersToAlias a;
2530         struct samr_RemoveMultipleMembersFromAlias r;
2531         NTSTATUS status;
2532         struct lsa_SidArray sids;
2533
2534         torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2535         a.in.alias_handle = alias_handle;
2536         a.in.sids = &sids;
2537
2538         sids.num_sids = 3;
2539         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2540
2541         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2542         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2543         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2544
2545         status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2546         torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2547
2548
2549         torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2550         r.in.alias_handle = alias_handle;
2551         r.in.sids = &sids;
2552
2553         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2554         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2555
2556         /* strange! removing twice doesn't give any error */
2557         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2558         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2559
2560         /* but removing an alias that isn't there does */
2561         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2562
2563         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2564         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2565
2566         return true;
2567 }
2568
2569 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2570                                             struct policy_handle *user_handle)
2571 {
2572         struct samr_TestPrivateFunctionsUser r;
2573         NTSTATUS status;
2574
2575         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2576
2577         r.in.user_handle = user_handle;
2578
2579         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2580         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2581
2582         return true;
2583 }
2584
2585 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2586                                           struct torture_context *tctx,
2587                                           struct policy_handle *handle,
2588                                           bool use_info2,
2589                                           NTTIME *pwdlastset)
2590 {
2591         NTSTATUS status;
2592         uint16_t levels[] = { /* 3, */ 5, 21 };
2593         int i;
2594         NTTIME pwdlastset3 = 0;
2595         NTTIME pwdlastset5 = 0;
2596         NTTIME pwdlastset21 = 0;
2597
2598         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2599                         use_info2 ? "2":"");
2600
2601         for (i=0; i<ARRAY_SIZE(levels); i++) {
2602
2603                 struct samr_QueryUserInfo r;
2604                 struct samr_QueryUserInfo2 r2;
2605                 union samr_UserInfo *info;
2606
2607                 if (use_info2) {
2608                         r2.in.user_handle = handle;
2609                         r2.in.level = levels[i];
2610                         r2.out.info = &info;
2611                         status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2612
2613                 } else {
2614                         r.in.user_handle = handle;
2615                         r.in.level = levels[i];
2616                         r.out.info = &info;
2617                         status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2618                 }
2619
2620                 if (!NT_STATUS_IS_OK(status) &&
2621                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2622                         printf("QueryUserInfo%s level %u failed - %s\n",
2623                                use_info2 ? "2":"", levels[i], nt_errstr(status));
2624                         return false;
2625                 }
2626
2627                 switch (levels[i]) {
2628                 case 3:
2629                         pwdlastset3 = info->info3.last_password_change;
2630                         break;
2631                 case 5:
2632                         pwdlastset5 = info->info5.last_password_change;
2633                         break;
2634                 case 21:
2635                         pwdlastset21 = info->info21.last_password_change;
2636                         break;
2637                 default:
2638                         return false;
2639                 }
2640         }
2641         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2642                                     "pwdlastset mixup"); */
2643         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2644                                  "pwdlastset mixup");
2645
2646         *pwdlastset = pwdlastset21;
2647
2648         torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2649
2650         return true;
2651 }
2652
2653 static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
2654                                 struct cli_credentials *machine_credentials,
2655                                 struct cli_credentials *test_credentials,
2656                                 struct netlogon_creds_CredentialState *creds,
2657                                 NTSTATUS expected_result)
2658 {
2659         NTSTATUS status;
2660         struct netr_LogonSamLogon r;
2661         struct netr_Authenticator auth, auth2;
2662         union netr_LogonLevel logon;
2663         union netr_Validation validation;
2664         uint8_t authoritative;
2665         struct netr_NetworkInfo ninfo;
2666         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2667         int flags = CLI_CRED_NTLM_AUTH;
2668
2669         if (lp_client_lanman_auth(tctx->lp_ctx)) {
2670                 flags |= CLI_CRED_LANMAN_AUTH;
2671         }
2672
2673         if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2674                 flags |= CLI_CRED_NTLMv2_AUTH;
2675         }
2676
2677         cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2678                                                  &ninfo.identity_info.account_name.string,
2679                                                  &ninfo.identity_info.domain_name.string);
2680
2681         generate_random_buffer(ninfo.challenge,
2682                                sizeof(ninfo.challenge));
2683         chal = data_blob_const(ninfo.challenge,
2684                                sizeof(ninfo.challenge));
2685
2686         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
2687                                                 cli_credentials_get_domain(machine_credentials));
2688
2689         status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2690                                                    &flags,
2691                                                    chal,
2692                                                    names_blob,
2693                                                    &lm_resp, &nt_resp,
2694                                                    NULL, NULL);
2695         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2696
2697         ninfo.lm.data = lm_resp.data;
2698         ninfo.lm.length = lm_resp.length;
2699
2700         ninfo.nt.data = nt_resp.data;
2701         ninfo.nt.length = nt_resp.length;
2702
2703         ninfo.identity_info.parameter_control =
2704                 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2705                 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2706         ninfo.identity_info.logon_id_low = 0;
2707         ninfo.identity_info.logon_id_high = 0;
2708         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
2709
2710         logon.network = &ninfo;
2711
2712         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2713         r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2714         r.in.credential = &auth;
2715         r.in.return_authenticator = &auth2;
2716         r.in.logon_level = 2;
2717         r.in.logon = &logon;
2718         r.out.validation = &validation;
2719         r.out.authoritative = &authoritative;
2720
2721         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2722
2723         ZERO_STRUCT(auth2);
2724         netlogon_creds_client_authenticator(creds, &auth);
2725
2726         r.in.validation_level = 2;
2727
2728         status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
2729         if (!NT_STATUS_IS_OK(status)) {
2730                 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
2731                 return true;
2732         } else {
2733                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
2734         }
2735
2736         torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
2737                         "Credential chaining failed");
2738
2739         return true;
2740 }
2741
2742 static bool test_SamLogon(struct torture_context *tctx,
2743                           struct dcerpc_pipe *p,
2744                           struct cli_credentials *machine_credentials,
2745                           struct cli_credentials *test_credentials,
2746                           NTSTATUS expected_result)
2747 {
2748         struct netlogon_creds_CredentialState *creds;
2749
2750         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
2751                 return false;
2752         }
2753
2754         return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
2755                                    creds, expected_result);
2756 }
2757
2758 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2759                                      struct dcerpc_pipe *p,
2760                                      struct cli_credentials *machine_creds,
2761                                      const char *acct_name,
2762                                      char *password,
2763                                      NTSTATUS expected_samlogon_result)
2764 {
2765         bool ret = true;
2766         struct cli_credentials *test_credentials;
2767
2768         test_credentials = cli_credentials_init(tctx);
2769
2770         cli_credentials_set_workstation(test_credentials,
2771                                         TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
2772         cli_credentials_set_domain(test_credentials,
2773                                    lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
2774         cli_credentials_set_username(test_credentials,
2775                                      acct_name, CRED_SPECIFIED);
2776         cli_credentials_set_password(test_credentials,
2777                                      password, CRED_SPECIFIED);
2778         cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
2779
2780         printf("testing samlogon as %s@%s password: %s\n",
2781                 acct_name, TEST_ACCOUNT_NAME_PWD, password);
2782
2783         if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
2784                            expected_samlogon_result)) {
2785                 torture_warning(tctx, "new password did not work\n");
2786                 ret = false;
2787         }
2788
2789         return ret;
2790 }
2791
2792 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2793                                    struct dcerpc_pipe *np,
2794                                    struct torture_context *tctx,
2795                                    struct policy_handle *handle,
2796                                    uint16_t level,
2797                                    uint32_t fields_present,
2798                                    uint8_t password_expired,
2799                                    bool *matched_expected_error,
2800                                    bool use_setinfo2,
2801                                    const char *acct_name,
2802                                    char **password,
2803                                    struct cli_credentials *machine_creds,
2804                                    bool use_queryinfo2,
2805                                    NTTIME *pwdlastset,
2806                                    NTSTATUS expected_samlogon_result)
2807 {
2808         const char *fields = NULL;
2809         bool ret = true;
2810
2811         switch (level) {
2812         case 21:
2813         case 23:
2814         case 25:
2815                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2816                                          fields_present);
2817                 break;
2818         default:
2819                 break;
2820         }
2821
2822         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2823                 "(password_expired: %d) %s\n",
2824                 use_setinfo2 ? "2":"", level, password_expired,
2825                 fields ? fields : "");
2826
2827         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2828                                        fields_present,
2829                                        password,
2830                                        password_expired,
2831                                        use_setinfo2,
2832                                        matched_expected_error)) {
2833                 ret = false;
2834         }
2835
2836         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2837                                            use_queryinfo2,
2838                                            pwdlastset)) {
2839                 ret = false;
2840         }
2841
2842         if (*matched_expected_error == true) {
2843                 return ret;
2844         }
2845
2846         if (!test_SamLogon_with_creds(tctx, np,
2847                                       machine_creds,
2848                                       acct_name,
2849                                       *password,
2850                                       expected_samlogon_result)) {
2851                 ret = false;
2852         }
2853
2854         return ret;
2855 }
2856
2857 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2858                                         struct torture_context *tctx,
2859                                         uint32_t acct_flags,
2860                                         const char *acct_name,
2861                                         struct policy_handle *handle,
2862                                         char **password,
2863                                         struct cli_credentials *machine_credentials)
2864 {
2865         int s = 0, q = 0, f = 0, l = 0, z = 0;
2866         bool ret = true;
2867         int delay = 500000;
2868         bool set_levels[] = { false, true };
2869         bool query_levels[] = { false, true };
2870         uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2871         uint32_t nonzeros[] = { 1, 24 };
2872         uint32_t fields_present[] = {
2873                 0,
2874                 SAMR_FIELD_EXPIRED_FLAG,
2875                 SAMR_FIELD_LAST_PWD_CHANGE,
2876                 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2877                 SAMR_FIELD_COMMENT,
2878                 SAMR_FIELD_NT_PASSWORD_PRESENT,
2879                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2880                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2881                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2882                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2883                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2884                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2885         };
2886         NTSTATUS status;
2887         struct dcerpc_pipe *np = NULL;
2888
2889         if (torture_setting_bool(tctx, "samba3", false)) {
2890                 delay = 1000000;
2891                 printf("Samba3 has second granularity, setting delay to: %d\n",
2892                         delay);
2893         }
2894
2895         status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
2896         if (!NT_STATUS_IS_OK(status)) {
2897                 return false;
2898         }
2899
2900         /* set to 1 to enable testing for all possible opcode
2901            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2902            combinations */
2903 #if 0
2904 #define TEST_SET_LEVELS 1
2905 #define TEST_QUERY_LEVELS 1
2906 #endif
2907         for (l=0; l<ARRAY_SIZE(levels); l++) {
2908         for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2909         for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2910 #ifdef TEST_SET_LEVELS
2911         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2912 #endif
2913 #ifdef TEST_QUERY_LEVELS
2914         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2915 #endif
2916                 NTTIME pwdlastset_old = 0;
2917                 NTTIME pwdlastset_new = 0;
2918                 bool matched_expected_error = false;
2919                 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2920
2921                 torture_comment(tctx, "------------------------------\n"
2922                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2923                                 "(s: %d (l: %d), q: %d)\n",
2924                                 acct_flags, s, levels[l], q);
2925
2926                 switch (levels[l]) {
2927                 case 21:
2928                 case 23:
2929                 case 25:
2930                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2931                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2932                                 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2933                         }
2934                         break;
2935                 }
2936
2937
2938                 /* set #1 */
2939
2940                 /* set a password and force password change (pwdlastset 0) by
2941                  * setting the password expired flag to a non-0 value */
2942
2943                 if (!test_SetPassword_level(p, np, tctx, handle,
2944                                             levels[l],
2945                                             fields_present[f],
2946                                             nonzeros[z],
2947                                             &matched_expected_error,
2948                                             set_levels[s],
2949                                             acct_name,
2950                                             password,
2951                                             machine_credentials,
2952                                             query_levels[q],
2953                                             &pwdlastset_old,
2954                                             expected_samlogon_result)) {
2955                         ret = false;
2956                 }
2957
2958                 if (matched_expected_error == true) {
2959                         /* skipping on expected failure */
2960                         continue;
2961                 }
2962
2963                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2964                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2965
2966                 switch (levels[l]) {
2967                 case 21:
2968                 case 23:
2969                 case 25:
2970                         if ((pwdlastset_new != 0) &&
2971                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2972                                 torture_comment(tctx, "not considering a non-0 "
2973                                         "pwdLastSet as a an error as the "
2974                                         "SAMR_FIELD_EXPIRED_FLAG has not "
2975                                         "been set\n");
2976                                 break;
2977                         }
2978                 default:
2979                         if (pwdlastset_new != 0) {
2980                                 torture_warning(tctx, "pwdLastSet test failed: "
2981                                         "expected pwdLastSet 0 but got %lld\n",
2982                                         pwdlastset_old);
2983                                 ret = false;
2984                         }
2985                         break;
2986                 }
2987
2988                 switch (levels[l]) {
2989                 case 21:
2990                 case 23:
2991                 case 25:
2992                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2993                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
2994                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
2995                              (pwdlastset_old >= pwdlastset_new)) {
2996                                 torture_warning(tctx, "pwdlastset not increasing\n");
2997                                 ret = false;
2998                         }
2999                         break;
3000                 default:
3001                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3002                             (pwdlastset_old >= pwdlastset_new)) {
3003                                 torture_warning(tctx, "pwdlastset not increasing\n");
3004                                 ret = false;
3005                         }
3006                         break;
3007                 }
3008
3009                 usleep(delay);
3010
3011                 /* set #2 */
3012
3013                 /* set a password, pwdlastset needs to get updated (increased
3014                  * value), password_expired value used here is 0 */
3015
3016                 if (!test_SetPassword_level(p, np, tctx, handle,
3017                                             levels[l],
3018                                             fields_present[f],
3019                                             0,
3020                                             &matched_expected_error,
3021                                             set_levels[s],
3022                                             acct_name,
3023                                             password,
3024                                             machine_credentials,
3025                                             query_levels[q],
3026                                             &pwdlastset_new,
3027                                             expected_samlogon_result)) {
3028                         ret = false;
3029                 }
3030
3031                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3032                  * and must be larger then the old value */
3033
3034                 switch (levels[l]) {
3035                 case 21:
3036                 case 23:
3037                 case 25:
3038
3039                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3040                          * password has been changed, old and new pwdlastset
3041                          * need to be the same value */
3042
3043                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3044                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3045                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3046                         {
3047                                 torture_assert_int_equal(tctx, pwdlastset_old,
3048                                         pwdlastset_new, "pwdlastset must be equal");
3049                                 break;
3050                         }
3051                 default:
3052                         if (pwdlastset_old >= pwdlastset_new) {
3053                                 torture_warning(tctx, "pwdLastSet test failed: "
3054                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3055                                         pwdlastset_old, pwdlastset_new);
3056                                 ret = false;
3057                         }
3058                         if (pwdlastset_new == 0) {
3059                                 torture_warning(tctx, "pwdLastSet test failed: "
3060                                         "expected non-0 pwdlastset, got: %lld\n",
3061                                         pwdlastset_new);
3062                                 ret = false;
3063                         }
3064                 }
3065
3066                 switch (levels[l]) {
3067                 case 21:
3068                 case 23:
3069                 case 25:
3070                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3071                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3072                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3073                              (pwdlastset_old >= pwdlastset_new)) {
3074                                 torture_warning(tctx, "pwdlastset not increasing\n");
3075                                 ret = false;
3076                         }
3077                         break;
3078                 default:
3079                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3080                             (pwdlastset_old >= pwdlastset_new)) {
3081                                 torture_warning(tctx, "pwdlastset not increasing\n");
3082                                 ret = false;
3083                         }
3084                         break;
3085                 }
3086
3087                 pwdlastset_old = pwdlastset_new;
3088
3089                 usleep(delay);
3090
3091                 /* set #2b */
3092
3093                 /* set a password, pwdlastset needs to get updated (increased
3094                  * value), password_expired value used here is 0 */
3095
3096                 if (!test_SetPassword_level(p, np, tctx, handle,
3097                                             levels[l],
3098                                             fields_present[f],
3099                                             0,
3100                                             &matched_expected_error,
3101                                             set_levels[s],
3102                                             acct_name,
3103                                             password,
3104                                             machine_credentials,
3105                                             query_levels[q],
3106                                             &pwdlastset_new,
3107                                             expected_samlogon_result)) {
3108                         ret = false;
3109                 }
3110
3111                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3112                  * and must be larger then the old value */
3113
3114                 switch (levels[l]) {
3115                 case 21:
3116                 case 23:
3117                 case 25:
3118
3119                         /* if no password has been changed, old and new pwdlastset
3120                          * need to be the same value */
3121
3122                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3123                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3124                         {
3125                                 torture_assert_int_equal(tctx, pwdlastset_old,
3126                                         pwdlastset_new, "pwdlastset must be equal");
3127                                 break;
3128                         }
3129                 default:
3130                         if (pwdlastset_old >= pwdlastset_new) {
3131                                 torture_warning(tctx, "pwdLastSet test failed: "
3132                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3133                                         pwdlastset_old, pwdlastset_new);
3134                                 ret = false;
3135                         }
3136                         if (pwdlastset_new == 0) {
3137                                 torture_warning(tctx, "pwdLastSet test failed: "
3138                                         "expected non-0 pwdlastset, got: %lld\n",
3139                                         pwdlastset_new);
3140                                 ret = false;
3141                         }
3142                 }
3143
3144                 /* set #3 */
3145
3146                 /* set a password and force password change (pwdlastset 0) by
3147                  * setting the password expired flag to a non-0 value */
3148
3149                 if (!test_SetPassword_level(p, np, tctx, handle,
3150                                             levels[l],
3151                                             fields_present[f],
3152                                             nonzeros[z],
3153                                             &matched_expected_error,
3154                                             set_levels[s],
3155                                             acct_name,
3156                                             password,
3157                                             machine_credentials,
3158                                             query_levels[q],
3159                                             &pwdlastset_new,
3160                                             expected_samlogon_result)) {
3161                         ret = false;
3162                 }
3163
3164                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3165                  * set without the SAMR_FIELD_EXPIRED_FLAG */
3166
3167                 switch (levels[l]) {
3168                 case 21:
3169                 case 23:
3170                 case 25:
3171                         if ((pwdlastset_new != 0) &&
3172                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3173                                 torture_comment(tctx, "not considering a non-0 "
3174                                         "pwdLastSet as a an error as the "
3175                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3176                                         "been set\n");
3177                                 break;
3178                         }
3179
3180                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3181                          * password has been changed, old and new pwdlastset
3182                          * need to be the same value */
3183
3184                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3185                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3186                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3187                         {
3188                                 torture_assert_int_equal(tctx, pwdlastset_old,
3189                                         pwdlastset_new, "pwdlastset must be equal");
3190                                 break;
3191                         }
3192                 default:
3193
3194                         if (pwdlastset_old == pwdlastset_new) {
3195                                 torture_warning(tctx, "pwdLastSet test failed: "
3196                                         "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3197                                         pwdlastset_old, pwdlastset_new);
3198                                 ret = false;
3199                         }
3200
3201                         if (pwdlastset_new != 0) {
3202                                 torture_warning(tctx, "pwdLastSet test failed: "
3203                                         "expected pwdLastSet 0, got %lld\n",
3204                                         pwdlastset_old);
3205                                 ret = false;
3206                         }
3207                         break;
3208                 }
3209
3210                 switch (levels[l]) {
3211                 case 21:
3212                 case 23:
3213                 case 25:
3214                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3215                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3216                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3217                              (pwdlastset_old >= pwdlastset_new)) {
3218                                 torture_warning(tctx, "pwdlastset not increasing\n");
3219                                 ret = false;
3220                         }
3221                         break;
3222                 default:
3223                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3224                             (pwdlastset_old >= pwdlastset_new)) {
3225                                 torture_warning(tctx, "pwdlastset not increasing\n");
3226                                 ret = false;
3227                         }
3228                         break;
3229                 }
3230
3231                 /* if the level we are testing does not have a fields_present
3232                  * field, skip all fields present tests by setting f to to
3233                  * arraysize */
3234                 switch (levels[l]) {
3235                 case 18:
3236                 case 24:
3237                 case 26:
3238                         f = ARRAY_SIZE(fields_present);
3239                         break;
3240                 }
3241
3242 #ifdef TEST_QUERY_LEVELS
3243         }
3244 #endif
3245 #ifdef TEST_SET_LEVELS
3246         }
3247 #endif
3248         } /* fields present */
3249         } /* nonzeros */
3250         } /* levels */
3251
3252 #undef TEST_SET_LEVELS
3253 #undef TEST_QUERY_LEVELS
3254
3255         return ret;
3256 }
3257
3258 static bool test_user_ops(struct dcerpc_pipe *p, 
3259                           struct torture_context *tctx,
3260                           struct policy_handle *user_handle, 
3261                           struct policy_handle *domain_handle, 
3262                           uint32_t base_acct_flags, 
3263                           const char *base_acct_name, enum torture_samr_choice which_ops,
3264                           struct cli_credentials *machine_credentials)
3265 {
3266         char *password = NULL;
3267         struct samr_QueryUserInfo q;
3268         union samr_UserInfo *info;
3269         NTSTATUS status;
3270
3271         bool ret = true;
3272         int i;
3273         uint32_t rid;
3274         const uint32_t password_fields[] = {
3275                 SAMR_FIELD_NT_PASSWORD_PRESENT,
3276                 SAMR_FIELD_LM_PASSWORD_PRESENT,
3277                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3278                 0
3279         };
3280         
3281         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3282         if (!NT_STATUS_IS_OK(status)) {
3283                 ret = false;
3284         }
3285
3286         switch (which_ops) {
3287         case TORTURE_SAMR_USER_ATTRIBUTES:
3288                 if (!test_QuerySecurity(p, tctx, user_handle)) {
3289                         ret = false;
3290                 }
3291
3292                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3293                         ret = false;
3294                 }
3295
3296                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3297                         ret = false;
3298                 }
3299
3300                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3301                                       base_acct_name)) {
3302                         ret = false;
3303                 }       
3304
3305                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3306                         ret = false;
3307                 }
3308
3309                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3310                         ret = false;
3311                 }
3312
3313                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3314                         ret = false;
3315                 }
3316                 break;
3317         case TORTURE_SAMR_PASSWORDS:
3318                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3319                         char simple_pass[9];
3320                         char *v = generate_random_str(tctx, 1);
3321                         
3322                         ZERO_STRUCT(simple_pass);
3323                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
3324
3325                         printf("Testing machine account password policy rules\n");
3326
3327                         /* Workstation trust accounts don't seem to need to honour password quality policy */
3328                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3329                                 ret = false;
3330                         }
3331
3332                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3333                                 ret = false;
3334                         }
3335
3336                         /* reset again, to allow another 'user' password change */
3337                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3338                                 ret = false;
3339                         }
3340
3341                         /* Try a 'short' password */
3342                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3343                                 ret = false;
3344                         }
3345
3346                         /* Try a compleatly random password */
3347                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3348                                 ret = false;
3349                         }
3350                 }
3351
3352                 for (i = 0; password_fields[i]; i++) {
3353                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3354                                 ret = false;
3355                         }       
3356                 
3357                         /* check it was set right */
3358                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3359                                 ret = false;
3360                         }
3361                 }               
3362
3363                 for (i = 0; password_fields[i]; i++) {
3364                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3365                                 ret = false;
3366                         }       
3367                 
3368                         /* check it was set right */
3369                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3370                                 ret = false;
3371                         }
3372                 }               
3373
3374                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3375                         ret = false;
3376                 }       
3377
3378                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3379                         ret = false;
3380                 }       
3381
3382                 if (torture_setting_bool(tctx, "samba4", false)) {
3383                         printf("skipping Set Password level 18 and 21 against Samba4\n");
3384                 } else {
3385
3386                         if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3387                                 ret = false;
3388                         }
3389
3390                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3391                                 ret = false;
3392                         }
3393
3394                         for (i = 0; password_fields[i]; i++) {
3395
3396                                 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3397                                         /* we need to skip as that would break
3398                                          * the ChangePasswordUser3 verify */
3399                                         continue;
3400                                 }
3401
3402                                 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3403                                         ret = false;
3404                                 }
3405
3406                                 /* check it was set right */
3407                                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3408                                         ret = false;
3409                                 }
3410                         }
3411                 }
3412
3413                 q.in.user_handle = user_handle;
3414                 q.in.level = 5;
3415                 q.out.info = &info;
3416                 
3417                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3418                 if (!NT_STATUS_IS_OK(status)) {
3419                         printf("QueryUserInfo level %u failed - %s\n", 
3420                                q.in.level, nt_errstr(status));
3421                         ret = false;
3422                 } else {
3423                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3424                         if ((info->info5.acct_flags) != expected_flags) {
3425                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3426                                        info->info5.acct_flags,
3427                                        expected_flags);
3428                                 /* FIXME: GD */
3429                                 if (!torture_setting_bool(tctx, "samba3", false)) {
3430                                         ret = false;
3431                                 }
3432                         }
3433                         if (info->info5.rid != rid) {
3434                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3435                                        info->info5.rid, rid);
3436
3437                         }
3438                 }
3439
3440                 break;
3441
3442         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3443
3444                 /* test last password change timestamp behaviour */
3445                 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3446                                                  base_acct_name,
3447                                                  user_handle, &password,
3448                                                  machine_credentials)) {
3449                         ret = false;
3450                 }
3451
3452                 if (ret == true) {
3453                         torture_comment(tctx, "pwdLastSet test succeeded\n");
3454                 } else {
3455                         torture_warning(tctx, "pwdLastSet test failed\n");
3456                 }
3457
3458                 break;
3459
3460         case TORTURE_SAMR_OTHER:
3461                 /* We just need the account to exist */
3462                 break;
3463         }
3464         return ret;
3465 }
3466
3467 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3468                            struct policy_handle *alias_handle,
3469                            const struct dom_sid *domain_sid)
3470 {
3471         bool ret = true;
3472
3473         if (!test_QuerySecurity(p, tctx, alias_handle)) {
3474                 ret = false;
3475         }
3476
3477         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3478                 ret = false;
3479         }
3480
3481         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3482                 ret = false;
3483         }
3484
3485         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3486                 ret = false;
3487         }
3488
3489         if (torture_setting_bool(tctx, "samba4", false)) {
3490                 printf("skipping MultipleMembers Alias tests against Samba4\n");
3491                 return ret;
3492         }
3493
3494         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3495                 ret = false;
3496         }
3497
3498         return ret;
3499 }
3500
3501
3502 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3503                                      struct policy_handle *user_handle)
3504 {
3505         struct samr_DeleteUser d;
3506         NTSTATUS status;
3507         torture_comment(tctx, "Testing DeleteUser\n");
3508
3509         d.in.user_handle = user_handle;
3510         d.out.user_handle = user_handle;
3511
3512         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3513         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3514
3515         return true;
3516 }
3517
3518 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3519                             struct policy_handle *handle, const char *name)
3520 {
3521         NTSTATUS status;
3522         struct samr_DeleteUser d;
3523         struct policy_handle user_handle;
3524         uint32_t rid;
3525
3526         status = test_LookupName(p, mem_ctx, handle, name, &rid);
3527         if (!NT_STATUS_IS_OK(status)) {
3528                 goto failed;
3529         }
3530
3531         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
3532         if (!NT_STATUS_IS_OK(status)) {
3533                 goto failed;
3534         }
3535
3536         d.in.user_handle = &user_handle;
3537         d.out.user_handle = &user_handle;
3538         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
3539         if (!NT_STATUS_IS_OK(status)) {
3540                 goto failed;
3541         }
3542
3543         return true;
3544
3545 failed:
3546         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3547         return false;
3548 }
3549
3550
3551 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3552                                     struct policy_handle *handle, const char *name)
3553 {
3554         NTSTATUS status;
3555         struct samr_OpenGroup r;
3556         struct samr_DeleteDomainGroup d;
3557         struct policy_handle group_handle;
3558         uint32_t rid;
3559
3560         status = test_LookupName(p, mem_ctx, handle, name, &rid);
3561         if (!NT_STATUS_IS_OK(status)) {
3562                 goto failed;
3563         }
3564
3565         r.in.domain_handle = handle;
3566         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3567         r.in.rid = rid;
3568         r.out.group_handle = &group_handle;
3569         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3570         if (!NT_STATUS_IS_OK(status)) {
3571                 goto failed;
3572         }
3573
3574         d.in.group_handle = &group_handle;
3575         d.out.group_handle = &group_handle;
3576         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3577         if (!NT_STATUS_IS_OK(status)) {
3578                 goto failed;
3579         }
3580
3581         return true;
3582
3583 failed:
3584         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3585         return false;
3586 }
3587
3588
3589 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3590                                    struct policy_handle *domain_handle, const char *name)
3591 {
3592         NTSTATUS status;
3593         struct samr_OpenAlias r;
3594         struct samr_DeleteDomAlias d;
3595         struct policy_handle alias_handle;
3596         uint32_t rid;
3597
3598         printf("testing DeleteAlias_byname\n");
3599
3600         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
3601         if (!NT_STATUS_IS_OK(status)) {
3602                 goto failed;
3603         }
3604
3605         r.in.domain_handle = domain_handle;
3606         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3607         r.in.rid = rid;
3608         r.out.alias_handle = &alias_handle;
3609         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3610         if (!NT_STATUS_IS_OK(status)) {
3611                 goto failed;
3612         }
3613
3614         d.in.alias_handle = &alias_handle;
3615         d.out.alias_handle = &alias_handle;
3616         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3617         if (!NT_STATUS_IS_OK(status)) {
3618                 goto failed;
3619         }
3620
3621         return true;
3622
3623 failed:
3624         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3625         return false;
3626 }
3627
3628 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3629                                      struct policy_handle *alias_handle)
3630 {
3631         struct samr_DeleteDomAlias d;
3632         NTSTATUS status;
3633         bool ret = true;
3634         printf("Testing DeleteAlias\n");
3635
3636         d.in.alias_handle = alias_handle;
3637         d.out.alias_handle = alias_handle;
3638
3639         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
3640         if (!NT_STATUS_IS_OK(status)) {
3641                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3642                 ret = false;
3643         }
3644
3645         return ret;
3646 }
3647
3648 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3649                             struct policy_handle *domain_handle, 
3650                              struct policy_handle *alias_handle, 
3651                              const struct dom_sid *domain_sid)
3652 {
3653         NTSTATUS status;
3654         struct samr_CreateDomAlias r;
3655         struct lsa_String name;
3656         uint32_t rid;
3657         bool ret = true;
3658
3659         init_lsa_String(&name, TEST_ALIASNAME);
3660         r.in.domain_handle = domain_handle;
3661         r.in.alias_name = &name;
3662         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3663         r.out.alias_handle = alias_handle;
3664         r.out.rid = &rid;
3665
3666         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
3667
3668         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3669
3670         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3671                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3672                         printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
3673                         return true;
3674                 } else {
3675                         printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string, 
3676                                nt_errstr(status));
3677                         return false;
3678                 }
3679         }
3680
3681         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
3682                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
3683                         return false;
3684                 }
3685                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
3686         }
3687
3688         if (!NT_STATUS_IS_OK(status)) {
3689                 printf("CreateAlias failed - %s\n", nt_errstr(status));
3690                 return false;
3691         }
3692
3693         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
3694                 ret = false;
3695         }
3696
3697         return ret;
3698 }
3699
3700 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3701                                 const char *acct_name,
3702                                 struct policy_handle *domain_handle, char **password)
3703 {
3704         bool ret = true;
3705
3706         if (!*password) {
3707                 return false;
3708         }
3709
3710         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
3711                 ret = false;
3712         }
3713
3714         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
3715                 ret = false;
3716         }
3717
3718         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
3719                 ret = false;
3720         }
3721
3722         /* test what happens when setting the old password again */
3723         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
3724                 ret = false;
3725         }
3726
3727         {
3728                 char simple_pass[9];
3729                 char *v = generate_random_str(mem_ctx, 1);
3730
3731                 ZERO_STRUCT(simple_pass);
3732                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
3733
3734                 /* test what happens when picking a simple password */
3735                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
3736                         ret = false;
3737                 }
3738         }
3739
3740         /* set samr_SetDomainInfo level 1 with min_length 5 */
3741         {
3742                 struct samr_QueryDomainInfo r;
3743                 union samr_DomainInfo *info = NULL;
3744                 struct samr_SetDomainInfo s;
3745                 uint16_t len_old, len;
3746                 uint32_t pwd_prop_old;
3747                 int64_t min_pwd_age_old;
3748                 NTSTATUS status;
3749
3750                 len = 5;
3751
3752                 r.in.domain_handle = domain_handle;
3753                 r.in.level = 1;
3754                 r.out.info = &info;
3755
3756                 printf("testing samr_QueryDomainInfo level 1\n");
3757                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3758                 if (!NT_STATUS_IS_OK(status)) {
3759                         return false;
3760                 }
3761
3762                 s.in.domain_handle = domain_handle;
3763                 s.in.level = 1;
3764                 s.in.info = info;
3765
3766                 /* remember the old min length, so we can reset it */
3767                 len_old = s.in.info->info1.min_password_length;
3768                 s.in.info->info1.min_password_length = len;
3769                 pwd_prop_old = s.in.info->info1.password_properties;
3770                 /* turn off password complexity checks for this test */
3771                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
3772
3773                 min_pwd_age_old = s.in.info->info1.min_password_age;
3774                 s.in.info->info1.min_password_age = 0;
3775
3776                 printf("testing samr_SetDomainInfo level 1\n");
3777                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3778                 if (!NT_STATUS_IS_OK(status)) {
3779                         return false;
3780                 }
3781
3782                 printf("calling test_ChangePasswordUser3 with too short password\n");
3783
3784                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
3785                         ret = false;
3786                 }
3787
3788                 s.in.info->info1.min_password_length = len_old;
3789                 s.in.info->info1.password_properties = pwd_prop_old;
3790                 s.in.info->info1.min_password_age = min_pwd_age_old;
3791                 
3792                 printf("testing samr_SetDomainInfo level 1\n");
3793                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3794                 if (!NT_STATUS_IS_OK(status)) {
3795                         return false;
3796                 }
3797
3798         }
3799
3800         {
3801                 NTSTATUS status;
3802                 struct samr_OpenUser r;
3803                 struct samr_QueryUserInfo q;
3804                 union samr_UserInfo *info;
3805                 struct samr_LookupNames n;
3806                 struct policy_handle user_handle;
3807                 struct samr_Ids rids, types;
3808
3809                 n.in.domain_handle = domain_handle;
3810                 n.in.num_names = 1;
3811                 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
3812                 n.in.names[0].string = acct_name; 
3813                 n.out.rids = &rids;
3814                 n.out.types = &types;
3815
3816                 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3817                 if (!NT_STATUS_IS_OK(status)) {
3818                         printf("LookupNames failed - %s\n", nt_errstr(status));
3819                         return false;
3820                 }
3821
3822                 r.in.domain_handle = domain_handle;
3823                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3824                 r.in.rid = n.out.rids->ids[0];
3825                 r.out.user_handle = &user_handle;
3826
3827                 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3828                 if (!NT_STATUS_IS_OK(status)) {
3829                         printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
3830                         return false;
3831                 }
3832
3833                 q.in.user_handle = &user_handle;
3834                 q.in.level = 5;
3835                 q.out.info = &info;
3836
3837                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3838                 if (!NT_STATUS_IS_OK(status)) {
3839                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
3840                         return false;
3841                 }
3842
3843                 printf("calling test_ChangePasswordUser3 with too early password change\n");
3844
3845                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
3846                                               info->info5.last_password_change, true)) {
3847                         ret = false;
3848                 }
3849         }
3850
3851         /* we change passwords twice - this has the effect of verifying
3852            they were changed correctly for the final call */
3853         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3854                 ret = false;
3855         }
3856
3857         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
3858                 ret = false;
3859         }
3860
3861         return ret;
3862 }
3863
3864 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3865                             struct policy_handle *domain_handle, 
3866                             struct policy_handle *user_handle_out,
3867                             struct dom_sid *domain_sid, 
3868                             enum torture_samr_choice which_ops,
3869                             struct cli_credentials *machine_credentials)
3870 {
3871
3872         TALLOC_CTX *user_ctx;
3873
3874         NTSTATUS status;
3875         struct samr_CreateUser r;
3876         struct samr_QueryUserInfo q;
3877         union samr_UserInfo *info;
3878         struct samr_DeleteUser d;
3879         uint32_t rid;
3880
3881         /* This call creates a 'normal' account - check that it really does */
3882         const uint32_t acct_flags = ACB_NORMAL;
3883         struct lsa_String name;
3884         bool ret = true;
3885
3886         struct policy_handle user_handle;
3887         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
3888         init_lsa_String(&name, TEST_ACCOUNT_NAME);
3889
3890         r.in.domain_handle = domain_handle;
3891         r.in.account_name = &name;
3892         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3893         r.out.user_handle = &user_handle;
3894         r.out.rid = &rid;
3895
3896         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
3897
3898         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3899
3900         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
3901                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
3902                         printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
3903                         return true;
3904                 } else {
3905                         printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
3906                                nt_errstr(status));
3907                         return false;
3908                 }
3909         }
3910
3911         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3912                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
3913                         talloc_free(user_ctx);
3914                         return false;
3915                 }
3916                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
3917         }
3918         if (!NT_STATUS_IS_OK(status)) {
3919                 talloc_free(user_ctx);
3920                 printf("CreateUser failed - %s\n", nt_errstr(status));
3921                 return false;
3922         } else {
3923                 q.in.user_handle = &user_handle;
3924                 q.in.level = 16;
3925                 q.out.info = &info;
3926                 
3927                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
3928                 if (!NT_STATUS_IS_OK(status)) {
3929                         printf("QueryUserInfo level %u failed - %s\n", 
3930                                q.in.level, nt_errstr(status));
3931                         ret = false;
3932                 } else {
3933                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
3934                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3935                                        info->info16.acct_flags,
3936                                        acct_flags);
3937                                 ret = false;
3938                         }
3939                 }
3940                 
3941                 if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
3942                                    acct_flags, name.string, which_ops,
3943                                    machine_credentials)) {
3944                         ret = false;
3945                 }
3946                 
3947                 if (user_handle_out) {
3948                         *user_handle_out = user_handle;
3949                 } else {
3950                         printf("Testing DeleteUser (createuser test)\n");
3951                         
3952                         d.in.user_handle = &user_handle;
3953                         d.out.user_handle = &user_handle;
3954                         
3955                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
3956                         if (!NT_STATUS_IS_OK(status)) {
3957                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
3958                                 ret = false;
3959                         }
3960                 }
3961                 
3962         }
3963
3964         talloc_free(user_ctx);
3965         
3966         return ret;
3967 }
3968
3969
3970 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
3971                              struct policy_handle *domain_handle,
3972                              struct dom_sid *domain_sid,
3973                              enum torture_samr_choice which_ops,
3974                              struct cli_credentials *machine_credentials)
3975 {
3976         NTSTATUS status;
3977         struct samr_CreateUser2 r;
3978         struct samr_QueryUserInfo q;
3979         union samr_UserInfo *info;
3980         struct samr_DeleteUser d;
3981         struct policy_handle user_handle;
3982         uint32_t rid;
3983         struct lsa_String name;
3984         bool ret = true;
3985         int i;
3986
3987         struct {
3988                 uint32_t acct_flags;
3989                 const char *account_name;
3990                 NTSTATUS nt_status;
3991         } account_types[] = {
3992                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
3993                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3994                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
3995                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3996                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3997                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
3998                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
3999                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4000                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4001                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4002                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4003                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4004                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4005                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4006                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4007         };
4008
4009         for (i = 0; account_types[i].account_name; i++) {
4010                 TALLOC_CTX *user_ctx;
4011                 uint32_t acct_flags = account_types[i].acct_flags;
4012                 uint32_t access_granted;
4013                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4014                 init_lsa_String(&name, account_types[i].account_name);
4015
4016                 r.in.domain_handle = domain_handle;
4017                 r.in.account_name = &name;
4018                 r.in.acct_flags = acct_flags;
4019                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4020                 r.out.user_handle = &user_handle;
4021                 r.out.access_granted = &access_granted;
4022                 r.out.rid = &rid;
4023                 
4024                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4025                 
4026                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4027                 
4028                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4029                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4030                                 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4031                                 continue;
4032                         } else {
4033                                 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
4034                                        nt_errstr(status));
4035                                 ret = false;
4036                                 continue;
4037                         }
4038                 }
4039
4040                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4041                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4042                                 talloc_free(user_ctx);
4043                                 ret = false;
4044                                 continue;
4045                         }
4046                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4047
4048                 }
4049                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4050                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
4051                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
4052                         ret = false;
4053                 }
4054                 
4055                 if (NT_STATUS_IS_OK(status)) {
4056                         q.in.user_handle = &user_handle;
4057                         q.in.level = 5;
4058                         q.out.info = &info;
4059                         
4060                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4061                         if (!NT_STATUS_IS_OK(status)) {
4062                                 printf("QueryUserInfo level %u failed - %s\n", 
4063                                        q.in.level, nt_errstr(status));
4064                                 ret = false;
4065                         } else {
4066                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4067                                 if (acct_flags == ACB_NORMAL) {
4068                                         expected_flags |= ACB_PW_EXPIRED;
4069                                 }
4070                                 if ((info->info5.acct_flags) != expected_flags) {
4071                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4072                                                info->info5.acct_flags,
4073                                                expected_flags);
4074                                         ret = false;
4075                                 } 
4076                                 switch (acct_flags) {
4077                                 case ACB_SVRTRUST:
4078                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4079                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", 
4080                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
4081                                                 ret = false;
4082                                         }
4083                                         break;
4084                                 case ACB_WSTRUST:
4085                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4086                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", 
4087                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4088                                                 ret = false;
4089                                         }
4090                                         break;
4091                                 case ACB_NORMAL:
4092                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4093                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", 
4094                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
4095                                                 ret = false;
4096                                         }
4097                                         break;
4098                                 }
4099                         }
4100                 
4101                         if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
4102                                            acct_flags, name.string, which_ops,
4103                                            machine_credentials)) {
4104                                 ret = false;
4105                         }
4106
4107                         printf("Testing DeleteUser (createuser2 test)\n");
4108                 
4109                         d.in.user_handle = &user_handle;
4110                         d.out.user_handle = &user_handle;
4111                         
4112                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4113                         if (!NT_STATUS_IS_OK(status)) {
4114                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
4115                                 ret = false;
4116                         }
4117                 }
4118                 talloc_free(user_ctx);
4119         }
4120
4121         return ret;
4122 }
4123
4124 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4125                                 struct policy_handle *handle)
4126 {
4127         NTSTATUS status;
4128         struct samr_QueryAliasInfo r;
4129         union samr_AliasInfo *info;
4130         uint16_t levels[] = {1, 2, 3};
4131         int i;
4132         bool ret = true;
4133
4134         for (i=0;i<ARRAY_SIZE(levels);i++) {
4135                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4136
4137                 r.in.alias_handle = handle;
4138                 r.in.level = levels[i];
4139                 r.out.info = &info;
4140
4141                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
4142                 if (!NT_STATUS_IS_OK(status)) {
4143                         printf("QueryAliasInfo level %u failed - %s\n", 
4144                                levels[i], nt_errstr(status));
4145                         ret = false;
4146                 }
4147         }
4148
4149         return ret;
4150 }
4151
4152 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4153                                 struct policy_handle *handle)
4154 {
4155         NTSTATUS status;
4156         struct samr_QueryGroupInfo r;
4157         union samr_GroupInfo *info;
4158         uint16_t levels[] = {1, 2, 3, 4, 5};
4159         int i;
4160         bool ret = true;
4161
4162         for (i=0;i<ARRAY_SIZE(levels);i++) {
4163                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4164
4165                 r.in.group_handle = handle;
4166                 r.in.level = levels[i];
4167                 r.out.info = &info;
4168
4169                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4170                 if (!NT_STATUS_IS_OK(status)) {
4171                         printf("QueryGroupInfo level %u failed - %s\n", 
4172                                levels[i], nt_errstr(status));
4173                         ret = false;
4174                 }
4175         }
4176
4177         return ret;
4178 }
4179
4180 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4181                                   struct policy_handle *handle)
4182 {
4183         NTSTATUS status;
4184         struct samr_QueryGroupMember r;
4185         struct samr_RidTypeArray *rids = NULL;
4186         bool ret = true;
4187
4188         printf("Testing QueryGroupMember\n");
4189
4190         r.in.group_handle = handle;
4191         r.out.rids = &rids;
4192
4193         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
4194         if (!NT_STATUS_IS_OK(status)) {
4195                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4196                 ret = false;
4197         }
4198
4199         return ret;
4200 }
4201
4202
4203 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4204                               struct policy_handle *handle)
4205 {
4206         NTSTATUS status;
4207         struct samr_QueryGroupInfo r;
4208         union samr_GroupInfo *info;
4209         struct samr_SetGroupInfo s;
4210         uint16_t levels[] = {1, 2, 3, 4};
4211         uint16_t set_ok[] = {0, 1, 1, 1};
4212         int i;
4213         bool ret = true;
4214
4215         for (i=0;i<ARRAY_SIZE(levels);i++) {
4216                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4217
4218                 r.in.group_handle = handle;
4219                 r.in.level = levels[i];
4220                 r.out.info = &info;
4221
4222                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
4223                 if (!NT_STATUS_IS_OK(status)) {
4224                         printf("QueryGroupInfo level %u failed - %s\n", 
4225                                levels[i], nt_errstr(status));
4226                         ret = false;
4227                 }
4228
4229                 printf("Testing SetGroupInfo level %u\n", levels[i]);
4230
4231                 s.in.group_handle = handle;
4232                 s.in.level = levels[i];
4233                 s.in.info = *r.out.info;
4234
4235 #if 0
4236                 /* disabled this, as it changes the name only from the point of view of samr, 
4237                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
4238                    the name is still reserved, so creating the old name fails, but deleting by the old name
4239                    also fails */
4240                 if (s.in.level == 2) {
4241                         init_lsa_String(&s.in.info->string, "NewName");
4242                 }
4243 #endif
4244
4245                 if (s.in.level == 4) {
4246                         init_lsa_String(&s.in.info->description, "test description");
4247                 }
4248
4249                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
4250                 if (set_ok[i]) {
4251                         if (!NT_STATUS_IS_OK(status)) {
4252                                 printf("SetGroupInfo level %u failed - %s\n", 
4253                                        r.in.level, nt_errstr(status));
4254                                 ret = false;
4255                                 continue;
4256                         }
4257                 } else {
4258                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4259                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
4260                                        r.in.level, nt_errstr(status));
4261                                 ret = false;
4262                                 continue;
4263                         }
4264                 }
4265         }
4266
4267         return ret;
4268 }
4269
4270 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4271                                struct policy_handle *handle)
4272 {
4273         NTSTATUS status;
4274         struct samr_QueryUserInfo r;
4275         union samr_UserInfo *info;
4276         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4277                            11, 12, 13, 14, 16, 17, 20, 21};
4278         int i;
4279         bool ret = true;
4280
4281         for (i=0;i<ARRAY_SIZE(levels);i++) {
4282                 printf("Testing QueryUserInfo level %u\n", levels[i]);
4283
4284                 r.in.user_handle = handle;
4285                 r.in.level = levels[i];
4286                 r.out.info = &info;
4287
4288                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
4289                 if (!NT_STATUS_IS_OK(status)) {
4290                         printf("QueryUserInfo level %u failed - %s\n", 
4291                                levels[i], nt_errstr(status));
4292                         ret = false;
4293                 }
4294         }
4295
4296         return ret;
4297 }
4298
4299 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4300                                 struct policy_handle *handle)
4301 {
4302         NTSTATUS status;
4303         struct samr_QueryUserInfo2 r;
4304         union samr_UserInfo *info;
4305         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4306                            11, 12, 13, 14, 16, 17, 20, 21};
4307         int i;
4308         bool ret = true;
4309
4310         for (i=0;i<ARRAY_SIZE(levels);i++) {
4311                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4312
4313                 r.in.user_handle = handle;
4314                 r.in.level = levels[i];
4315                 r.out.info = &info;
4316
4317                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
4318                 if (!NT_STATUS_IS_OK(status)) {
4319                         printf("QueryUserInfo2 level %u failed - %s\n", 
4320                                levels[i], nt_errstr(status));
4321                         ret = false;
4322                 }
4323         }
4324
4325         return ret;
4326 }
4327
4328 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4329                           struct policy_handle *handle, uint32_t rid)
4330 {
4331         NTSTATUS status;
4332         struct samr_OpenUser r;
4333         struct policy_handle user_handle;
4334         bool ret = true;
4335
4336         printf("Testing OpenUser(%u)\n", rid);
4337
4338         r.in.domain_handle = handle;
4339         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4340         r.in.rid = rid;
4341         r.out.user_handle = &user_handle;
4342
4343         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4344         if (!NT_STATUS_IS_OK(status)) {
4345                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4346                 return false;
4347         }
4348
4349         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
4350                 ret = false;
4351         }
4352
4353         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
4354                 ret = false;
4355         }
4356
4357         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
4358                 ret = false;
4359         }
4360
4361         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
4362                 ret = false;
4363         }
4364
4365         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
4366                 ret = false;
4367         }
4368
4369         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4370                 ret = false;
4371         }
4372
4373         return ret;
4374 }
4375
4376 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4377                            struct policy_handle *handle, uint32_t rid)
4378 {
4379         NTSTATUS status;
4380         struct samr_OpenGroup r;
4381         struct policy_handle group_handle;
4382         bool ret = true;
4383
4384         printf("Testing OpenGroup(%u)\n", rid);
4385
4386         r.in.domain_handle = handle;
4387         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4388         r.in.rid = rid;
4389         r.out.group_handle = &group_handle;
4390
4391         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
4392         if (!NT_STATUS_IS_OK(status)) {
4393                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4394                 return false;
4395         }
4396
4397         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
4398                 ret = false;
4399         }
4400
4401         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
4402                 ret = false;
4403         }
4404
4405         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
4406                 ret = false;
4407         }
4408
4409         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
4410                 ret = false;
4411         }
4412
4413         return ret;
4414 }
4415
4416 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4417                            struct policy_handle *handle, uint32_t rid)
4418 {
4419         NTSTATUS status;
4420         struct samr_OpenAlias r;
4421         struct policy_handle alias_handle;
4422         bool ret = true;
4423
4424         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4425
4426         r.in.domain_handle = handle;
4427         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4428         r.in.rid = rid;
4429         r.out.alias_handle = &alias_handle;
4430
4431         status = dcerpc_samr_OpenAlias(p, tctx, &r);
4432         if (!NT_STATUS_IS_OK(status)) {
4433                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4434                 return false;
4435         }
4436
4437         if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4438                 ret = false;
4439         }
4440
4441         if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4442                 ret = false;
4443         }
4444
4445         if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4446                 ret = false;
4447         }
4448
4449         if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4450                 ret = false;
4451         }
4452
4453         return ret;
4454 }
4455
4456 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4457                        struct policy_handle *handle, uint32_t rid, 
4458                        uint32_t acct_flag_mask)
4459 {
4460         NTSTATUS status;
4461         struct samr_OpenUser r;
4462         struct samr_QueryUserInfo q;
4463         union samr_UserInfo *info;
4464         struct policy_handle user_handle;
4465         bool ret = true;
4466
4467         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4468
4469         r.in.domain_handle = handle;
4470         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4471         r.in.rid = rid;
4472         r.out.user_handle = &user_handle;
4473
4474         status = dcerpc_samr_OpenUser(p, tctx, &r);
4475         if (!NT_STATUS_IS_OK(status)) {
4476                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4477                 return false;
4478         }
4479
4480         q.in.user_handle = &user_handle;
4481         q.in.level = 16;
4482         q.out.info = &info;
4483         
4484         status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4485         if (!NT_STATUS_IS_OK(status)) {
4486                 printf("QueryUserInfo level 16 failed - %s\n", 
4487                        nt_errstr(status));
4488                 ret = false;
4489         } else {
4490                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4491                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4492                                acct_flag_mask, info->info16.acct_flags, rid);
4493                         ret = false;
4494                 }
4495         }
4496         
4497         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4498                 ret = false;
4499         }
4500
4501         return ret;
4502 }
4503
4504 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx,
4505                                  struct policy_handle *handle)
4506 {
4507         NTSTATUS status = STATUS_MORE_ENTRIES;
4508         struct samr_EnumDomainUsers r;
4509         uint32_t mask, resume_handle=0;
4510         int i, mask_idx;
4511         bool ret = true;
4512         struct samr_LookupNames n;
4513         struct samr_LookupRids  lr ;
4514         struct lsa_Strings names;
4515         struct samr_Ids rids, types;
4516         struct samr_SamArray *sam = NULL;
4517         uint32_t num_entries = 0;
4518
4519         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
4520                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
4521                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
4522                             ACB_PWNOEXP, 0};
4523
4524         printf("Testing EnumDomainUsers\n");
4525
4526         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4527                 r.in.domain_handle = handle;
4528                 r.in.resume_handle = &resume_handle;
4529                 r.in.acct_flags = mask = masks[mask_idx];
4530                 r.in.max_size = (uint32_t)-1;
4531                 r.out.resume_handle = &resume_handle;
4532                 r.out.num_entries = &num_entries;
4533                 r.out.sam = &sam;
4534
4535                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4536                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
4537                     !NT_STATUS_IS_OK(status)) {
4538                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4539                         return false;
4540                 }
4541         
4542                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4543
4544                 if (sam->count == 0) {
4545                         continue;
4546                 }
4547
4548                 for (i=0;i<sam->count;i++) {
4549                         if (mask) {
4550                                 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4551                                         ret = false;
4552                                 }
4553                         } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4554                                 ret = false;
4555                         }
4556                 }
4557         }
4558
4559         printf("Testing LookupNames\n");
4560         n.in.domain_handle = handle;
4561         n.in.num_names = sam->count;
4562         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4563         n.out.rids = &rids;
4564         n.out.types = &types;
4565         for (i=0;i<sam->count;i++) {
4566                 n.in.names[i].string = sam->entries[i].name.string;
4567         }
4568         status = dcerpc_samr_LookupNames(p, tctx, &n);
4569         if (!NT_STATUS_IS_OK(status)) {
4570                 printf("LookupNames failed - %s\n", nt_errstr(status));
4571                 ret = false;
4572         }
4573
4574
4575         printf("Testing LookupRids\n");
4576         lr.in.domain_handle = handle;
4577         lr.in.num_rids = sam->count;
4578         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4579         lr.out.names = &names;
4580         lr.out.types = &types;
4581         for (i=0;i<sam->count;i++) {
4582                 lr.in.rids[i] = sam->entries[i].idx;
4583         }
4584         status = dcerpc_samr_LookupRids(p, tctx, &lr);
4585         torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4586
4587         return ret;     
4588 }
4589
4590 /*
4591   try blasting the server with a bunch of sync requests
4592 */
4593 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx, 
4594                                        struct policy_handle *handle)
4595 {
4596         NTSTATUS status;
4597         struct samr_EnumDomainUsers r;
4598         uint32_t resume_handle=0;
4599         int i;
4600 #define ASYNC_COUNT 100
4601         struct rpc_request *req[ASYNC_COUNT];
4602
4603         if (!torture_setting_bool(tctx, "dangerous", false)) {
4604                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4605         }
4606
4607         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4608
4609         r.in.domain_handle = handle;
4610         r.in.resume_handle = &resume_handle;
4611         r.in.acct_flags = 0;
4612         r.in.max_size = (uint32_t)-1;
4613         r.out.resume_handle = &resume_handle;
4614
4615         for (i=0;i<ASYNC_COUNT;i++) {
4616                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
4617         }
4618
4619         for (i=0;i<ASYNC_COUNT;i++) {
4620                 status = dcerpc_ndr_request_recv(req[i]);
4621                 if (!NT_STATUS_IS_OK(status)) {
4622                         printf("EnumDomainUsers[%d] failed - %s\n", 
4623                                i, nt_errstr(status));
4624                         return false;
4625                 }
4626         }
4627         
4628         torture_comment(tctx, "%d async requests OK\n", i);
4629
4630         return true;
4631 }
4632
4633 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4634                                   struct policy_handle *handle)
4635 {
4636         NTSTATUS status;
4637         struct samr_EnumDomainGroups r;
4638         uint32_t resume_handle=0;
4639         struct samr_SamArray *sam = NULL;
4640         uint32_t num_entries = 0;
4641         int i;
4642         bool ret = true;
4643
4644         printf("Testing EnumDomainGroups\n");
4645
4646         r.in.domain_handle = handle;
4647         r.in.resume_handle = &resume_handle;
4648         r.in.max_size = (uint32_t)-1;
4649         r.out.resume_handle = &resume_handle;
4650         r.out.num_entries = &num_entries;
4651         r.out.sam = &sam;
4652
4653         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
4654         if (!NT_STATUS_IS_OK(status)) {
4655                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
4656                 return false;
4657         }
4658         
4659         if (!sam) {
4660                 return false;
4661         }
4662
4663         for (i=0;i<sam->count;i++) {
4664                 if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
4665                         ret = false;
4666                 }
4667         }
4668
4669         return ret;
4670 }
4671
4672 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4673                                    struct policy_handle *handle)
4674 {
4675         NTSTATUS status;
4676         struct samr_EnumDomainAliases r;
4677         uint32_t resume_handle=0;
4678         struct samr_SamArray *sam = NULL;
4679         uint32_t num_entries = 0;
4680         int i;
4681         bool ret = true;
4682
4683         printf("Testing EnumDomainAliases\n");
4684
4685         r.in.domain_handle = handle;
4686         r.in.resume_handle = &resume_handle;
4687         r.in.max_size = (uint32_t)-1;
4688         r.out.sam = &sam;
4689         r.out.num_entries = &num_entries;
4690         r.out.resume_handle = &resume_handle;
4691
4692         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
4693         if (!NT_STATUS_IS_OK(status)) {
4694                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
4695                 return false;
4696         }
4697         
4698         if (!sam) {
4699                 return false;
4700         }
4701
4702         for (i=0;i<sam->count;i++) {
4703                 if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
4704                         ret = false;
4705                 }
4706         }
4707
4708         return ret;     
4709 }
4710
4711 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4712                                             struct policy_handle *handle)
4713 {
4714         NTSTATUS status;
4715         struct samr_GetDisplayEnumerationIndex r;
4716         bool ret = true;
4717         uint16_t levels[] = {1, 2, 3, 4, 5};
4718         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4719         struct lsa_String name;
4720         uint32_t idx = 0;
4721         int i;
4722
4723         for (i=0;i<ARRAY_SIZE(levels);i++) {
4724                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
4725
4726                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4727
4728                 r.in.domain_handle = handle;
4729                 r.in.level = levels[i];
4730                 r.in.name = &name;
4731                 r.out.idx = &idx;
4732
4733                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4734
4735                 if (ok_lvl[i] && 
4736                     !NT_STATUS_IS_OK(status) &&
4737                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4738                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
4739                                levels[i], nt_errstr(status));
4740                         ret = false;
4741                 }
4742
4743                 init_lsa_String(&name, "zzzzzzzz");
4744
4745                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
4746                 
4747                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4748                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
4749                                levels[i], nt_errstr(status));
4750                         ret = false;
4751                 }
4752         }
4753         
4754         return ret;     
4755 }
4756
4757 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4758                                              struct policy_handle *handle)
4759 {
4760         NTSTATUS status;
4761         struct samr_GetDisplayEnumerationIndex2 r;
4762         bool ret = true;
4763         uint16_t levels[] = {1, 2, 3, 4, 5};
4764         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
4765         struct lsa_String name;
4766         uint32_t idx = 0;
4767         int i;
4768
4769         for (i=0;i<ARRAY_SIZE(levels);i++) {
4770                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
4771
4772                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
4773
4774                 r.in.domain_handle = handle;
4775                 r.in.level = levels[i];
4776                 r.in.name = &name;
4777                 r.out.idx = &idx;
4778
4779                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4780                 if (ok_lvl[i] && 
4781                     !NT_STATUS_IS_OK(status) && 
4782                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4783                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
4784                                levels[i], nt_errstr(status));
4785                         ret = false;
4786                 }
4787
4788                 init_lsa_String(&name, "zzzzzzzz");
4789
4790                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
4791                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
4792                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
4793                                levels[i], nt_errstr(status));
4794                         ret = false;
4795                 }
4796         }
4797         
4798         return ret;     
4799 }
4800
4801 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
4802         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
4803                 /* odd, but valid */                                            \
4804         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
4805                         printf("%s mismatch for %s: %s != %s (%s)\n", \
4806                                #s1, user.string,  s1.string, s2.string, __location__);   \
4807                         ret = false; \
4808         }
4809 #define INT_EQUAL_QUERY(s1, s2, user)           \
4810                 if (s1 != s2) { \
4811                         printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
4812                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
4813                         ret = false; \
4814                 }
4815
4816 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4817                                        struct samr_QueryDisplayInfo *querydisplayinfo,
4818                                        bool *seen_testuser) 
4819 {
4820         struct samr_OpenUser r;
4821         struct samr_QueryUserInfo q;
4822         union samr_UserInfo *info;
4823         struct policy_handle user_handle;
4824         int i, ret = true;
4825         NTSTATUS status;
4826         r.in.domain_handle = querydisplayinfo->in.domain_handle;
4827         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4828         for (i = 0; ; i++) {
4829                 switch (querydisplayinfo->in.level) {
4830                 case 1:
4831                         if (i >= querydisplayinfo->out.info->info1.count) {
4832                                 return ret;
4833                         }
4834                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
4835                         break;
4836                 case 2:
4837                         if (i >= querydisplayinfo->out.info->info2.count) {
4838                                 return ret;
4839                         }
4840                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
4841                         break;
4842                 case 3:
4843                         /* Groups */
4844                 case 4:
4845                 case 5:
4846                         /* Not interested in validating just the account name */
4847                         return true;
4848                 }
4849                         
4850                 r.out.user_handle = &user_handle;
4851                 
4852                 switch (querydisplayinfo->in.level) {
4853                 case 1:
4854                 case 2:
4855                         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
4856                         if (!NT_STATUS_IS_OK(status)) {
4857                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4858                                 return false;
4859                         }
4860                 }
4861                 
4862                 q.in.user_handle = &user_handle;
4863                 q.in.level = 21;
4864                 q.out.info = &info;
4865                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
4866                 if (!NT_STATUS_IS_OK(status)) {
4867                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
4868                         return false;
4869                 }
4870                 
4871                 switch (querydisplayinfo->in.level) {
4872                 case 1:
4873                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
4874                                 *seen_testuser = true;
4875                         }
4876                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
4877                                            info->info21.full_name, info->info21.account_name);
4878                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
4879                                            info->info21.account_name, info->info21.account_name);
4880                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
4881                                            info->info21.description, info->info21.account_name);
4882                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
4883                                         info->info21.rid, info->info21.account_name);
4884                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
4885                                         info->info21.acct_flags, info->info21.account_name);
4886                         
4887                         break;
4888                 case 2:
4889                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
4890                                            info->info21.account_name, info->info21.account_name);
4891                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
4892                                            info->info21.description, info->info21.account_name);
4893                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
4894                                         info->info21.rid, info->info21.account_name);
4895                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
4896                                         info->info21.acct_flags, info->info21.account_name);
4897                         
4898                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
4899                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", 
4900                                        info->info21.account_name.string);
4901                         }
4902
4903                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
4904                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
4905                                        info->info21.account_name.string,
4906                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
4907                                        info->info21.acct_flags);
4908                                 return false;
4909                         }
4910                         
4911                         break;
4912                 }
4913                 
4914                 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
4915                         return false;
4916                 }
4917         }
4918         return ret;
4919 }
4920
4921 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4922                                   struct policy_handle *handle)
4923 {
4924         NTSTATUS status;
4925         struct samr_QueryDisplayInfo r;
4926         struct samr_QueryDomainInfo dom_info;
4927         union samr_DomainInfo *info = NULL;
4928         bool ret = true;
4929         uint16_t levels[] = {1, 2, 3, 4, 5};
4930         int i;
4931         bool seen_testuser = false;
4932         uint32_t total_size;
4933         uint32_t returned_size;
4934         union samr_DispInfo disp_info;
4935
4936
4937         for (i=0;i<ARRAY_SIZE(levels);i++) {
4938                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
4939
4940                 r.in.start_idx = 0;
4941                 status = STATUS_MORE_ENTRIES;
4942                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
4943                         r.in.domain_handle = handle;
4944                         r.in.level = levels[i];
4945                         r.in.max_entries = 2;
4946                         r.in.buf_size = (uint32_t)-1;
4947                         r.out.total_size = &total_size;
4948                         r.out.returned_size = &returned_size;
4949                         r.out.info = &disp_info;
4950                         
4951                         status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
4952                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
4953                                 printf("QueryDisplayInfo level %u failed - %s\n", 
4954                                        levels[i], nt_errstr(status));
4955                                 ret = false;
4956                         }
4957                         switch (r.in.level) {
4958                         case 1:
4959                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
4960                                         ret = false;
4961                                 }
4962                                 r.in.start_idx += r.out.info->info1.count;
4963                                 break;
4964                         case 2:
4965                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
4966                                         ret = false;
4967                                 }
4968                                 r.in.start_idx += r.out.info->info2.count;
4969                                 break;
4970                         case 3:
4971                                 r.in.start_idx += r.out.info->info3.count;
4972                                 break;
4973                         case 4:
4974                                 r.in.start_idx += r.out.info->info4.count;
4975                                 break;
4976                         case 5:
4977                                 r.in.start_idx += r.out.info->info5.count;
4978                                 break;
4979                         }
4980                 }
4981                 dom_info.in.domain_handle = handle;
4982                 dom_info.in.level = 2;
4983                 dom_info.out.info = &info;
4984
4985                 /* Check number of users returned is correct */
4986                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
4987                 if (!NT_STATUS_IS_OK(status)) {
4988                         printf("QueryDomainInfo level %u failed - %s\n", 
4989                                r.in.level, nt_errstr(status));
4990                                 ret = false;
4991                                 break;
4992                 }
4993                 switch (r.in.level) {
4994                 case 1:
4995                 case 4:
4996                         if (info->general.num_users < r.in.start_idx) {
4997                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
4998                                        r.in.start_idx, info->general.num_groups,
4999                                        info->general.domain_name.string);
5000                                 ret = false;
5001                         }
5002                         if (!seen_testuser) {
5003                                 struct policy_handle user_handle;
5004                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5005                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", 
5006                                                info->general.domain_name.string);
5007                                         ret = false;
5008                                         test_samr_handle_Close(p, mem_ctx, &user_handle);
5009                                 }
5010                         }
5011                         break;
5012                 case 3:
5013                 case 5:
5014                         if (info->general.num_groups != r.in.start_idx) {
5015                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5016                                        r.in.start_idx, info->general.num_groups,
5017                                        info->general.domain_name.string);
5018                                 ret = false;
5019                         }
5020                         
5021                         break;
5022                 }
5023
5024         }
5025         
5026         return ret;     
5027 }
5028
5029 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
5030                                   struct policy_handle *handle)
5031 {
5032         NTSTATUS status;
5033         struct samr_QueryDisplayInfo2 r;
5034         bool ret = true;
5035         uint16_t levels[] = {1, 2, 3, 4, 5};
5036         int i;
5037         uint32_t total_size;
5038         uint32_t returned_size;
5039         union samr_DispInfo info;
5040
5041         for (i=0;i<ARRAY_SIZE(levels);i++) {
5042                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5043
5044                 r.in.domain_handle = handle;
5045                 r.in.level = levels[i];
5046                 r.in.start_idx = 0;
5047                 r.in.max_entries = 1000;
5048                 r.in.buf_size = (uint32_t)-1;
5049                 r.out.total_size = &total_size;
5050                 r.out.returned_size = &returned_size;
5051                 r.out.info = &info;
5052
5053                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
5054                 if (!NT_STATUS_IS_OK(status)) {
5055                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
5056                                levels[i], nt_errstr(status));
5057                         ret = false;
5058                 }
5059         }
5060         
5061         return ret;     
5062 }
5063
5064 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5065                                   struct policy_handle *handle)
5066 {
5067         NTSTATUS status;
5068         struct samr_QueryDisplayInfo3 r;
5069         bool ret = true;
5070         uint16_t levels[] = {1, 2, 3, 4, 5};
5071         int i;
5072         uint32_t total_size;
5073         uint32_t returned_size;
5074         union samr_DispInfo info;
5075
5076         for (i=0;i<ARRAY_SIZE(levels);i++) {
5077                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5078
5079                 r.in.domain_handle = handle;
5080                 r.in.level = levels[i];
5081                 r.in.start_idx = 0;
5082                 r.in.max_entries = 1000;
5083                 r.in.buf_size = (uint32_t)-1;
5084                 r.out.total_size = &total_size;
5085                 r.out.returned_size = &returned_size;
5086                 r.out.info = &info;
5087
5088                 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5089                 if (!NT_STATUS_IS_OK(status)) {
5090                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
5091                                levels[i], nt_errstr(status));
5092                         ret = false;
5093                 }
5094         }
5095         
5096         return ret;     
5097 }
5098
5099
5100 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
5101                                            struct policy_handle *handle)
5102 {
5103         NTSTATUS status;
5104         struct samr_QueryDisplayInfo r;
5105         bool ret = true;
5106         uint32_t total_size;
5107         uint32_t returned_size;
5108         union samr_DispInfo info;
5109
5110         printf("Testing QueryDisplayInfo continuation\n");
5111
5112         r.in.domain_handle = handle;
5113         r.in.level = 1;
5114         r.in.start_idx = 0;
5115         r.in.max_entries = 1;
5116         r.in.buf_size = (uint32_t)-1;
5117         r.out.total_size = &total_size;
5118         r.out.returned_size = &returned_size;
5119         r.out.info = &info;
5120
5121         do {
5122                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
5123                 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5124                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5125                                 printf("expected idx %d but got %d\n",
5126                                        r.in.start_idx + 1,
5127                                        r.out.info->info1.entries[0].idx);
5128                                 break;
5129                         }
5130                 }
5131                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5132                     !NT_STATUS_IS_OK(status)) {
5133                         printf("QueryDisplayInfo level %u failed - %s\n", 
5134                                r.in.level, nt_errstr(status));
5135                         ret = false;
5136                         break;
5137                 }
5138                 r.in.start_idx++;
5139         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5140                   NT_STATUS_IS_OK(status)) &&
5141                  *r.out.returned_size != 0);
5142         
5143         return ret;     
5144 }
5145
5146 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5147                                  struct policy_handle *handle)
5148 {
5149         NTSTATUS status;
5150         struct samr_QueryDomainInfo r;
5151         union samr_DomainInfo *info = NULL;
5152         struct samr_SetDomainInfo s;
5153         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5154         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
5155         int i;
5156         bool ret = true;
5157         const char *domain_comment = talloc_asprintf(tctx, 
5158                                   "Tortured by Samba4 RPC-SAMR: %s", 
5159                                   timestring(tctx, time(NULL)));
5160
5161         s.in.domain_handle = handle;
5162         s.in.level = 4;
5163         s.in.info = talloc(tctx, union samr_DomainInfo);
5164         
5165         s.in.info->oem.oem_information.string = domain_comment;
5166         status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5167         if (!NT_STATUS_IS_OK(status)) {
5168                 printf("SetDomainInfo level %u (set comment) failed - %s\n", 
5169                        s.in.level, nt_errstr(status));
5170                 return false;
5171         }
5172
5173         for (i=0;i<ARRAY_SIZE(levels);i++) {
5174                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5175
5176                 r.in.domain_handle = handle;
5177                 r.in.level = levels[i];
5178                 r.out.info = &info;
5179
5180                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5181                 if (!NT_STATUS_IS_OK(status)) {
5182                         printf("QueryDomainInfo level %u failed - %s\n", 
5183                                r.in.level, nt_errstr(status));
5184                         ret = false;
5185                         continue;
5186                 }
5187
5188                 switch (levels[i]) {
5189                 case 2:
5190                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5191                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5192                                        levels[i], info->general.oem_information.string, domain_comment);
5193                                 ret = false;
5194                         }
5195                         if (!info->general.primary.string) {
5196                                 printf("QueryDomainInfo level %u returned no PDC name\n",
5197                                        levels[i]);
5198                                 ret = false;
5199                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5200                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5201                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5202                                                levels[i], info->general.primary.string, dcerpc_server_name(p));
5203                                 }
5204                         }
5205                         break;
5206                 case 4:
5207                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5208                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5209                                        levels[i], info->oem.oem_information.string, domain_comment);
5210                                 ret = false;
5211                         }
5212                         break;
5213                 case 6:
5214                         if (!info->info6.primary.string) {
5215                                 printf("QueryDomainInfo level %u returned no PDC name\n",
5216                                        levels[i]);
5217                                 ret = false;
5218                         }
5219                         break;
5220                 case 11:
5221                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5222                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5223                                        levels[i], info->general2.general.oem_information.string, domain_comment);
5224                                 ret = false;
5225                         }
5226                         break;
5227                 }
5228
5229                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5230
5231                 s.in.domain_handle = handle;
5232                 s.in.level = levels[i];
5233                 s.in.info = info;
5234
5235                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5236                 if (set_ok[i]) {
5237                         if (!NT_STATUS_IS_OK(status)) {
5238                                 printf("SetDomainInfo level %u failed - %s\n", 
5239                                        r.in.level, nt_errstr(status));
5240                                 ret = false;
5241                                 continue;
5242                         }
5243                 } else {
5244                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5245                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
5246                                        r.in.level, nt_errstr(status));
5247                                 ret = false;
5248                                 continue;
5249                         }
5250                 }
5251
5252                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5253                 if (!NT_STATUS_IS_OK(status)) {
5254                         printf("QueryDomainInfo level %u failed - %s\n", 
5255                                r.in.level, nt_errstr(status));
5256                         ret = false;
5257                         continue;
5258                 }
5259         }
5260
5261         return ret;     
5262 }
5263
5264
5265 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5266                                   struct policy_handle *handle)
5267 {
5268         NTSTATUS status;
5269         struct samr_QueryDomainInfo2 r;
5270         union samr_DomainInfo *info = NULL;
5271         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5272         int i;
5273         bool ret = true;
5274
5275         for (i=0;i<ARRAY_SIZE(levels);i++) {
5276                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5277
5278                 r.in.domain_handle = handle;
5279                 r.in.level = levels[i];
5280                 r.out.info = &info;
5281
5282                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5283                 if (!NT_STATUS_IS_OK(status)) {
5284                         printf("QueryDomainInfo2 level %u failed - %s\n", 
5285                                r.in.level, nt_errstr(status));
5286                         ret = false;
5287                         continue;
5288                 }
5289         }
5290
5291         return true;    
5292 }
5293
5294 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5295    set of group names. */
5296 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5297                            struct policy_handle *handle)
5298 {
5299         struct samr_EnumDomainGroups q1;
5300         struct samr_QueryDisplayInfo q2;
5301         NTSTATUS status;
5302         uint32_t resume_handle=0;
5303         struct samr_SamArray *sam = NULL;
5304         uint32_t num_entries = 0;
5305         int i;
5306         bool ret = true;
5307         uint32_t total_size;
5308         uint32_t returned_size;
5309         union samr_DispInfo info;
5310
5311         int num_names = 0;
5312         const char **names = NULL;
5313
5314         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5315
5316         q1.in.domain_handle = handle;
5317         q1.in.resume_handle = &resume_handle;
5318         q1.in.max_size = 5;
5319         q1.out.resume_handle = &resume_handle;
5320         q1.out.num_entries = &num_entries;
5321         q1.out.sam = &sam;
5322
5323         status = STATUS_MORE_ENTRIES;
5324         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5325                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5326
5327                 if (!NT_STATUS_IS_OK(status) &&
5328                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5329                         break;
5330
5331                 for (i=0; i<*q1.out.num_entries; i++) {
5332                         add_string_to_array(tctx,
5333                                             sam->entries[i].name.string,
5334                                             &names, &num_names);
5335                 }
5336         }
5337
5338         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5339         
5340         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5341
5342         q2.in.domain_handle = handle;
5343         q2.in.level = 5;
5344         q2.in.start_idx = 0;
5345         q2.in.max_entries = 5;
5346         q2.in.buf_size = (uint32_t)-1;
5347         q2.out.total_size = &total_size;
5348         q2.out.returned_size = &returned_size;
5349         q2.out.info = &info;
5350
5351         status = STATUS_MORE_ENTRIES;
5352         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5353                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5354
5355                 if (!NT_STATUS_IS_OK(status) &&
5356                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5357                         break;
5358
5359                 for (i=0; i<q2.out.info->info5.count; i++) {
5360                         int j;
5361                         const char *name = q2.out.info->info5.entries[i].account_name.string;
5362                         bool found = false;
5363                         for (j=0; j<num_names; j++) {
5364                                 if (names[j] == NULL)
5365                                         continue;
5366                                 if (strequal(names[j], name)) {
5367                                         names[j] = NULL;
5368                                         found = true;
5369                                         break;
5370                                 }
5371                         }
5372
5373                         if (!found) {
5374                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5375                                        name);
5376                                 ret = false;
5377                         }
5378                 }
5379                 q2.in.start_idx += q2.out.info->info5.count;
5380         }
5381
5382         if (!NT_STATUS_IS_OK(status)) {
5383                 printf("QueryDisplayInfo level 5 failed - %s\n",
5384                        nt_errstr(status));
5385                 ret = false;
5386         }
5387
5388         for (i=0; i<num_names; i++) {
5389                 if (names[i] != NULL) {
5390                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5391                                names[i]);
5392                         ret = false;
5393                 }
5394         }
5395
5396         return ret;
5397 }
5398
5399 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5400                                    struct policy_handle *group_handle)
5401 {
5402         struct samr_DeleteDomainGroup d;
5403         NTSTATUS status;
5404
5405         torture_comment(tctx, "Testing DeleteDomainGroup\n");
5406
5407         d.in.group_handle = group_handle;
5408         d.out.group_handle = group_handle;
5409
5410         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5411         torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5412
5413         return true;
5414 }
5415
5416 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5417                                             struct policy_handle *domain_handle)
5418 {
5419         struct samr_TestPrivateFunctionsDomain r;
5420         NTSTATUS status;
5421         bool ret = true;
5422
5423         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5424
5425         r.in.domain_handle = domain_handle;
5426
5427         status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5428         torture_assert_ntstatus_equal(tctx, NT_STATUS_NOT_IMPLEMENTED, status, "TestPrivateFunctionsDomain");
5429
5430         return ret;
5431 }
5432
5433 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5434                           struct dom_sid *domain_sid,
5435                           struct policy_handle *domain_handle)
5436 {
5437         struct samr_RidToSid r;
5438         NTSTATUS status;
5439         bool ret = true;
5440         struct dom_sid *calc_sid, *out_sid;
5441         int rids[] = { 0, 42, 512, 10200 };
5442         int i;
5443
5444         for (i=0;i<ARRAY_SIZE(rids);i++) {
5445                 torture_comment(tctx, "Testing RidToSid\n");
5446                 
5447                 calc_sid = dom_sid_dup(tctx, domain_sid);
5448                 r.in.domain_handle = domain_handle;
5449                 r.in.rid = rids[i];
5450                 r.out.sid = &out_sid;
5451                 
5452                 status = dcerpc_samr_RidToSid(p, tctx, &r);
5453                 if (!NT_STATUS_IS_OK(status)) {
5454                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5455                         ret = false;
5456                 } else {
5457                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5458
5459                         if (!dom_sid_equal(calc_sid, out_sid)) {
5460                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
5461                                        dom_sid_string(tctx, out_sid),
5462                                        dom_sid_string(tctx, calc_sid));
5463                                 ret = false;
5464                         }
5465                 }
5466         }
5467
5468         return ret;
5469 }
5470
5471 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5472                                        struct policy_handle *domain_handle)
5473 {
5474         struct samr_GetBootKeyInformation r;
5475         NTSTATUS status;
5476         bool ret = true;
5477         uint32_t unknown = 0;
5478
5479         torture_comment(tctx, "Testing GetBootKeyInformation\n");
5480
5481         r.in.domain_handle = domain_handle;
5482         r.out.unknown = &unknown;
5483
5484         status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5485         if (!NT_STATUS_IS_OK(status)) {
5486                 /* w2k3 seems to fail this sometimes and pass it sometimes */
5487                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5488         }
5489
5490         return ret;
5491 }
5492
5493 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx, 
5494                                 struct policy_handle *domain_handle,
5495                                 struct policy_handle *group_handle)
5496 {
5497         NTSTATUS status;
5498         struct samr_AddGroupMember r;
5499         struct samr_DeleteGroupMember d;
5500         struct samr_QueryGroupMember q;
5501         struct samr_RidTypeArray *rids = NULL;
5502         struct samr_SetMemberAttributesOfGroup s;
5503         uint32_t rid;
5504
5505         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5506         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5507
5508         r.in.group_handle = group_handle;
5509         r.in.rid = rid;
5510         r.in.flags = 0; /* ??? */
5511
5512         torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5513
5514         d.in.group_handle = group_handle;
5515         d.in.rid = rid;
5516
5517         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5518         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5519
5520         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5521         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5522
5523         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5524         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5525
5526         if (torture_setting_bool(tctx, "samba4", false)) {
5527                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5528         } else {
5529                 /* this one is quite strange. I am using random inputs in the
5530                    hope of triggering an error that might give us a clue */
5531
5532                 s.in.group_handle = group_handle;
5533                 s.in.unknown1 = random();
5534                 s.in.unknown2 = random();
5535
5536                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5537                 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5538         }
5539
5540         q.in.group_handle = group_handle;
5541         q.out.rids = &rids;
5542
5543         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5544         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5545
5546         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5547         torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5548
5549         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5550         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5551
5552         return true;
5553 }
5554
5555
5556 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, 
5557                                                                    struct torture_context *tctx, 
5558                                    struct policy_handle *domain_handle, 
5559                                    struct policy_handle *group_handle,
5560                                    struct dom_sid *domain_sid)
5561 {
5562         NTSTATUS status;
5563         struct samr_CreateDomainGroup r;
5564         uint32_t rid;
5565         struct lsa_String name;
5566         bool ret = true;
5567
5568         init_lsa_String(&name, TEST_GROUPNAME);
5569
5570         r.in.domain_handle = domain_handle;
5571         r.in.name = &name;
5572         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5573         r.out.group_handle = group_handle;
5574         r.out.rid = &rid;
5575
5576         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5577
5578         status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5579
5580         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5581                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5582                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5583                         return true;
5584                 } else {
5585                         printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string, 
5586                                nt_errstr(status));
5587                         return false;
5588                 }
5589         }
5590
5591         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5592                 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5593                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string, 
5594                                nt_errstr(status));
5595                         return false;
5596                 }
5597                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5598         }
5599         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5600                 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5601                         
5602                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string, 
5603                                nt_errstr(status));
5604                         return false;
5605                 }
5606                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5607         }
5608         torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
5609
5610         if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
5611                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
5612                 ret = false;
5613         }
5614
5615         if (!test_SetGroupInfo(p, tctx, group_handle)) {
5616                 ret = false;
5617         }
5618
5619         return ret;
5620 }
5621
5622
5623 /*
5624   its not totally clear what this does. It seems to accept any sid you like.
5625 */
5626 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
5627                                                struct torture_context *tctx,
5628                                                struct policy_handle *domain_handle)
5629 {
5630         NTSTATUS status;
5631         struct samr_RemoveMemberFromForeignDomain r;
5632
5633         r.in.domain_handle = domain_handle;
5634         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
5635
5636         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
5637         torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
5638
5639         return true;
5640 }
5641
5642
5643
5644 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5645                          struct policy_handle *handle);
5646
5647 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, 
5648                             struct policy_handle *handle, struct dom_sid *sid,
5649                             enum torture_samr_choice which_ops,
5650                             struct cli_credentials *machine_credentials)
5651 {
5652         NTSTATUS status;
5653         struct samr_OpenDomain r;
5654         struct policy_handle domain_handle;
5655         struct policy_handle alias_handle;
5656         struct policy_handle user_handle;
5657         struct policy_handle group_handle;
5658         bool ret = true;
5659
5660         ZERO_STRUCT(alias_handle);
5661         ZERO_STRUCT(user_handle);
5662         ZERO_STRUCT(group_handle);
5663         ZERO_STRUCT(domain_handle);
5664
5665         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
5666
5667         r.in.connect_handle = handle;
5668         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5669         r.in.sid = sid;
5670         r.out.domain_handle = &domain_handle;
5671
5672         status = dcerpc_samr_OpenDomain(p, tctx, &r);
5673         torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
5674
5675         /* run the domain tests with the main handle closed - this tests
5676            the servers reference counting */
5677         ret &= test_samr_handle_Close(p, tctx, handle);
5678
5679         switch (which_ops) {
5680         case TORTURE_SAMR_USER_ATTRIBUTES:
5681         case TORTURE_SAMR_PASSWORDS:
5682                 if (!torture_setting_bool(tctx, "samba3", false)) {
5683                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
5684                 }
5685                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5686                 /* This test needs 'complex' users to validate */
5687                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
5688                 if (!ret) {
5689                         printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
5690                 }
5691                 break;
5692         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5693                 if (!torture_setting_bool(tctx, "samba3", false)) {
5694                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
5695                 }
5696                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
5697                 if (!ret) {
5698                         printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
5699                 }
5700                 break;
5701         case TORTURE_SAMR_OTHER:
5702                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL);
5703                 if (!ret) {
5704                         printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
5705                 }
5706                 ret &= test_QuerySecurity(p, tctx, &domain_handle);
5707                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
5708                 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
5709                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
5710                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
5711                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
5712                 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
5713                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
5714                 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
5715                 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
5716                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
5717                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
5718                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
5719                 
5720                 if (torture_setting_bool(tctx, "samba4", false)) {
5721                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
5722                 } else {
5723                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
5724                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
5725                 }
5726                 ret &= test_GroupList(p, tctx, &domain_handle);
5727                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
5728                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
5729                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
5730                 if (!ret) {
5731                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
5732                 }
5733                 break;
5734         }
5735
5736         if (!policy_handle_empty(&user_handle) &&
5737             !test_DeleteUser(p, tctx, &user_handle)) {
5738                 ret = false;
5739         }
5740
5741         if (!policy_handle_empty(&alias_handle) &&
5742             !test_DeleteAlias(p, tctx, &alias_handle)) {
5743                 ret = false;
5744         }
5745
5746         if (!policy_handle_empty(&group_handle) &&
5747             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
5748                 ret = false;
5749         }
5750
5751         ret &= test_samr_handle_Close(p, tctx, &domain_handle);
5752
5753         /* reconnect the main handle */
5754         ret &= test_Connect(p, tctx, handle);
5755
5756         if (!ret) {
5757                 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
5758         }
5759
5760         return ret;
5761 }
5762
5763 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5764                               struct policy_handle *handle, const char *domain,
5765                               enum torture_samr_choice which_ops,
5766                               struct cli_credentials *machine_credentials)
5767 {
5768         NTSTATUS status;
5769         struct samr_LookupDomain r;
5770         struct dom_sid2 *sid = NULL;
5771         struct lsa_String n1;
5772         struct lsa_String n2;
5773         bool ret = true;
5774
5775         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
5776
5777         /* check for correct error codes */
5778         r.in.connect_handle = handle;
5779         r.in.domain_name = &n2;
5780         r.out.sid = &sid;
5781         n2.string = NULL;
5782
5783         status = dcerpc_samr_LookupDomain(p, tctx, &r);
5784         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
5785
5786         init_lsa_String(&n2, "xxNODOMAINxx");
5787
5788         status = dcerpc_samr_LookupDomain(p, tctx, &r);
5789         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
5790
5791         r.in.connect_handle = handle;
5792
5793         init_lsa_String(&n1, domain);
5794         r.in.domain_name = &n1;
5795
5796         status = dcerpc_samr_LookupDomain(p, tctx, &r);
5797         torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
5798
5799         if (!test_GetDomPwInfo(p, tctx, &n1)) {
5800                 ret = false;
5801         }
5802
5803         if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
5804                              machine_credentials)) {
5805                 ret = false;
5806         }
5807
5808         return ret;
5809 }
5810
5811
5812 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
5813                              struct policy_handle *handle, enum torture_samr_choice which_ops,
5814                              struct cli_credentials *machine_credentials)
5815 {
5816         NTSTATUS status;
5817         struct samr_EnumDomains r;
5818         uint32_t resume_handle = 0;
5819         uint32_t num_entries = 0;
5820         struct samr_SamArray *sam = NULL;
5821         int i;
5822         bool ret = true;
5823
5824         r.in.connect_handle = handle;
5825         r.in.resume_handle = &resume_handle;
5826         r.in.buf_size = (uint32_t)-1;
5827         r.out.resume_handle = &resume_handle;
5828         r.out.num_entries = &num_entries;
5829         r.out.sam = &sam;
5830
5831         status = dcerpc_samr_EnumDomains(p, tctx, &r);
5832         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5833
5834         if (!*r.out.sam) {
5835                 return false;
5836         }
5837
5838         for (i=0;i<sam->count;i++) {
5839                 if (!test_LookupDomain(p, tctx, handle, 
5840                                        sam->entries[i].name.string, which_ops,
5841                                        machine_credentials)) {
5842                         ret = false;
5843                 }
5844         }
5845
5846         status = dcerpc_samr_EnumDomains(p, tctx, &r);
5847         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
5848
5849         return ret;
5850 }
5851
5852
5853 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
5854                          struct policy_handle *handle)
5855 {
5856         NTSTATUS status;
5857         struct samr_Connect r;
5858         struct samr_Connect2 r2;
5859         struct samr_Connect3 r3;
5860         struct samr_Connect4 r4;
5861         struct samr_Connect5 r5;
5862         union samr_ConnectInfo info;
5863         struct policy_handle h;
5864         uint32_t level_out = 0;
5865         bool ret = true, got_handle = false;
5866
5867         torture_comment(tctx, "testing samr_Connect\n");
5868
5869         r.in.system_name = 0;
5870         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5871         r.out.connect_handle = &h;
5872
5873         status = dcerpc_samr_Connect(p, tctx, &r);
5874         if (!NT_STATUS_IS_OK(status)) {
5875                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
5876                 ret = false;
5877         } else {
5878                 got_handle = true;
5879                 *handle = h;
5880         }
5881
5882         torture_comment(tctx, "testing samr_Connect2\n");
5883
5884         r2.in.system_name = NULL;
5885         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5886         r2.out.connect_handle = &h;
5887
5888         status = dcerpc_samr_Connect2(p, tctx, &r2);
5889         if (!NT_STATUS_IS_OK(status)) {
5890                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
5891                 ret = false;
5892         } else {
5893                 if (got_handle) {
5894                         test_samr_handle_Close(p, tctx, handle);
5895                 }
5896                 got_handle = true;
5897                 *handle = h;
5898         }
5899
5900         torture_comment(tctx, "testing samr_Connect3\n");
5901
5902         r3.in.system_name = NULL;
5903         r3.in.unknown = 0;
5904         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5905         r3.out.connect_handle = &h;
5906
5907         status = dcerpc_samr_Connect3(p, tctx, &r3);
5908         if (!NT_STATUS_IS_OK(status)) {
5909                 printf("Connect3 failed - %s\n", nt_errstr(status));
5910                 ret = false;
5911         } else {
5912                 if (got_handle) {
5913                         test_samr_handle_Close(p, tctx, handle);
5914                 }
5915                 got_handle = true;
5916                 *handle = h;
5917         }
5918
5919         torture_comment(tctx, "testing samr_Connect4\n");
5920
5921         r4.in.system_name = "";
5922         r4.in.client_version = 0;
5923         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5924         r4.out.connect_handle = &h;
5925
5926         status = dcerpc_samr_Connect4(p, tctx, &r4);
5927         if (!NT_STATUS_IS_OK(status)) {
5928                 printf("Connect4 failed - %s\n", nt_errstr(status));
5929                 ret = false;
5930         } else {
5931                 if (got_handle) {
5932                         test_samr_handle_Close(p, tctx, handle);
5933                 }
5934                 got_handle = true;
5935                 *handle = h;
5936         }
5937
5938         torture_comment(tctx, "testing samr_Connect5\n");
5939
5940         info.info1.client_version = 0;
5941         info.info1.unknown2 = 0;
5942
5943         r5.in.system_name = "";
5944         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5945         r5.in.level_in = 1;
5946         r5.out.level_out = &level_out;
5947         r5.in.info_in = &info;
5948         r5.out.info_out = &info;
5949         r5.out.connect_handle = &h;
5950
5951         status = dcerpc_samr_Connect5(p, tctx, &r5);
5952         if (!NT_STATUS_IS_OK(status)) {
5953                 printf("Connect5 failed - %s\n", nt_errstr(status));
5954                 ret = false;
5955         } else {
5956                 if (got_handle) {
5957                         test_samr_handle_Close(p, tctx, handle);
5958                 }
5959                 got_handle = true;
5960                 *handle = h;
5961         }
5962
5963         return ret;
5964 }
5965
5966
5967 bool torture_rpc_samr(struct torture_context *torture)
5968 {
5969         NTSTATUS status;
5970         struct dcerpc_pipe *p;
5971         bool ret = true;
5972         struct policy_handle handle;
5973
5974         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
5975         if (!NT_STATUS_IS_OK(status)) {
5976                 return false;
5977         }
5978
5979         ret &= test_Connect(p, torture, &handle);
5980
5981         ret &= test_QuerySecurity(p, torture, &handle);
5982
5983         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
5984
5985         ret &= test_SetDsrmPassword(p, torture, &handle);
5986
5987         ret &= test_Shutdown(p, torture, &handle);
5988
5989         ret &= test_samr_handle_Close(p, torture, &handle);
5990
5991         return ret;
5992 }
5993
5994
5995 bool torture_rpc_samr_users(struct torture_context *torture)
5996 {
5997         NTSTATUS status;
5998         struct dcerpc_pipe *p;
5999         bool ret = true;
6000         struct policy_handle handle;
6001
6002         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6003         if (!NT_STATUS_IS_OK(status)) {
6004                 return false;
6005         }
6006
6007         ret &= test_Connect(p, torture, &handle);
6008
6009         ret &= test_QuerySecurity(p, torture, &handle);
6010
6011         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6012
6013         ret &= test_SetDsrmPassword(p, torture, &handle);
6014
6015         ret &= test_Shutdown(p, torture, &handle);
6016
6017         ret &= test_samr_handle_Close(p, torture, &handle);
6018
6019         return ret;
6020 }
6021
6022
6023 bool torture_rpc_samr_passwords(struct torture_context *torture)
6024 {
6025         NTSTATUS status;
6026         struct dcerpc_pipe *p;
6027         bool ret = true;
6028         struct policy_handle handle;
6029
6030         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6031         if (!NT_STATUS_IS_OK(status)) {
6032                 return false;
6033         }
6034
6035         ret &= test_Connect(p, torture, &handle);
6036
6037         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6038
6039         ret &= test_samr_handle_Close(p, torture, &handle);
6040
6041         return ret;
6042 }
6043
6044 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6045                                         struct dcerpc_pipe *p2,
6046                                         struct cli_credentials *machine_credentials)
6047 {
6048         NTSTATUS status;
6049         struct dcerpc_pipe *p;
6050         bool ret = true;
6051         struct policy_handle handle;
6052
6053         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6054         if (!NT_STATUS_IS_OK(status)) {
6055                 return false;
6056         }
6057
6058         ret &= test_Connect(p, torture, &handle);
6059
6060         ret &= test_EnumDomains(p, torture, &handle,
6061                                 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6062                                 machine_credentials);
6063
6064         ret &= test_samr_handle_Close(p, torture, &handle);
6065
6066         return ret;
6067 }
6068
6069 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6070 {
6071         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6072         struct torture_rpc_tcase *tcase;
6073
6074         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6075                                                           &ndr_table_samr,
6076                                                           TEST_ACCOUNT_NAME_PWD);
6077
6078         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6079                                          torture_rpc_samr_pwdlastset);
6080
6081         return suite;
6082 }