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