source: trunk/server/source4/torture/rpc/samr.c

Last change on this file was 920, checked in by Silvan Scherrer, 9 years ago

Samba Server: apply latest security patches to trunk

File size: 245.4 KB
Line 
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 Copyright (C) Guenther Deschner 2008-2010
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "includes.h"
24#include "torture/torture.h"
25#include <tevent.h>
26#include "system/time.h"
27#include "librpc/gen_ndr/lsa.h"
28#include "librpc/gen_ndr/ndr_netlogon.h"
29#include "librpc/gen_ndr/ndr_netlogon_c.h"
30#include "librpc/gen_ndr/ndr_samr_c.h"
31#include "librpc/gen_ndr/ndr_lsa_c.h"
32#include "../lib/crypto/crypto.h"
33#include "libcli/auth/libcli_auth.h"
34#include "libcli/security/security.h"
35#include "torture/rpc/torture_rpc.h"
36#include "param/param.h"
37#include "auth/gensec/gensec.h"
38#include "auth/gensec/gensec_proto.h"
39#include "../libcli/auth/schannel.h"
40
41#include <unistd.h>
42
43#define TEST_ACCOUNT_NAME "samrtorturetest"
44#define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
45#define TEST_ALIASNAME "samrtorturetestalias"
46#define TEST_GROUPNAME "samrtorturetestgroup"
47#define TEST_MACHINENAME "samrtestmach$"
48#define TEST_DOMAINNAME "samrtestdom$"
49
50enum torture_samr_choice {
51 TORTURE_SAMR_PASSWORDS,
52 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
53 TORTURE_SAMR_PASSWORDS_BADPWDCOUNT,
54 TORTURE_SAMR_PASSWORDS_LOCKOUT,
55 TORTURE_SAMR_USER_ATTRIBUTES,
56 TORTURE_SAMR_USER_PRIVILEGES,
57 TORTURE_SAMR_OTHER,
58 TORTURE_SAMR_MANY_ACCOUNTS,
59 TORTURE_SAMR_MANY_GROUPS,
60 TORTURE_SAMR_MANY_ALIASES
61};
62
63struct torture_samr_context {
64 struct policy_handle handle;
65 struct cli_credentials *machine_credentials;
66 enum torture_samr_choice choice;
67 uint32_t num_objects_large_dc;
68};
69
70static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
71 struct torture_context *tctx,
72 struct policy_handle *handle);
73
74static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
75 struct torture_context *tctx,
76 struct policy_handle *handle);
77
78static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
79 struct torture_context *tctx,
80 struct policy_handle *handle);
81
82static bool test_ChangePassword(struct dcerpc_pipe *p,
83 struct torture_context *tctx,
84 const char *acct_name,
85 struct policy_handle *domain_handle, char **password);
86
87static void init_lsa_String(struct lsa_String *string, const char *s)
88{
89 string->string = s;
90}
91
92static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
93{
94 string->string = s;
95}
96
97static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
98{
99 string->length = length;
100 string->size = length;
101 string->array = (uint16_t *)discard_const(s);
102}
103
104bool test_samr_handle_Close(struct dcerpc_binding_handle *b,
105 struct torture_context *tctx,
106 struct policy_handle *handle)
107{
108 struct samr_Close r;
109
110 r.in.handle = handle;
111 r.out.handle = handle;
112
113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Close_r(b, tctx, &r),
114 "Close failed");
115 torture_assert_ntstatus_ok(tctx, r.out.result, "Close failed");
116
117 return true;
118}
119
120static bool test_Shutdown(struct dcerpc_binding_handle *b,
121 struct torture_context *tctx,
122 struct policy_handle *handle)
123{
124 struct samr_Shutdown r;
125
126 if (!torture_setting_bool(tctx, "dangerous", false)) {
127 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
128 return true;
129 }
130
131 r.in.connect_handle = handle;
132
133 torture_comment(tctx, "Testing samr_Shutdown\n");
134
135 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Shutdown_r(b, tctx, &r),
136 "Shutdown failed");
137 torture_assert_ntstatus_ok(tctx, r.out.result, "Shutdown failed");
138
139 return true;
140}
141
142static bool test_SetDsrmPassword(struct dcerpc_binding_handle *b,
143 struct torture_context *tctx,
144 struct policy_handle *handle)
145{
146 struct samr_SetDsrmPassword r;
147 struct lsa_String string;
148 struct samr_Password hash;
149
150 if (!torture_setting_bool(tctx, "dangerous", false)) {
151 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
152 }
153
154 E_md4hash("TeSTDSRM123", hash.hash);
155
156 init_lsa_String(&string, "Administrator");
157
158 r.in.name = &string;
159 r.in.unknown = 0;
160 r.in.hash = &hash;
161
162 torture_comment(tctx, "Testing samr_SetDsrmPassword\n");
163
164 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDsrmPassword_r(b, tctx, &r),
165 "SetDsrmPassword failed");
166 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED, "SetDsrmPassword failed");
167
168 return true;
169}
170
171
172static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
173 struct torture_context *tctx,
174 struct policy_handle *handle)
175{
176 struct samr_QuerySecurity r;
177 struct samr_SetSecurity s;
178 struct sec_desc_buf *sdbuf = NULL;
179
180 r.in.handle = handle;
181 r.in.sec_info = 7;
182 r.out.sdbuf = &sdbuf;
183
184 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
185 "QuerySecurity failed");
186 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
187
188 torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
189
190 s.in.handle = handle;
191 s.in.sec_info = 7;
192 s.in.sdbuf = sdbuf;
193
194 if (torture_setting_bool(tctx, "samba4", false)) {
195 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
196 }
197
198 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetSecurity_r(b, tctx, &s),
199 "SetSecurity failed");
200 torture_assert_ntstatus_ok(tctx, r.out.result, "SetSecurity failed");
201
202 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QuerySecurity_r(b, tctx, &r),
203 "QuerySecurity failed");
204 torture_assert_ntstatus_ok(tctx, r.out.result, "QuerySecurity failed");
205
206 return true;
207}
208
209
210static bool test_SetUserInfo(struct dcerpc_binding_handle *b, struct torture_context *tctx,
211 struct policy_handle *handle, uint32_t base_acct_flags,
212 const char *base_account_name)
213{
214 struct samr_SetUserInfo s;
215 struct samr_SetUserInfo2 s2;
216 struct samr_QueryUserInfo q;
217 struct samr_QueryUserInfo q0;
218 union samr_UserInfo u;
219 union samr_UserInfo *info;
220 bool ret = true;
221 const char *test_account_name;
222
223 uint32_t user_extra_flags = 0;
224
225 if (!torture_setting_bool(tctx, "samba3", false)) {
226 if (base_acct_flags == ACB_NORMAL) {
227 /* When created, accounts are expired by default */
228 user_extra_flags = ACB_PW_EXPIRED;
229 }
230 }
231
232 s.in.user_handle = handle;
233 s.in.info = &u;
234
235 s2.in.user_handle = handle;
236 s2.in.info = &u;
237
238 q.in.user_handle = handle;
239 q.out.info = &info;
240 q0 = q;
241
242#define TESTCALL(call, r) \
243 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ ##call## _r(b, tctx, &r),\
244 #call " failed"); \
245 if (!NT_STATUS_IS_OK(r.out.result)) { \
246 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
247 r.in.level, nt_errstr(r.out.result), __location__); \
248 ret = false; \
249 break; \
250 }
251
252#define STRING_EQUAL(s1, s2, field) \
253 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
254 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
255 #field, s2, __location__); \
256 ret = false; \
257 break; \
258 }
259
260#define MEM_EQUAL(s1, s2, length, field) \
261 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
262 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
263 #field, (const char *)s2, __location__); \
264 ret = false; \
265 break; \
266 }
267
268#define INT_EQUAL(i1, i2, field) \
269 if (i1 != i2) { \
270 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
271 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
272 ret = false; \
273 break; \
274 }
275
276#define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
277 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
278 q.in.level = lvl1; \
279 TESTCALL(QueryUserInfo, q) \
280 s.in.level = lvl1; \
281 s2.in.level = lvl1; \
282 u = *info; \
283 if (lvl1 == 21) { \
284 ZERO_STRUCT(u.info21); \
285 u.info21.fields_present = fpval; \
286 } \
287 init_lsa_String(&u.info ## lvl1.field1, value); \
288 TESTCALL(SetUserInfo, s) \
289 TESTCALL(SetUserInfo2, s2) \
290 init_lsa_String(&u.info ## lvl1.field1, ""); \
291 TESTCALL(QueryUserInfo, q); \
292 u = *info; \
293 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
294 q.in.level = lvl2; \
295 TESTCALL(QueryUserInfo, q) \
296 u = *info; \
297 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
298 } while (0)
299
300#define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
301 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
302 q.in.level = lvl1; \
303 TESTCALL(QueryUserInfo, q) \
304 s.in.level = lvl1; \
305 s2.in.level = lvl1; \
306 u = *info; \
307 if (lvl1 == 21) { \
308 ZERO_STRUCT(u.info21); \
309 u.info21.fields_present = fpval; \
310 } \
311 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
312 TESTCALL(SetUserInfo, s) \
313 TESTCALL(SetUserInfo2, s2) \
314 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
315 TESTCALL(QueryUserInfo, q); \
316 u = *info; \
317 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
318 q.in.level = lvl2; \
319 TESTCALL(QueryUserInfo, q) \
320 u = *info; \
321 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
322 } while (0)
323
324#define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
325 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
326 q.in.level = lvl1; \
327 TESTCALL(QueryUserInfo, q) \
328 s.in.level = lvl1; \
329 s2.in.level = lvl1; \
330 u = *info; \
331 if (lvl1 == 21) { \
332 uint8_t *bits = u.info21.logon_hours.bits; \
333 ZERO_STRUCT(u.info21); \
334 if (fpval == SAMR_FIELD_LOGON_HOURS) { \
335 u.info21.logon_hours.units_per_week = 168; \
336 u.info21.logon_hours.bits = bits; \
337 } \
338 u.info21.fields_present = fpval; \
339 } \
340 u.info ## lvl1.field1 = value; \
341 TESTCALL(SetUserInfo, s) \
342 TESTCALL(SetUserInfo2, s2) \
343 u.info ## lvl1.field1 = 0; \
344 TESTCALL(QueryUserInfo, q); \
345 u = *info; \
346 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
347 q.in.level = lvl2; \
348 TESTCALL(QueryUserInfo, q) \
349 u = *info; \
350 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
351 } while (0)
352
353#define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
354 TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
355 } while (0)
356
357 q0.in.level = 12;
358 do { TESTCALL(QueryUserInfo, q0) } while (0);
359
360 TEST_USERINFO_STRING(2, comment, 1, comment, "xx2-1 comment", 0);
361 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
362 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
363 SAMR_FIELD_COMMENT);
364
365 test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
366 TEST_USERINFO_STRING(7, account_name, 1, account_name, base_account_name, 0);
367 test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
368 TEST_USERINFO_STRING(7, account_name, 3, account_name, base_account_name, 0);
369 test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
370 TEST_USERINFO_STRING(7, account_name, 5, account_name, base_account_name, 0);
371 test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
372 TEST_USERINFO_STRING(7, account_name, 6, account_name, base_account_name, 0);
373 test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
374 TEST_USERINFO_STRING(7, account_name, 7, account_name, base_account_name, 0);
375 test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
376 TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
377 test_account_name = base_account_name;
378 TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
379 SAMR_FIELD_ACCOUNT_NAME);
380
381 TEST_USERINFO_STRING(6, full_name, 1, full_name, "xx6-1 full_name", 0);
382 TEST_USERINFO_STRING(6, full_name, 3, full_name, "xx6-3 full_name", 0);
383 TEST_USERINFO_STRING(6, full_name, 5, full_name, "xx6-5 full_name", 0);
384 TEST_USERINFO_STRING(6, full_name, 6, full_name, "xx6-6 full_name", 0);
385 TEST_USERINFO_STRING(6, full_name, 8, full_name, "xx6-8 full_name", 0);
386 TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
387 TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
388 TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
389 SAMR_FIELD_FULL_NAME);
390
391 TEST_USERINFO_STRING(6, full_name, 1, full_name, "", 0);
392 TEST_USERINFO_STRING(6, full_name, 3, full_name, "", 0);
393 TEST_USERINFO_STRING(6, full_name, 5, full_name, "", 0);
394 TEST_USERINFO_STRING(6, full_name, 6, full_name, "", 0);
395 TEST_USERINFO_STRING(6, full_name, 8, full_name, "", 0);
396 TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
397 TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
398 TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
399 SAMR_FIELD_FULL_NAME);
400
401 TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
402 TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
403 TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
404 TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
405 SAMR_FIELD_LOGON_SCRIPT);
406
407 TEST_USERINFO_STRING(12, profile_path, 3, profile_path, "xx12-3 profile_path", 0);
408 TEST_USERINFO_STRING(12, profile_path, 5, profile_path, "xx12-5 profile_path", 0);
409 TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
410 TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
411 SAMR_FIELD_PROFILE_PATH);
412
413 TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
414 TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
415 TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
416 TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
417 SAMR_FIELD_HOME_DIRECTORY);
418 TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
419 SAMR_FIELD_HOME_DIRECTORY);
420
421 TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
422 TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
423 TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
424 TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
425 SAMR_FIELD_HOME_DRIVE);
426 TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
427 SAMR_FIELD_HOME_DRIVE);
428
429 TEST_USERINFO_STRING(13, description, 1, description, "xx13-1 description", 0);
430 TEST_USERINFO_STRING(13, description, 5, description, "xx13-5 description", 0);
431 TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
432 TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
433 SAMR_FIELD_DESCRIPTION);
434
435 TEST_USERINFO_STRING(14, workstations, 3, workstations, "14workstation3", 0);
436 TEST_USERINFO_STRING(14, workstations, 5, workstations, "14workstation4", 0);
437 TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
438 TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
439 SAMR_FIELD_WORKSTATIONS);
440 TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
441 SAMR_FIELD_WORKSTATIONS);
442 TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
443 SAMR_FIELD_WORKSTATIONS);
444 TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
445 SAMR_FIELD_WORKSTATIONS);
446
447 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
448 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
449 SAMR_FIELD_PARAMETERS);
450 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
451 SAMR_FIELD_PARAMETERS);
452 /* also empty user parameters are allowed */
453 TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
454 TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
455 SAMR_FIELD_PARAMETERS);
456 TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
457 SAMR_FIELD_PARAMETERS);
458
459 /* Samba 3 cannot store country_code and code_page atm. - gd */
460 if (!torture_setting_bool(tctx, "samba3", false)) {
461 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
462 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
463 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
464 SAMR_FIELD_COUNTRY_CODE);
465 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
466 SAMR_FIELD_COUNTRY_CODE);
467
468 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
469 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
470 SAMR_FIELD_CODE_PAGE);
471 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
472 SAMR_FIELD_CODE_PAGE);
473 }
474
475 if (!torture_setting_bool(tctx, "samba3", false)) {
476 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
477 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
478 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
479 SAMR_FIELD_ACCT_EXPIRY);
480 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
481 SAMR_FIELD_ACCT_EXPIRY);
482 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
483 SAMR_FIELD_ACCT_EXPIRY);
484 } else {
485 /* Samba 3 can only store seconds / time_t in passdb - gd */
486 NTTIME nt;
487 unix_to_nt_time(&nt, time(NULL) + __LINE__);
488 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
489 unix_to_nt_time(&nt, time(NULL) + __LINE__);
490 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
491 unix_to_nt_time(&nt, time(NULL) + __LINE__);
492 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
493 unix_to_nt_time(&nt, time(NULL) + __LINE__);
494 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
495 unix_to_nt_time(&nt, time(NULL) + __LINE__);
496 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
497 }
498
499 TEST_USERINFO_INT(4, logon_hours.bits[3], 3, logon_hours.bits[3], 1, 0);
500 TEST_USERINFO_INT(4, logon_hours.bits[3], 5, logon_hours.bits[3], 2, 0);
501 TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
502 TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
503 SAMR_FIELD_LOGON_HOURS);
504
505 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
506 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
507 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
508 0);
509 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
510 (base_acct_flags | ACB_DISABLED),
511 (base_acct_flags | ACB_DISABLED | user_extra_flags),
512 0);
513
514 /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
515 TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
516 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
517 (base_acct_flags | ACB_DISABLED | ACB_PWNOEXP),
518 0);
519 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
520 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
521 (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
522 0);
523
524
525 /* The 'autolock' flag doesn't stick - check this */
526 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
527 (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
528 (base_acct_flags | ACB_DISABLED | user_extra_flags),
529 0);
530#if 0
531 /* Removing the 'disabled' flag doesn't stick - check this */
532 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
533 (base_acct_flags),
534 (base_acct_flags | ACB_DISABLED | user_extra_flags),
535 0);
536#endif
537
538 /* Samba3 cannot store these atm */
539 if (!torture_setting_bool(tctx, "samba3", false)) {
540 /* The 'store plaintext' flag does stick */
541 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
542 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
543 (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
544 0);
545 /* The 'use DES' flag does stick */
546 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
547 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
548 (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
549 0);
550 /* The 'don't require kerberos pre-authentication flag does stick */
551 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
552 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
553 (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
554 0);
555 /* The 'no kerberos PAC required' flag sticks */
556 TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
557 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
558 (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
559 0);
560 }
561 TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
562 (base_acct_flags | ACB_DISABLED),
563 (base_acct_flags | ACB_DISABLED | user_extra_flags),
564 SAMR_FIELD_ACCT_FLAGS);
565
566#if 0
567 /* these fail with win2003 - it appears you can't set the primary gid?
568 the set succeeds, but the gid isn't changed. Very weird! */
569 TEST_USERINFO_INT(9, primary_gid, 1, primary_gid, 513);
570 TEST_USERINFO_INT(9, primary_gid, 3, primary_gid, 513);
571 TEST_USERINFO_INT(9, primary_gid, 5, primary_gid, 513);
572 TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
573#endif
574
575 return ret;
576}
577
578/*
579 generate a random password for password change tests
580*/
581static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
582{
583 size_t len = MAX(8, min_len);
584 char *s = generate_random_password(mem_ctx, len, len+6);
585 return s;
586}
587
588static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
589{
590 char *s = samr_rand_pass_silent(mem_ctx, min_len);
591 printf("Generated password '%s'\n", s);
592 return s;
593
594}
595
596/*
597 generate a random password for password change tests
598*/
599static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
600{
601 int i;
602 DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
603 generate_random_buffer(password.data, password.length);
604
605 for (i=0; i < len; i++) {
606 if (((uint16_t *)password.data)[i] == 0) {
607 ((uint16_t *)password.data)[i] = 1;
608 }
609 }
610
611 return password;
612}
613
614/*
615 generate a random password for password change tests (fixed length)
616*/
617static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
618{
619 char *s = generate_random_password(mem_ctx, len, len);
620 printf("Generated password '%s'\n", s);
621 return s;
622}
623
624static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
625 struct policy_handle *handle, char **password)
626{
627 NTSTATUS status;
628 struct samr_SetUserInfo s;
629 union samr_UserInfo u;
630 bool ret = true;
631 DATA_BLOB session_key;
632 char *newpass;
633 struct dcerpc_binding_handle *b = p->binding_handle;
634 struct samr_GetUserPwInfo pwp;
635 struct samr_PwInfo info;
636 int policy_min_pw_len = 0;
637 pwp.in.user_handle = handle;
638 pwp.out.info = &info;
639
640 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
641 "GetUserPwInfo failed");
642 if (NT_STATUS_IS_OK(pwp.out.result)) {
643 policy_min_pw_len = pwp.out.info->min_password_length;
644 }
645 newpass = samr_rand_pass(tctx, policy_min_pw_len);
646
647 s.in.user_handle = handle;
648 s.in.info = &u;
649 s.in.level = 24;
650
651 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
652 u.info24.password_expired = 0;
653
654 status = dcerpc_fetch_session_key(p, &session_key);
655 if (!NT_STATUS_IS_OK(status)) {
656 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
657 s.in.level, nt_errstr(status));
658 return false;
659 }
660
661 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
662
663 torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
664
665 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
666 "SetUserInfo failed");
667 if (!NT_STATUS_IS_OK(s.out.result)) {
668 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
669 s.in.level, nt_errstr(s.out.result));
670 ret = false;
671 } else {
672 *password = newpass;
673 }
674
675 return ret;
676}
677
678
679static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
680 struct policy_handle *handle, uint32_t fields_present,
681 char **password)
682{
683 NTSTATUS status;
684 struct samr_SetUserInfo s;
685 union samr_UserInfo u;
686 bool ret = true;
687 DATA_BLOB session_key;
688 struct dcerpc_binding_handle *b = p->binding_handle;
689 char *newpass;
690 struct samr_GetUserPwInfo pwp;
691 struct samr_PwInfo info;
692 int policy_min_pw_len = 0;
693 pwp.in.user_handle = handle;
694 pwp.out.info = &info;
695
696 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
697 "GetUserPwInfo failed");
698 if (NT_STATUS_IS_OK(pwp.out.result)) {
699 policy_min_pw_len = pwp.out.info->min_password_length;
700 }
701 newpass = samr_rand_pass(tctx, policy_min_pw_len);
702
703 s.in.user_handle = handle;
704 s.in.info = &u;
705 s.in.level = 23;
706
707 ZERO_STRUCT(u);
708
709 u.info23.info.fields_present = fields_present;
710
711 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
712
713 status = dcerpc_fetch_session_key(p, &session_key);
714 if (!NT_STATUS_IS_OK(status)) {
715 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
716 s.in.level, nt_errstr(status));
717 return false;
718 }
719
720 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
721
722 torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
723
724 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
725 "SetUserInfo failed");
726 if (!NT_STATUS_IS_OK(s.out.result)) {
727 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
728 s.in.level, nt_errstr(s.out.result));
729 ret = false;
730 } else {
731 *password = newpass;
732 }
733
734 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
735
736 status = dcerpc_fetch_session_key(p, &session_key);
737 if (!NT_STATUS_IS_OK(status)) {
738 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
739 s.in.level, nt_errstr(status));
740 return false;
741 }
742
743 /* This should break the key nicely */
744 session_key.length--;
745 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
746
747 torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
748
749 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
750 "SetUserInfo failed");
751 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
752 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
753 s.in.level, nt_errstr(s.out.result));
754 ret = false;
755 }
756
757 return ret;
758}
759
760
761static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
762 struct policy_handle *handle, bool makeshort,
763 char **password)
764{
765 NTSTATUS status;
766 struct samr_SetUserInfo s;
767 union samr_UserInfo u;
768 bool ret = true;
769 DATA_BLOB session_key;
770 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
771 uint8_t confounder[16];
772 char *newpass;
773 struct dcerpc_binding_handle *b = p->binding_handle;
774 MD5_CTX ctx;
775 struct samr_GetUserPwInfo pwp;
776 struct samr_PwInfo info;
777 int policy_min_pw_len = 0;
778 pwp.in.user_handle = handle;
779 pwp.out.info = &info;
780
781 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
782 "GetUserPwInfo failed");
783 if (NT_STATUS_IS_OK(pwp.out.result)) {
784 policy_min_pw_len = pwp.out.info->min_password_length;
785 }
786 if (makeshort && policy_min_pw_len) {
787 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
788 } else {
789 newpass = samr_rand_pass(tctx, policy_min_pw_len);
790 }
791
792 s.in.user_handle = handle;
793 s.in.info = &u;
794 s.in.level = 26;
795
796 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
797 u.info26.password_expired = 0;
798
799 status = dcerpc_fetch_session_key(p, &session_key);
800 if (!NT_STATUS_IS_OK(status)) {
801 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
802 s.in.level, nt_errstr(status));
803 return false;
804 }
805
806 generate_random_buffer((uint8_t *)confounder, 16);
807
808 MD5Init(&ctx);
809 MD5Update(&ctx, confounder, 16);
810 MD5Update(&ctx, session_key.data, session_key.length);
811 MD5Final(confounded_session_key.data, &ctx);
812
813 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
814 memcpy(&u.info26.password.data[516], confounder, 16);
815
816 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
817
818 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
819 "SetUserInfo failed");
820 if (!NT_STATUS_IS_OK(s.out.result)) {
821 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
822 s.in.level, nt_errstr(s.out.result));
823 ret = false;
824 } else {
825 *password = newpass;
826 }
827
828 /* This should break the key nicely */
829 confounded_session_key.data[0]++;
830
831 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
832 memcpy(&u.info26.password.data[516], confounder, 16);
833
834 torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
835
836 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
837 "SetUserInfo failed");
838 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
839 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
840 s.in.level, nt_errstr(s.out.result));
841 ret = false;
842 } else {
843 *password = newpass;
844 }
845
846 return ret;
847}
848
849static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
850 struct policy_handle *handle, uint32_t fields_present,
851 char **password)
852{
853 NTSTATUS status;
854 struct samr_SetUserInfo s;
855 union samr_UserInfo u;
856 bool ret = true;
857 DATA_BLOB session_key;
858 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
859 MD5_CTX ctx;
860 uint8_t confounder[16];
861 char *newpass;
862 struct dcerpc_binding_handle *b = p->binding_handle;
863 struct samr_GetUserPwInfo pwp;
864 struct samr_PwInfo info;
865 int policy_min_pw_len = 0;
866 pwp.in.user_handle = handle;
867 pwp.out.info = &info;
868
869 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
870 "GetUserPwInfo failed");
871 if (NT_STATUS_IS_OK(pwp.out.result)) {
872 policy_min_pw_len = pwp.out.info->min_password_length;
873 }
874 newpass = samr_rand_pass(tctx, policy_min_pw_len);
875
876 s.in.user_handle = handle;
877 s.in.info = &u;
878 s.in.level = 25;
879
880 ZERO_STRUCT(u);
881
882 u.info25.info.fields_present = fields_present;
883
884 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
885
886 status = dcerpc_fetch_session_key(p, &session_key);
887 if (!NT_STATUS_IS_OK(status)) {
888 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
889 s.in.level, nt_errstr(status));
890 return false;
891 }
892
893 generate_random_buffer((uint8_t *)confounder, 16);
894
895 MD5Init(&ctx);
896 MD5Update(&ctx, confounder, 16);
897 MD5Update(&ctx, session_key.data, session_key.length);
898 MD5Final(confounded_session_key.data, &ctx);
899
900 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
901 memcpy(&u.info25.password.data[516], confounder, 16);
902
903 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
904
905 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
906 "SetUserInfo failed");
907 if (!NT_STATUS_IS_OK(s.out.result)) {
908 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
909 s.in.level, nt_errstr(s.out.result));
910 ret = false;
911 } else {
912 *password = newpass;
913 }
914
915 /* This should break the key nicely */
916 confounded_session_key.data[0]++;
917
918 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
919 memcpy(&u.info25.password.data[516], confounder, 16);
920
921 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
922
923 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
924 "SetUserInfo failed");
925 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_WRONG_PASSWORD)) {
926 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
927 s.in.level, nt_errstr(s.out.result));
928 ret = false;
929 }
930
931 return ret;
932}
933
934static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
935 struct policy_handle *handle, char **password)
936{
937 NTSTATUS status;
938 struct samr_SetUserInfo s;
939 union samr_UserInfo u;
940 bool ret = true;
941 DATA_BLOB session_key;
942 char *newpass;
943 struct dcerpc_binding_handle *b = p->binding_handle;
944 struct samr_GetUserPwInfo pwp;
945 struct samr_PwInfo info;
946 int policy_min_pw_len = 0;
947 uint8_t lm_hash[16], nt_hash[16];
948
949 pwp.in.user_handle = handle;
950 pwp.out.info = &info;
951
952 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
953 "GetUserPwInfo failed");
954 if (NT_STATUS_IS_OK(pwp.out.result)) {
955 policy_min_pw_len = pwp.out.info->min_password_length;
956 }
957 newpass = samr_rand_pass(tctx, policy_min_pw_len);
958
959 s.in.user_handle = handle;
960 s.in.info = &u;
961 s.in.level = 18;
962
963 ZERO_STRUCT(u);
964
965 u.info18.nt_pwd_active = true;
966 u.info18.lm_pwd_active = true;
967
968 E_md4hash(newpass, nt_hash);
969 E_deshash(newpass, lm_hash);
970
971 status = dcerpc_fetch_session_key(p, &session_key);
972 if (!NT_STATUS_IS_OK(status)) {
973 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
974 s.in.level, nt_errstr(status));
975 return false;
976 }
977
978 {
979 DATA_BLOB in,out;
980 in = data_blob_const(nt_hash, 16);
981 out = data_blob_talloc_zero(tctx, 16);
982 sess_crypt_blob(&out, &in, &session_key, true);
983 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
984 }
985 {
986 DATA_BLOB in,out;
987 in = data_blob_const(lm_hash, 16);
988 out = data_blob_talloc_zero(tctx, 16);
989 sess_crypt_blob(&out, &in, &session_key, true);
990 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
991 }
992
993 torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
994
995 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
996 "SetUserInfo failed");
997 if (!NT_STATUS_IS_OK(s.out.result)) {
998 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
999 s.in.level, nt_errstr(s.out.result));
1000 ret = false;
1001 } else {
1002 *password = newpass;
1003 }
1004
1005 return ret;
1006}
1007
1008static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
1009 struct policy_handle *handle, uint32_t fields_present,
1010 char **password)
1011{
1012 NTSTATUS status;
1013 struct samr_SetUserInfo s;
1014 union samr_UserInfo u;
1015 bool ret = true;
1016 DATA_BLOB session_key;
1017 char *newpass;
1018 struct dcerpc_binding_handle *b = p->binding_handle;
1019 struct samr_GetUserPwInfo pwp;
1020 struct samr_PwInfo info;
1021 int policy_min_pw_len = 0;
1022 uint8_t lm_hash[16], nt_hash[16];
1023
1024 pwp.in.user_handle = handle;
1025 pwp.out.info = &info;
1026
1027 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1028 "GetUserPwInfo failed");
1029 if (NT_STATUS_IS_OK(pwp.out.result)) {
1030 policy_min_pw_len = pwp.out.info->min_password_length;
1031 }
1032 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1033
1034 s.in.user_handle = handle;
1035 s.in.info = &u;
1036 s.in.level = 21;
1037
1038 E_md4hash(newpass, nt_hash);
1039 E_deshash(newpass, lm_hash);
1040
1041 ZERO_STRUCT(u);
1042
1043 u.info21.fields_present = fields_present;
1044
1045 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1046 u.info21.lm_owf_password.length = 16;
1047 u.info21.lm_owf_password.size = 16;
1048 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1049 u.info21.lm_password_set = true;
1050 }
1051
1052 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1053 u.info21.nt_owf_password.length = 16;
1054 u.info21.nt_owf_password.size = 16;
1055 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1056 u.info21.nt_password_set = true;
1057 }
1058
1059 status = dcerpc_fetch_session_key(p, &session_key);
1060 if (!NT_STATUS_IS_OK(status)) {
1061 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1062 s.in.level, nt_errstr(status));
1063 return false;
1064 }
1065
1066 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1067 DATA_BLOB in,out;
1068 in = data_blob_const(u.info21.lm_owf_password.array,
1069 u.info21.lm_owf_password.length);
1070 out = data_blob_talloc_zero(tctx, 16);
1071 sess_crypt_blob(&out, &in, &session_key, true);
1072 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1073 }
1074
1075 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1076 DATA_BLOB in,out;
1077 in = data_blob_const(u.info21.nt_owf_password.array,
1078 u.info21.nt_owf_password.length);
1079 out = data_blob_talloc_zero(tctx, 16);
1080 sess_crypt_blob(&out, &in, &session_key, true);
1081 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1082 }
1083
1084 torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1085
1086 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1087 "SetUserInfo failed");
1088 if (!NT_STATUS_IS_OK(s.out.result)) {
1089 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1090 s.in.level, nt_errstr(s.out.result));
1091 ret = false;
1092 } else {
1093 *password = newpass;
1094 }
1095
1096 /* try invalid length */
1097 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1098
1099 u.info21.nt_owf_password.length++;
1100
1101 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1102 "SetUserInfo failed");
1103 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1104 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1105 s.in.level, nt_errstr(s.out.result));
1106 ret = false;
1107 }
1108 }
1109
1110 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1111
1112 u.info21.lm_owf_password.length++;
1113
1114 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1115 "SetUserInfo failed");
1116 if (!NT_STATUS_EQUAL(s.out.result, NT_STATUS_INVALID_PARAMETER)) {
1117 torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1118 s.in.level, nt_errstr(s.out.result));
1119 ret = false;
1120 }
1121 }
1122
1123 return ret;
1124}
1125
1126static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1127 struct torture_context *tctx,
1128 struct policy_handle *handle,
1129 uint16_t level,
1130 uint32_t fields_present,
1131 char **password, uint8_t password_expired,
1132 bool use_setinfo2,
1133 bool *matched_expected_error)
1134{
1135 NTSTATUS status;
1136 NTSTATUS expected_error = NT_STATUS_OK;
1137 struct samr_SetUserInfo s;
1138 struct samr_SetUserInfo2 s2;
1139 union samr_UserInfo u;
1140 bool ret = true;
1141 DATA_BLOB session_key;
1142 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1143 MD5_CTX ctx;
1144 uint8_t confounder[16];
1145 char *newpass;
1146 struct dcerpc_binding_handle *b = p->binding_handle;
1147 struct samr_GetUserPwInfo pwp;
1148 struct samr_PwInfo info;
1149 int policy_min_pw_len = 0;
1150 const char *comment = NULL;
1151 uint8_t lm_hash[16], nt_hash[16];
1152
1153 pwp.in.user_handle = handle;
1154 pwp.out.info = &info;
1155
1156 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1157 "GetUserPwInfo failed");
1158 if (NT_STATUS_IS_OK(pwp.out.result)) {
1159 policy_min_pw_len = pwp.out.info->min_password_length;
1160 }
1161 newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1162
1163 if (use_setinfo2) {
1164 s2.in.user_handle = handle;
1165 s2.in.info = &u;
1166 s2.in.level = level;
1167 } else {
1168 s.in.user_handle = handle;
1169 s.in.info = &u;
1170 s.in.level = level;
1171 }
1172
1173 if (fields_present & SAMR_FIELD_COMMENT) {
1174 comment = talloc_asprintf(tctx, "comment: %ld\n", (long int) time(NULL));
1175 }
1176
1177 ZERO_STRUCT(u);
1178
1179 switch (level) {
1180 case 18:
1181 E_md4hash(newpass, nt_hash);
1182 E_deshash(newpass, lm_hash);
1183
1184 u.info18.nt_pwd_active = true;
1185 u.info18.lm_pwd_active = true;
1186 u.info18.password_expired = password_expired;
1187
1188 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1189 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1190
1191 break;
1192 case 21:
1193 E_md4hash(newpass, nt_hash);
1194 E_deshash(newpass, lm_hash);
1195
1196 u.info21.fields_present = fields_present;
1197 u.info21.password_expired = password_expired;
1198 u.info21.comment.string = comment;
1199
1200 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1201 u.info21.lm_owf_password.length = 16;
1202 u.info21.lm_owf_password.size = 16;
1203 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1204 u.info21.lm_password_set = true;
1205 }
1206
1207 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1208 u.info21.nt_owf_password.length = 16;
1209 u.info21.nt_owf_password.size = 16;
1210 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1211 u.info21.nt_password_set = true;
1212 }
1213
1214 break;
1215 case 23:
1216 u.info23.info.fields_present = fields_present;
1217 u.info23.info.password_expired = password_expired;
1218 u.info23.info.comment.string = comment;
1219
1220 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1221
1222 break;
1223 case 24:
1224 u.info24.password_expired = password_expired;
1225
1226 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1227
1228 break;
1229 case 25:
1230 u.info25.info.fields_present = fields_present;
1231 u.info25.info.password_expired = password_expired;
1232 u.info25.info.comment.string = comment;
1233
1234 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1235
1236 break;
1237 case 26:
1238 u.info26.password_expired = password_expired;
1239
1240 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1241
1242 break;
1243 }
1244
1245 status = dcerpc_fetch_session_key(p, &session_key);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1248 s.in.level, nt_errstr(status));
1249 return false;
1250 }
1251
1252 generate_random_buffer((uint8_t *)confounder, 16);
1253
1254 MD5Init(&ctx);
1255 MD5Update(&ctx, confounder, 16);
1256 MD5Update(&ctx, session_key.data, session_key.length);
1257 MD5Final(confounded_session_key.data, &ctx);
1258
1259 switch (level) {
1260 case 18:
1261 {
1262 DATA_BLOB in,out;
1263 in = data_blob_const(u.info18.nt_pwd.hash, 16);
1264 out = data_blob_talloc_zero(tctx, 16);
1265 sess_crypt_blob(&out, &in, &session_key, true);
1266 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1267 }
1268 {
1269 DATA_BLOB in,out;
1270 in = data_blob_const(u.info18.lm_pwd.hash, 16);
1271 out = data_blob_talloc_zero(tctx, 16);
1272 sess_crypt_blob(&out, &in, &session_key, true);
1273 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1274 }
1275
1276 break;
1277 case 21:
1278 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1279 DATA_BLOB in,out;
1280 in = data_blob_const(u.info21.lm_owf_password.array,
1281 u.info21.lm_owf_password.length);
1282 out = data_blob_talloc_zero(tctx, 16);
1283 sess_crypt_blob(&out, &in, &session_key, true);
1284 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1285 }
1286 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1287 DATA_BLOB in,out;
1288 in = data_blob_const(u.info21.nt_owf_password.array,
1289 u.info21.nt_owf_password.length);
1290 out = data_blob_talloc_zero(tctx, 16);
1291 sess_crypt_blob(&out, &in, &session_key, true);
1292 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1293 }
1294 break;
1295 case 23:
1296 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1297 break;
1298 case 24:
1299 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1300 break;
1301 case 25:
1302 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1303 memcpy(&u.info25.password.data[516], confounder, 16);
1304 break;
1305 case 26:
1306 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1307 memcpy(&u.info26.password.data[516], confounder, 16);
1308 break;
1309 }
1310
1311 if (use_setinfo2) {
1312 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo2_r(b, tctx, &s2),
1313 "SetUserInfo2 failed");
1314 status = s2.out.result;
1315 } else {
1316 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
1317 "SetUserInfo failed");
1318 status = s.out.result;
1319 }
1320
1321 if (!NT_STATUS_IS_OK(status)) {
1322 if (fields_present == 0) {
1323 expected_error = NT_STATUS_INVALID_PARAMETER;
1324 }
1325 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1326 expected_error = NT_STATUS_ACCESS_DENIED;
1327 }
1328 }
1329
1330 if (!NT_STATUS_IS_OK(expected_error)) {
1331 if (use_setinfo2) {
1332 torture_assert_ntstatus_equal(tctx,
1333 s2.out.result,
1334 expected_error, "SetUserInfo2 failed");
1335 } else {
1336 torture_assert_ntstatus_equal(tctx,
1337 s.out.result,
1338 expected_error, "SetUserInfo failed");
1339 }
1340 *matched_expected_error = true;
1341 return true;
1342 }
1343
1344 if (!NT_STATUS_IS_OK(status)) {
1345 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1346 use_setinfo2 ? "2":"", level, nt_errstr(status));
1347 ret = false;
1348 } else {
1349 *password = newpass;
1350 }
1351
1352 return ret;
1353}
1354
1355static bool test_SetAliasInfo(struct dcerpc_binding_handle *b,
1356 struct torture_context *tctx,
1357 struct policy_handle *handle)
1358{
1359 struct samr_SetAliasInfo r;
1360 struct samr_QueryAliasInfo q;
1361 union samr_AliasInfo *info;
1362 uint16_t levels[] = {2, 3};
1363 int i;
1364 bool ret = true;
1365
1366 /* Ignoring switch level 1, as that includes the number of members for the alias
1367 * and setting this to a wrong value might have negative consequences
1368 */
1369
1370 for (i=0;i<ARRAY_SIZE(levels);i++) {
1371 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1372
1373 r.in.alias_handle = handle;
1374 r.in.level = levels[i];
1375 r.in.info = talloc(tctx, union samr_AliasInfo);
1376 switch (r.in.level) {
1377 case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1378 case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1379 "Test Description, should test I18N as well"); break;
1380 case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1381 }
1382
1383 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetAliasInfo_r(b, tctx, &r),
1384 "SetAliasInfo failed");
1385 if (!NT_STATUS_IS_OK(r.out.result)) {
1386 torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1387 levels[i], nt_errstr(r.out.result));
1388 ret = false;
1389 }
1390
1391 q.in.alias_handle = handle;
1392 q.in.level = levels[i];
1393 q.out.info = &info;
1394
1395 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &q),
1396 "QueryAliasInfo failed");
1397 if (!NT_STATUS_IS_OK(q.out.result)) {
1398 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1399 levels[i], nt_errstr(q.out.result));
1400 ret = false;
1401 }
1402 }
1403
1404 return ret;
1405}
1406
1407static bool test_GetGroupsForUser(struct dcerpc_binding_handle *b,
1408 struct torture_context *tctx,
1409 struct policy_handle *user_handle)
1410{
1411 struct samr_GetGroupsForUser r;
1412 struct samr_RidWithAttributeArray *rids = NULL;
1413
1414 torture_comment(tctx, "Testing GetGroupsForUser\n");
1415
1416 r.in.user_handle = user_handle;
1417 r.out.rids = &rids;
1418
1419 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetGroupsForUser_r(b, tctx, &r),
1420 "GetGroupsForUser failed");
1421 torture_assert_ntstatus_ok(tctx, r.out.result, "GetGroupsForUser failed");
1422
1423 return true;
1424
1425}
1426
1427static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1428 struct lsa_String *domain_name)
1429{
1430 struct samr_GetDomPwInfo r;
1431 struct samr_PwInfo info;
1432 struct dcerpc_binding_handle *b = p->binding_handle;
1433
1434 r.in.domain_name = domain_name;
1435 r.out.info = &info;
1436
1437 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1438
1439 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1440 "GetDomPwInfo failed");
1441 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1442
1443 r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1444 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1445
1446 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1447 "GetDomPwInfo failed");
1448 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1449
1450 r.in.domain_name->string = "\\\\__NONAME__";
1451 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1452
1453 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1454 "GetDomPwInfo failed");
1455 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1456
1457 r.in.domain_name->string = "\\\\Builtin";
1458 torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1459
1460 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &r),
1461 "GetDomPwInfo failed");
1462 torture_assert_ntstatus_ok(tctx, r.out.result, "GetDomPwInfo failed");
1463
1464 return true;
1465}
1466
1467static bool test_GetUserPwInfo(struct dcerpc_binding_handle *b,
1468 struct torture_context *tctx,
1469 struct policy_handle *handle)
1470{
1471 struct samr_GetUserPwInfo r;
1472 struct samr_PwInfo info;
1473
1474 torture_comment(tctx, "Testing GetUserPwInfo\n");
1475
1476 r.in.user_handle = handle;
1477 r.out.info = &info;
1478
1479 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &r),
1480 "GetUserPwInfo failed");
1481 torture_assert_ntstatus_ok(tctx, r.out.result, "GetUserPwInfo");
1482
1483 return true;
1484}
1485
1486static NTSTATUS test_LookupName(struct dcerpc_binding_handle *b,
1487 struct torture_context *tctx,
1488 struct policy_handle *domain_handle, const char *name,
1489 uint32_t *rid)
1490{
1491 NTSTATUS status;
1492 struct samr_LookupNames n;
1493 struct lsa_String sname[2];
1494 struct samr_Ids rids, types;
1495
1496 init_lsa_String(&sname[0], name);
1497
1498 n.in.domain_handle = domain_handle;
1499 n.in.num_names = 1;
1500 n.in.names = sname;
1501 n.out.rids = &rids;
1502 n.out.types = &types;
1503 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1504 if (!NT_STATUS_IS_OK(status)) {
1505 return status;
1506 }
1507 if (NT_STATUS_IS_OK(n.out.result)) {
1508 *rid = n.out.rids->ids[0];
1509 } else {
1510 return n.out.result;
1511 }
1512
1513 init_lsa_String(&sname[1], "xxNONAMExx");
1514 n.in.num_names = 2;
1515 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1516 if (!NT_STATUS_IS_OK(status)) {
1517 return status;
1518 }
1519 if (!NT_STATUS_EQUAL(n.out.result, STATUS_SOME_UNMAPPED)) {
1520 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(n.out.result));
1521 if (NT_STATUS_IS_OK(n.out.result)) {
1522 return NT_STATUS_UNSUCCESSFUL;
1523 }
1524 return n.out.result;
1525 }
1526
1527 n.in.num_names = 0;
1528 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1529 if (!NT_STATUS_IS_OK(status)) {
1530 return status;
1531 }
1532 if (!NT_STATUS_IS_OK(n.out.result)) {
1533 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1534 return n.out.result;
1535 }
1536
1537 init_lsa_String(&sname[0], "xxNONAMExx");
1538 n.in.num_names = 1;
1539 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1540 if (!NT_STATUS_IS_OK(status)) {
1541 return status;
1542 }
1543 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1544 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(n.out.result));
1545 if (NT_STATUS_IS_OK(n.out.result)) {
1546 return NT_STATUS_UNSUCCESSFUL;
1547 }
1548 return n.out.result;
1549 }
1550
1551 init_lsa_String(&sname[0], "xxNONAMExx");
1552 init_lsa_String(&sname[1], "xxNONAME2xx");
1553 n.in.num_names = 2;
1554 status = dcerpc_samr_LookupNames_r(b, tctx, &n);
1555 if (!NT_STATUS_IS_OK(status)) {
1556 return status;
1557 }
1558 if (!NT_STATUS_EQUAL(n.out.result, NT_STATUS_NONE_MAPPED)) {
1559 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(n.out.result));
1560 if (NT_STATUS_IS_OK(n.out.result)) {
1561 return NT_STATUS_UNSUCCESSFUL;
1562 }
1563 return n.out.result;
1564 }
1565
1566 return NT_STATUS_OK;
1567}
1568
1569static NTSTATUS test_OpenUser_byname(struct dcerpc_binding_handle *b,
1570 struct torture_context *tctx,
1571 struct policy_handle *domain_handle,
1572 const char *name, struct policy_handle *user_handle)
1573{
1574 NTSTATUS status;
1575 struct samr_OpenUser r;
1576 uint32_t rid;
1577
1578 status = test_LookupName(b, tctx, domain_handle, name, &rid);
1579 if (!NT_STATUS_IS_OK(status)) {
1580 return status;
1581 }
1582
1583 r.in.domain_handle = domain_handle;
1584 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1585 r.in.rid = rid;
1586 r.out.user_handle = user_handle;
1587 status = dcerpc_samr_OpenUser_r(b, tctx, &r);
1588 if (!NT_STATUS_IS_OK(status)) {
1589 return status;
1590 }
1591 if (!NT_STATUS_IS_OK(r.out.result)) {
1592 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(r.out.result));
1593 }
1594
1595 return r.out.result;
1596}
1597
1598#if 0
1599static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1600 struct torture_context *tctx,
1601 struct policy_handle *handle)
1602{
1603 NTSTATUS status;
1604 struct samr_ChangePasswordUser r;
1605 bool ret = true;
1606 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1607 struct policy_handle user_handle;
1608 char *oldpass = "test";
1609 char *newpass = "test2";
1610 uint8_t old_nt_hash[16], new_nt_hash[16];
1611 uint8_t old_lm_hash[16], new_lm_hash[16];
1612
1613 status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 return false;
1616 }
1617
1618 torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1619
1620 torture_comment(tctx, "old password: %s\n", oldpass);
1621 torture_comment(tctx, "new password: %s\n", newpass);
1622
1623 E_md4hash(oldpass, old_nt_hash);
1624 E_md4hash(newpass, new_nt_hash);
1625 E_deshash(oldpass, old_lm_hash);
1626 E_deshash(newpass, new_lm_hash);
1627
1628 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1629 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1630 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1631 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1632 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1633 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1634
1635 r.in.handle = &user_handle;
1636 r.in.lm_present = 1;
1637 r.in.old_lm_crypted = &hash1;
1638 r.in.new_lm_crypted = &hash2;
1639 r.in.nt_present = 1;
1640 r.in.old_nt_crypted = &hash3;
1641 r.in.new_nt_crypted = &hash4;
1642 r.in.cross1_present = 1;
1643 r.in.nt_cross = &hash5;
1644 r.in.cross2_present = 1;
1645 r.in.lm_cross = &hash6;
1646
1647 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1648 "ChangePasswordUser failed");
1649 if (!NT_STATUS_IS_OK(r.out.result)) {
1650 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1651 ret = false;
1652 }
1653
1654 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1655 ret = false;
1656 }
1657
1658 return ret;
1659}
1660#endif
1661
1662static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b,
1663 struct torture_context *tctx,
1664 const char *acct_name,
1665 struct policy_handle *handle, char **password)
1666{
1667 NTSTATUS status;
1668 struct samr_ChangePasswordUser r;
1669 bool ret = true;
1670 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1671 struct policy_handle user_handle;
1672 char *oldpass;
1673 uint8_t old_nt_hash[16], new_nt_hash[16];
1674 uint8_t old_lm_hash[16], new_lm_hash[16];
1675 bool changed = true;
1676
1677 char *newpass;
1678 struct samr_GetUserPwInfo pwp;
1679 struct samr_PwInfo info;
1680 int policy_min_pw_len = 0;
1681
1682 status = test_OpenUser_byname(b, tctx, handle, acct_name, &user_handle);
1683 if (!NT_STATUS_IS_OK(status)) {
1684 return false;
1685 }
1686 pwp.in.user_handle = &user_handle;
1687 pwp.out.info = &info;
1688
1689 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetUserPwInfo_r(b, tctx, &pwp),
1690 "GetUserPwInfo failed");
1691 if (NT_STATUS_IS_OK(pwp.out.result)) {
1692 policy_min_pw_len = pwp.out.info->min_password_length;
1693 }
1694 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1695
1696 torture_comment(tctx, "Testing ChangePasswordUser\n");
1697
1698 torture_assert(tctx, *password != NULL,
1699 "Failing ChangePasswordUser as old password was NULL. Previous test failed?");
1700
1701 oldpass = *password;
1702
1703 E_md4hash(oldpass, old_nt_hash);
1704 E_md4hash(newpass, new_nt_hash);
1705 E_deshash(oldpass, old_lm_hash);
1706 E_deshash(newpass, new_lm_hash);
1707
1708 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1709 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1710 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1711 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1712 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1713 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1714
1715 r.in.user_handle = &user_handle;
1716 r.in.lm_present = 1;
1717 /* Break the LM hash */
1718 hash1.hash[0]++;
1719 r.in.old_lm_crypted = &hash1;
1720 r.in.new_lm_crypted = &hash2;
1721 r.in.nt_present = 1;
1722 r.in.old_nt_crypted = &hash3;
1723 r.in.new_nt_crypted = &hash4;
1724 r.in.cross1_present = 1;
1725 r.in.nt_cross = &hash5;
1726 r.in.cross2_present = 1;
1727 r.in.lm_cross = &hash6;
1728
1729 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1730 "ChangePasswordUser failed");
1731
1732 /* Do not proceed if this call has been removed */
1733 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
1734 return true;
1735 }
1736
1737 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1738 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1739 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1740 }
1741
1742 /* Unbreak the LM hash */
1743 hash1.hash[0]--;
1744
1745 r.in.user_handle = &user_handle;
1746 r.in.lm_present = 1;
1747 r.in.old_lm_crypted = &hash1;
1748 r.in.new_lm_crypted = &hash2;
1749 /* Break the NT hash */
1750 hash3.hash[0]--;
1751 r.in.nt_present = 1;
1752 r.in.old_nt_crypted = &hash3;
1753 r.in.new_nt_crypted = &hash4;
1754 r.in.cross1_present = 1;
1755 r.in.nt_cross = &hash5;
1756 r.in.cross2_present = 1;
1757 r.in.lm_cross = &hash6;
1758
1759 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1760 "ChangePasswordUser failed");
1761 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD,
1762 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1763
1764 /* Unbreak the NT hash */
1765 hash3.hash[0]--;
1766
1767 r.in.user_handle = &user_handle;
1768 r.in.lm_present = 1;
1769 r.in.old_lm_crypted = &hash1;
1770 r.in.new_lm_crypted = &hash2;
1771 r.in.nt_present = 1;
1772 r.in.old_nt_crypted = &hash3;
1773 r.in.new_nt_crypted = &hash4;
1774 r.in.cross1_present = 1;
1775 r.in.nt_cross = &hash5;
1776 r.in.cross2_present = 1;
1777 /* Break the LM cross */
1778 hash6.hash[0]++;
1779 r.in.lm_cross = &hash6;
1780
1781 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1782 "ChangePasswordUser failed");
1783 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1784 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(r.out.result));
1785 ret = false;
1786 }
1787
1788 /* Unbreak the LM cross */
1789 hash6.hash[0]--;
1790
1791 r.in.user_handle = &user_handle;
1792 r.in.lm_present = 1;
1793 r.in.old_lm_crypted = &hash1;
1794 r.in.new_lm_crypted = &hash2;
1795 r.in.nt_present = 1;
1796 r.in.old_nt_crypted = &hash3;
1797 r.in.new_nt_crypted = &hash4;
1798 r.in.cross1_present = 1;
1799 /* Break the NT cross */
1800 hash5.hash[0]++;
1801 r.in.nt_cross = &hash5;
1802 r.in.cross2_present = 1;
1803 r.in.lm_cross = &hash6;
1804
1805 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1806 "ChangePasswordUser failed");
1807 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1808 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(r.out.result));
1809 ret = false;
1810 }
1811
1812 /* Unbreak the NT cross */
1813 hash5.hash[0]--;
1814
1815
1816 /* Reset the hashes to not broken values */
1817 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1818 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1819 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1820 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1821 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1822 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1823
1824 r.in.user_handle = &user_handle;
1825 r.in.lm_present = 1;
1826 r.in.old_lm_crypted = &hash1;
1827 r.in.new_lm_crypted = &hash2;
1828 r.in.nt_present = 1;
1829 r.in.old_nt_crypted = &hash3;
1830 r.in.new_nt_crypted = &hash4;
1831 r.in.cross1_present = 1;
1832 r.in.nt_cross = &hash5;
1833 r.in.cross2_present = 0;
1834 r.in.lm_cross = NULL;
1835
1836 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1837 "ChangePasswordUser failed");
1838 if (NT_STATUS_IS_OK(r.out.result)) {
1839 changed = true;
1840 *password = newpass;
1841 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1842 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1843 ret = false;
1844 }
1845
1846 oldpass = newpass;
1847 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1848
1849 E_md4hash(oldpass, old_nt_hash);
1850 E_md4hash(newpass, new_nt_hash);
1851 E_deshash(oldpass, old_lm_hash);
1852 E_deshash(newpass, new_lm_hash);
1853
1854
1855 /* Reset the hashes to not broken values */
1856 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1857 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1858 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1859 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1860 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1861 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1862
1863 r.in.user_handle = &user_handle;
1864 r.in.lm_present = 1;
1865 r.in.old_lm_crypted = &hash1;
1866 r.in.new_lm_crypted = &hash2;
1867 r.in.nt_present = 1;
1868 r.in.old_nt_crypted = &hash3;
1869 r.in.new_nt_crypted = &hash4;
1870 r.in.cross1_present = 0;
1871 r.in.nt_cross = NULL;
1872 r.in.cross2_present = 1;
1873 r.in.lm_cross = &hash6;
1874
1875 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1876 "ChangePasswordUser failed");
1877 if (NT_STATUS_IS_OK(r.out.result)) {
1878 changed = true;
1879 *password = newpass;
1880 } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, r.out.result)) {
1881 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(r.out.result));
1882 ret = false;
1883 }
1884
1885 oldpass = newpass;
1886 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1887
1888 E_md4hash(oldpass, old_nt_hash);
1889 E_md4hash(newpass, new_nt_hash);
1890 E_deshash(oldpass, old_lm_hash);
1891 E_deshash(newpass, new_lm_hash);
1892
1893
1894 /* Reset the hashes to not broken values */
1895 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1896 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1897 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1898 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1899 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1900 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1901
1902 r.in.user_handle = &user_handle;
1903 r.in.lm_present = 1;
1904 r.in.old_lm_crypted = &hash1;
1905 r.in.new_lm_crypted = &hash2;
1906 r.in.nt_present = 1;
1907 r.in.old_nt_crypted = &hash3;
1908 r.in.new_nt_crypted = &hash4;
1909 r.in.cross1_present = 1;
1910 r.in.nt_cross = &hash5;
1911 r.in.cross2_present = 1;
1912 r.in.lm_cross = &hash6;
1913
1914 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1915 "ChangePasswordUser failed");
1916 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1917 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1918 } else if (!NT_STATUS_IS_OK(r.out.result)) {
1919 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(r.out.result));
1920 ret = false;
1921 } else {
1922 changed = true;
1923 *password = newpass;
1924 }
1925
1926 r.in.user_handle = &user_handle;
1927 r.in.lm_present = 1;
1928 r.in.old_lm_crypted = &hash1;
1929 r.in.new_lm_crypted = &hash2;
1930 r.in.nt_present = 1;
1931 r.in.old_nt_crypted = &hash3;
1932 r.in.new_nt_crypted = &hash4;
1933 r.in.cross1_present = 1;
1934 r.in.nt_cross = &hash5;
1935 r.in.cross2_present = 1;
1936 r.in.lm_cross = &hash6;
1937
1938 if (changed) {
1939 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r),
1940 "ChangePasswordUser failed");
1941 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
1942 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
1943 } else if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
1944 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(r.out.result));
1945 ret = false;
1946 }
1947 }
1948
1949
1950 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
1951 ret = false;
1952 }
1953
1954 return ret;
1955}
1956
1957
1958static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p,
1959 struct torture_context *tctx,
1960 const char *acct_name,
1961 struct policy_handle *handle, char **password)
1962{
1963 struct samr_OemChangePasswordUser2 r;
1964 bool ret = true;
1965 struct samr_Password lm_verifier;
1966 struct samr_CryptPassword lm_pass;
1967 struct lsa_AsciiString server, account, account_bad;
1968 char *oldpass;
1969 char *newpass;
1970 struct dcerpc_binding_handle *b = p->binding_handle;
1971 uint8_t old_lm_hash[16], new_lm_hash[16];
1972
1973 struct samr_GetDomPwInfo dom_pw_info;
1974 struct samr_PwInfo info;
1975 int policy_min_pw_len = 0;
1976
1977 struct lsa_String domain_name;
1978
1979 domain_name.string = "";
1980 dom_pw_info.in.domain_name = &domain_name;
1981 dom_pw_info.out.info = &info;
1982
1983 torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1984
1985 torture_assert(tctx, *password != NULL,
1986 "Failing OemChangePasswordUser2 as old password was NULL. Previous test failed?");
1987
1988 oldpass = *password;
1989
1990 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
1991 "GetDomPwInfo failed");
1992 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
1993 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1994 }
1995
1996 newpass = samr_rand_pass(tctx, policy_min_pw_len);
1997
1998 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1999 account.string = acct_name;
2000
2001 E_deshash(oldpass, old_lm_hash);
2002 E_deshash(newpass, new_lm_hash);
2003
2004 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2005 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2006 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2007
2008 r.in.server = &server;
2009 r.in.account = &account;
2010 r.in.password = &lm_pass;
2011 r.in.hash = &lm_verifier;
2012
2013 /* Break the verification */
2014 lm_verifier.hash[0]++;
2015
2016 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2017 "OemChangePasswordUser2 failed");
2018
2019 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2020 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2021 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2022 nt_errstr(r.out.result));
2023 ret = false;
2024 }
2025
2026 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2027 /* Break the old password */
2028 old_lm_hash[0]++;
2029 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2030 /* unbreak it for the next operation */
2031 old_lm_hash[0]--;
2032 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2033
2034 r.in.server = &server;
2035 r.in.account = &account;
2036 r.in.password = &lm_pass;
2037 r.in.hash = &lm_verifier;
2038
2039 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2040 "OemChangePasswordUser2 failed");
2041
2042 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2043 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2044 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2045 nt_errstr(r.out.result));
2046 ret = false;
2047 }
2048
2049 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2050 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2051
2052 r.in.server = &server;
2053 r.in.account = &account;
2054 r.in.password = &lm_pass;
2055 r.in.hash = NULL;
2056
2057 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2058 "OemChangePasswordUser2 failed");
2059
2060 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2061 && !NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2062 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
2063 nt_errstr(r.out.result));
2064 ret = false;
2065 }
2066
2067 /* This shouldn't be a valid name */
2068 account_bad.string = TEST_ACCOUNT_NAME "XX";
2069 r.in.account = &account_bad;
2070
2071 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2072 "OemChangePasswordUser2 failed");
2073
2074 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2075 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
2076 nt_errstr(r.out.result));
2077 ret = false;
2078 }
2079
2080 /* This shouldn't be a valid name */
2081 account_bad.string = TEST_ACCOUNT_NAME "XX";
2082 r.in.account = &account_bad;
2083 r.in.password = &lm_pass;
2084 r.in.hash = &lm_verifier;
2085
2086 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2087 "OemChangePasswordUser2 failed");
2088
2089 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2090 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
2091 nt_errstr(r.out.result));
2092 ret = false;
2093 }
2094
2095 /* This shouldn't be a valid name */
2096 account_bad.string = TEST_ACCOUNT_NAME "XX";
2097 r.in.account = &account_bad;
2098 r.in.password = NULL;
2099 r.in.hash = &lm_verifier;
2100
2101 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2102 "OemChangePasswordUser2 failed");
2103
2104 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
2105 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2106 nt_errstr(r.out.result));
2107 ret = false;
2108 }
2109
2110 E_deshash(oldpass, old_lm_hash);
2111 E_deshash(newpass, new_lm_hash);
2112
2113 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2114 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2115 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2116
2117 r.in.server = &server;
2118 r.in.account = &account;
2119 r.in.password = &lm_pass;
2120 r.in.hash = &lm_verifier;
2121
2122 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OemChangePasswordUser2_r(b, tctx, &r),
2123 "OemChangePasswordUser2 failed");
2124
2125 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2126 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2127 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2128 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2129 ret = false;
2130 } else {
2131 *password = newpass;
2132 }
2133
2134 return ret;
2135}
2136
2137
2138static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2139 const char *acct_name,
2140 char **password,
2141 char *newpass, bool allow_password_restriction)
2142{
2143 struct samr_ChangePasswordUser2 r;
2144 bool ret = true;
2145 struct lsa_String server, account;
2146 struct samr_CryptPassword nt_pass, lm_pass;
2147 struct samr_Password nt_verifier, lm_verifier;
2148 char *oldpass;
2149 struct dcerpc_binding_handle *b = p->binding_handle;
2150 uint8_t old_nt_hash[16], new_nt_hash[16];
2151 uint8_t old_lm_hash[16], new_lm_hash[16];
2152
2153 struct samr_GetDomPwInfo dom_pw_info;
2154 struct samr_PwInfo info;
2155
2156 struct lsa_String domain_name;
2157
2158 domain_name.string = "";
2159 dom_pw_info.in.domain_name = &domain_name;
2160 dom_pw_info.out.info = &info;
2161
2162 torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2163
2164 torture_assert(tctx, *password != NULL,
2165 "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?");
2166 oldpass = *password;
2167
2168 if (!newpass) {
2169 int policy_min_pw_len = 0;
2170 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2171 "GetDomPwInfo failed");
2172 if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2173 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2174 }
2175
2176 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2177 }
2178
2179 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2180 init_lsa_String(&account, acct_name);
2181
2182 E_md4hash(oldpass, old_nt_hash);
2183 E_md4hash(newpass, new_nt_hash);
2184
2185 E_deshash(oldpass, old_lm_hash);
2186 E_deshash(newpass, new_lm_hash);
2187
2188 encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2189 arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2190 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2191
2192 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2193 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2194 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2195
2196 r.in.server = &server;
2197 r.in.account = &account;
2198 r.in.nt_password = &nt_pass;
2199 r.in.nt_verifier = &nt_verifier;
2200 r.in.lm_change = 1;
2201 r.in.lm_password = &lm_pass;
2202 r.in.lm_verifier = &lm_verifier;
2203
2204 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2205 "ChangePasswordUser2 failed");
2206
2207 if (allow_password_restriction && NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2208 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2209 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2210 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(r.out.result));
2211 ret = false;
2212 } else {
2213 *password = newpass;
2214 }
2215
2216 return ret;
2217}
2218
2219
2220bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2221 const char *account_string,
2222 int policy_min_pw_len,
2223 char **password,
2224 const char *newpass,
2225 NTTIME last_password_change,
2226 bool handle_reject_reason)
2227{
2228 struct samr_ChangePasswordUser3 r;
2229 bool ret = true;
2230 struct lsa_String server, account, account_bad;
2231 struct samr_CryptPassword nt_pass, lm_pass;
2232 struct samr_Password nt_verifier, lm_verifier;
2233 char *oldpass;
2234 struct dcerpc_binding_handle *b = p->binding_handle;
2235 uint8_t old_nt_hash[16], new_nt_hash[16];
2236 uint8_t old_lm_hash[16], new_lm_hash[16];
2237 NTTIME t;
2238 struct samr_DomInfo1 *dominfo = NULL;
2239 struct userPwdChangeFailureInformation *reject = NULL;
2240
2241 torture_comment(tctx, "Testing ChangePasswordUser3\n");
2242
2243 if (newpass == NULL) {
2244 do {
2245 if (policy_min_pw_len == 0) {
2246 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2247 } else {
2248 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2249 }
2250 } while (check_password_quality(newpass) == false);
2251 } else {
2252 torture_comment(tctx, "Using password '%s'\n", newpass);
2253 }
2254
2255 torture_assert(tctx, *password != NULL,
2256 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2257
2258 oldpass = *password;
2259 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2260 init_lsa_String(&account, account_string);
2261
2262 E_md4hash(oldpass, old_nt_hash);
2263 E_md4hash(newpass, new_nt_hash);
2264
2265 E_deshash(oldpass, old_lm_hash);
2266 E_deshash(newpass, new_lm_hash);
2267
2268 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2269 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2270 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2271
2272 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2273 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2274 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2275
2276 /* Break the verification */
2277 nt_verifier.hash[0]++;
2278
2279 r.in.server = &server;
2280 r.in.account = &account;
2281 r.in.nt_password = &nt_pass;
2282 r.in.nt_verifier = &nt_verifier;
2283 r.in.lm_change = 1;
2284 r.in.lm_password = &lm_pass;
2285 r.in.lm_verifier = &lm_verifier;
2286 r.in.password3 = NULL;
2287 r.out.dominfo = &dominfo;
2288 r.out.reject = &reject;
2289
2290 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2291 "ChangePasswordUser3 failed");
2292 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2293 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2294 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2295 nt_errstr(r.out.result));
2296 ret = false;
2297 }
2298
2299 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2300 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2301 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2302
2303 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2304 /* Break the NT hash */
2305 old_nt_hash[0]++;
2306 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2307 /* Unbreak it again */
2308 old_nt_hash[0]--;
2309 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2310
2311 r.in.server = &server;
2312 r.in.account = &account;
2313 r.in.nt_password = &nt_pass;
2314 r.in.nt_verifier = &nt_verifier;
2315 r.in.lm_change = 1;
2316 r.in.lm_password = &lm_pass;
2317 r.in.lm_verifier = &lm_verifier;
2318 r.in.password3 = NULL;
2319 r.out.dominfo = &dominfo;
2320 r.out.reject = &reject;
2321
2322 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2323 "ChangePasswordUser3 failed");
2324 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2325 (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2326 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2327 nt_errstr(r.out.result));
2328 ret = false;
2329 }
2330
2331 /* This shouldn't be a valid name */
2332 init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2333
2334 r.in.account = &account_bad;
2335 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2336 "ChangePasswordUser3 failed");
2337 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2338 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2339 nt_errstr(r.out.result));
2340 ret = false;
2341 }
2342
2343 E_md4hash(oldpass, old_nt_hash);
2344 E_md4hash(newpass, new_nt_hash);
2345
2346 E_deshash(oldpass, old_lm_hash);
2347 E_deshash(newpass, new_lm_hash);
2348
2349 encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2350 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2351 E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2352
2353 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2354 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2355 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2356
2357 r.in.server = &server;
2358 r.in.account = &account;
2359 r.in.nt_password = &nt_pass;
2360 r.in.nt_verifier = &nt_verifier;
2361 r.in.lm_change = 1;
2362 r.in.lm_password = &lm_pass;
2363 r.in.lm_verifier = &lm_verifier;
2364 r.in.password3 = NULL;
2365 r.out.dominfo = &dominfo;
2366 r.out.reject = &reject;
2367
2368 unix_to_nt_time(&t, time(NULL));
2369
2370 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2371 "ChangePasswordUser3 failed");
2372
2373 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2374 && dominfo
2375 && reject
2376 && handle_reject_reason
2377 && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2378 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2379
2380 if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2381 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2382 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2383 return false;
2384 }
2385 }
2386
2387 /* We tested the order of precendence which is as follows:
2388
2389 * pwd min_age
2390 * pwd length
2391 * pwd complexity
2392 * pwd history
2393
2394 Guenther */
2395
2396 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2397 (last_password_change + dominfo->min_password_age > t)) {
2398
2399 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2400 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2401 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2402 return false;
2403 }
2404
2405 } else if ((dominfo->min_password_length > 0) &&
2406 (strlen(newpass) < dominfo->min_password_length)) {
2407
2408 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2409 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2410 SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2411 return false;
2412 }
2413
2414 } else if ((dominfo->password_history_length > 0) &&
2415 strequal(oldpass, newpass)) {
2416
2417 if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2418 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2419 SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2420 return false;
2421 }
2422 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2423
2424 if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2425 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2426 SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2427 return false;
2428 }
2429
2430 }
2431
2432 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2433 /* retry with adjusted size */
2434 return test_ChangePasswordUser3(p, tctx, account_string,
2435 dominfo->min_password_length,
2436 password, NULL, 0, false);
2437
2438 }
2439
2440 } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2441 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2442 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2443 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2444 return false;
2445 }
2446 /* Perhaps the server has a 'min password age' set? */
2447
2448 } else {
2449 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2450
2451 *password = talloc_strdup(tctx, newpass);
2452 }
2453
2454 return ret;
2455}
2456
2457bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2458 const char *account_string,
2459 struct policy_handle *handle,
2460 char **password)
2461{
2462 NTSTATUS status;
2463 struct samr_ChangePasswordUser3 r;
2464 struct samr_SetUserInfo s;
2465 union samr_UserInfo u;
2466 DATA_BLOB session_key;
2467 DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2468 uint8_t confounder[16];
2469 MD5_CTX ctx;
2470
2471 bool ret = true;
2472 struct lsa_String server, account;
2473 struct samr_CryptPassword nt_pass;
2474 struct samr_Password nt_verifier;
2475 DATA_BLOB new_random_pass;
2476 char *newpass;
2477 char *oldpass;
2478 struct dcerpc_binding_handle *b = p->binding_handle;
2479 uint8_t old_nt_hash[16], new_nt_hash[16];
2480 NTTIME t;
2481 struct samr_DomInfo1 *dominfo = NULL;
2482 struct userPwdChangeFailureInformation *reject = NULL;
2483
2484 new_random_pass = samr_very_rand_pass(tctx, 128);
2485
2486 torture_assert(tctx, *password != NULL,
2487 "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?");
2488
2489 oldpass = *password;
2490 server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2491 init_lsa_String(&account, account_string);
2492
2493 s.in.user_handle = handle;
2494 s.in.info = &u;
2495 s.in.level = 25;
2496
2497 ZERO_STRUCT(u);
2498
2499 u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2500
2501 set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2502
2503 status = dcerpc_fetch_session_key(p, &session_key);
2504 if (!NT_STATUS_IS_OK(status)) {
2505 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2506 s.in.level, nt_errstr(status));
2507 return false;
2508 }
2509
2510 generate_random_buffer((uint8_t *)confounder, 16);
2511
2512 MD5Init(&ctx);
2513 MD5Update(&ctx, confounder, 16);
2514 MD5Update(&ctx, session_key.data, session_key.length);
2515 MD5Final(confounded_session_key.data, &ctx);
2516
2517 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2518 memcpy(&u.info25.password.data[516], confounder, 16);
2519
2520 torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2521
2522 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2523 "SetUserInfo failed");
2524 if (!NT_STATUS_IS_OK(s.out.result)) {
2525 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2526 s.in.level, nt_errstr(s.out.result));
2527 ret = false;
2528 }
2529
2530 torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2531
2532 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2533
2534 new_random_pass = samr_very_rand_pass(tctx, 128);
2535
2536 mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2537
2538 set_pw_in_buffer(nt_pass.data, &new_random_pass);
2539 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2540 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2541
2542 r.in.server = &server;
2543 r.in.account = &account;
2544 r.in.nt_password = &nt_pass;
2545 r.in.nt_verifier = &nt_verifier;
2546 r.in.lm_change = 0;
2547 r.in.lm_password = NULL;
2548 r.in.lm_verifier = NULL;
2549 r.in.password3 = NULL;
2550 r.out.dominfo = &dominfo;
2551 r.out.reject = &reject;
2552
2553 unix_to_nt_time(&t, time(NULL));
2554
2555 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2556 "ChangePasswordUser3 failed");
2557
2558 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2559 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2560 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2561 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2562 return false;
2563 }
2564 /* Perhaps the server has a 'min password age' set? */
2565
2566 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2567 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2568 ret = false;
2569 }
2570
2571 newpass = samr_rand_pass(tctx, 128);
2572
2573 mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2574
2575 E_md4hash(newpass, new_nt_hash);
2576
2577 encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2578 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2579 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2580
2581 r.in.server = &server;
2582 r.in.account = &account;
2583 r.in.nt_password = &nt_pass;
2584 r.in.nt_verifier = &nt_verifier;
2585 r.in.lm_change = 0;
2586 r.in.lm_password = NULL;
2587 r.in.lm_verifier = NULL;
2588 r.in.password3 = NULL;
2589 r.out.dominfo = &dominfo;
2590 r.out.reject = &reject;
2591
2592 unix_to_nt_time(&t, time(NULL));
2593
2594 torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2595 "ChangePasswordUser3 failed");
2596
2597 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2598 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2599 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2600 SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2601 return false;
2602 }
2603 /* Perhaps the server has a 'min password age' set? */
2604
2605 } else {
2606 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2607 *password = talloc_strdup(tctx, newpass);
2608 }
2609
2610 return ret;
2611}
2612
2613
2614static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2615 struct torture_context *tctx,
2616 struct policy_handle *alias_handle)
2617{
2618 struct samr_GetMembersInAlias r;
2619 struct lsa_SidArray sids;
2620
2621 torture_comment(tctx, "Testing GetMembersInAlias\n");
2622
2623 r.in.alias_handle = alias_handle;
2624 r.out.sids = &sids;
2625
2626 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2627 "GetMembersInAlias failed");
2628 torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2629
2630 return true;
2631}
2632
2633static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2634 struct torture_context *tctx,
2635 struct policy_handle *alias_handle,
2636 const struct dom_sid *domain_sid)
2637{
2638 struct samr_AddAliasMember r;
2639 struct samr_DeleteAliasMember d;
2640 struct dom_sid *sid;
2641
2642 sid = dom_sid_add_rid(tctx, domain_sid, 512);
2643
2644 torture_comment(tctx, "Testing AddAliasMember\n");
2645 r.in.alias_handle = alias_handle;
2646 r.in.sid = sid;
2647
2648 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2649 "AddAliasMember failed");
2650 torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2651
2652 d.in.alias_handle = alias_handle;
2653 d.in.sid = sid;
2654
2655 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2656 "DeleteAliasMember failed");
2657 torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2658
2659 return true;
2660}
2661
2662static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2663 struct torture_context *tctx,
2664 struct policy_handle *alias_handle)
2665{
2666 struct samr_AddMultipleMembersToAlias a;
2667 struct samr_RemoveMultipleMembersFromAlias r;
2668 struct lsa_SidArray sids;
2669
2670 torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2671 a.in.alias_handle = alias_handle;
2672 a.in.sids = &sids;
2673
2674 sids.num_sids = 3;
2675 sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2676
2677 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2678 sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2679 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2680
2681 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2682 "AddMultipleMembersToAlias failed");
2683 torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2684
2685
2686 torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2687 r.in.alias_handle = alias_handle;
2688 r.in.sids = &sids;
2689
2690 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2691 "RemoveMultipleMembersFromAlias failed");
2692 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2693
2694 /* strange! removing twice doesn't give any error */
2695 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2696 "RemoveMultipleMembersFromAlias failed");
2697 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2698
2699 /* but removing an alias that isn't there does */
2700 sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2701
2702 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2703 "RemoveMultipleMembersFromAlias failed");
2704 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2705
2706 return true;
2707}
2708
2709static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2710 struct torture_context *tctx,
2711 struct policy_handle *domain_handle)
2712{
2713 struct samr_GetAliasMembership r;
2714 struct lsa_SidArray sids;
2715 struct samr_Ids rids;
2716
2717 torture_comment(tctx, "Testing GetAliasMembership\n");
2718
2719 r.in.domain_handle = domain_handle;
2720 r.in.sids = &sids;
2721 r.out.rids = &rids;
2722
2723 sids.num_sids = 0;
2724 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2725
2726 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2727 "GetAliasMembership failed");
2728 torture_assert_ntstatus_ok(tctx, r.out.result,
2729 "samr_GetAliasMembership failed");
2730
2731 torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2732 "protocol misbehaviour");
2733
2734 sids.num_sids = 1;
2735 sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2736 sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2737
2738 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2739 "samr_GetAliasMembership failed");
2740 torture_assert_ntstatus_ok(tctx, r.out.result,
2741 "samr_GetAliasMembership failed");
2742
2743#if 0
2744 /* only true for w2k8 it seems
2745 * win7, xp, w2k3 will return a 0 length array pointer */
2746
2747 if (rids.ids && (rids.count == 0)) {
2748 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2749 }
2750#endif
2751 if (!rids.ids && rids.count) {
2752 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2753 }
2754
2755 return true;
2756}
2757
2758static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2759 struct torture_context *tctx,
2760 struct policy_handle *user_handle)
2761{
2762 struct samr_TestPrivateFunctionsUser r;
2763
2764 torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2765
2766 r.in.user_handle = user_handle;
2767
2768 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2769 "TestPrivateFunctionsUser failed");
2770 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2771
2772 return true;
2773}
2774
2775static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2776 struct torture_context *tctx,
2777 struct policy_handle *handle,
2778 bool use_info2,
2779 NTTIME *pwdlastset)
2780{
2781 NTSTATUS status;
2782 uint16_t levels[] = { /* 3, */ 5, 21 };
2783 int i;
2784 NTTIME pwdlastset3 = 0;
2785 NTTIME pwdlastset5 = 0;
2786 NTTIME pwdlastset21 = 0;
2787
2788 torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2789 use_info2 ? "2":"");
2790
2791 for (i=0; i<ARRAY_SIZE(levels); i++) {
2792
2793 struct samr_QueryUserInfo r;
2794 struct samr_QueryUserInfo2 r2;
2795 union samr_UserInfo *info;
2796
2797 if (use_info2) {
2798 r2.in.user_handle = handle;
2799 r2.in.level = levels[i];
2800 r2.out.info = &info;
2801 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2802 "QueryUserInfo2 failed");
2803 status = r2.out.result;
2804
2805 } else {
2806 r.in.user_handle = handle;
2807 r.in.level = levels[i];
2808 r.out.info = &info;
2809 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2810 "QueryUserInfo failed");
2811 status = r.out.result;
2812 }
2813
2814 if (!NT_STATUS_IS_OK(status) &&
2815 !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2816 torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2817 use_info2 ? "2":"", levels[i], nt_errstr(status));
2818 return false;
2819 }
2820
2821 switch (levels[i]) {
2822 case 3:
2823 pwdlastset3 = info->info3.last_password_change;
2824 break;
2825 case 5:
2826 pwdlastset5 = info->info5.last_password_change;
2827 break;
2828 case 21:
2829 pwdlastset21 = info->info21.last_password_change;
2830 break;
2831 default:
2832 return false;
2833 }
2834 }
2835 /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2836 "pwdlastset mixup"); */
2837 torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2838 "pwdlastset mixup");
2839
2840 *pwdlastset = pwdlastset21;
2841
2842 torture_comment(tctx, "(pwdlastset: %llu)\n",
2843 (unsigned long long) *pwdlastset);
2844
2845 return true;
2846}
2847
2848static bool test_SamLogon(struct torture_context *tctx,
2849 struct dcerpc_pipe *p,
2850 struct cli_credentials *test_credentials,
2851 NTSTATUS expected_result,
2852 bool interactive)
2853{
2854 NTSTATUS status;
2855 struct netr_LogonSamLogonEx r;
2856 union netr_LogonLevel logon;
2857 union netr_Validation validation;
2858 uint8_t authoritative;
2859 struct netr_IdentityInfo identity;
2860 struct netr_NetworkInfo ninfo;
2861 struct netr_PasswordInfo pinfo;
2862 DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2863 int flags = CLI_CRED_NTLM_AUTH;
2864 uint32_t samlogon_flags = 0;
2865 struct netlogon_creds_CredentialState *creds;
2866 struct netr_Authenticator a;
2867 struct dcerpc_binding_handle *b = p->binding_handle;
2868
2869 torture_assert_ntstatus_ok(tctx, dcerpc_schannel_creds(p->conn->security_state.generic_state, tctx, &creds), "");
2870
2871 if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
2872 flags |= CLI_CRED_LANMAN_AUTH;
2873 }
2874
2875 if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
2876 flags |= CLI_CRED_NTLMv2_AUTH;
2877 }
2878
2879 cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2880 &identity.account_name.string,
2881 &identity.domain_name.string);
2882
2883 identity.parameter_control =
2884 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2885 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2886 identity.logon_id_low = 0;
2887 identity.logon_id_high = 0;
2888 identity.workstation.string = cli_credentials_get_workstation(test_credentials);
2889
2890 if (interactive) {
2891 netlogon_creds_client_authenticator(creds, &a);
2892
2893 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
2894 ZERO_STRUCT(pinfo.lmpassword.hash);
2895 }
2896 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
2897
2898 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
2899 netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
2900 netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
2901 } else {
2902 netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
2903 netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
2904 }
2905
2906 pinfo.identity_info = identity;
2907 logon.password = &pinfo;
2908
2909 r.in.logon_level = NetlogonInteractiveInformation;
2910 } else {
2911 generate_random_buffer(ninfo.challenge,
2912 sizeof(ninfo.challenge));
2913 chal = data_blob_const(ninfo.challenge,
2914 sizeof(ninfo.challenge));
2915
2916 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2917 cli_credentials_get_domain(test_credentials));
2918
2919 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2920 &flags,
2921 chal,
2922 names_blob,
2923 &lm_resp, &nt_resp,
2924 NULL, NULL);
2925 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2926
2927 ninfo.lm.data = lm_resp.data;
2928 ninfo.lm.length = lm_resp.length;
2929
2930 ninfo.nt.data = nt_resp.data;
2931 ninfo.nt.length = nt_resp.length;
2932
2933 ninfo.identity_info = identity;
2934 logon.network = &ninfo;
2935
2936 r.in.logon_level = NetlogonNetworkInformation;
2937 }
2938
2939 r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2940 r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2941 r.in.logon = &logon;
2942 r.in.flags = &samlogon_flags;
2943 r.out.flags = &samlogon_flags;
2944 r.out.validation = &validation;
2945 r.out.authoritative = &authoritative;
2946
2947 torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
2948
2949 r.in.validation_level = 6;
2950
2951 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2952 "netr_LogonSamLogonEx failed");
2953 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
2954 r.in.validation_level = 3;
2955 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
2956 "netr_LogonSamLogonEx failed");
2957 }
2958 if (!NT_STATUS_IS_OK(r.out.result)) {
2959 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
2960 return true;
2961 } else {
2962 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
2963 }
2964
2965 return true;
2966}
2967
2968static bool test_SamLogon_with_creds(struct torture_context *tctx,
2969 struct dcerpc_pipe *p,
2970 struct cli_credentials *machine_creds,
2971 const char *acct_name,
2972 const char *password,
2973 NTSTATUS expected_samlogon_result,
2974 bool interactive)
2975{
2976 bool ret = true;
2977 struct cli_credentials *test_credentials;
2978
2979 test_credentials = cli_credentials_init(tctx);
2980
2981 cli_credentials_set_workstation(test_credentials,
2982 cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2983 cli_credentials_set_domain(test_credentials,
2984 cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2985 cli_credentials_set_username(test_credentials,
2986 acct_name, CRED_SPECIFIED);
2987 cli_credentials_set_password(test_credentials,
2988 password, CRED_SPECIFIED);
2989
2990 torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
2991 interactive ? "interactive" : "network", acct_name, password);
2992
2993 if (!test_SamLogon(tctx, p, test_credentials,
2994 expected_samlogon_result, interactive)) {
2995 torture_warning(tctx, "new password did not work\n");
2996 ret = false;
2997 }
2998
2999 return ret;
3000}
3001
3002static bool test_SetPassword_level(struct dcerpc_pipe *p,
3003 struct dcerpc_pipe *np,
3004 struct torture_context *tctx,
3005 struct policy_handle *handle,
3006 uint16_t level,
3007 uint32_t fields_present,
3008 uint8_t password_expired,
3009 bool *matched_expected_error,
3010 bool use_setinfo2,
3011 const char *acct_name,
3012 char **password,
3013 struct cli_credentials *machine_creds,
3014 bool use_queryinfo2,
3015 NTTIME *pwdlastset,
3016 NTSTATUS expected_samlogon_result)
3017{
3018 const char *fields = NULL;
3019 bool ret = true;
3020 struct dcerpc_binding_handle *b = p->binding_handle;
3021
3022 switch (level) {
3023 case 21:
3024 case 23:
3025 case 25:
3026 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3027 fields_present);
3028 break;
3029 default:
3030 break;
3031 }
3032
3033 torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3034 "(password_expired: %d) %s\n",
3035 use_setinfo2 ? "2":"", level, password_expired,
3036 fields ? fields : "");
3037
3038 if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3039 fields_present,
3040 password,
3041 password_expired,
3042 use_setinfo2,
3043 matched_expected_error)) {
3044 ret = false;
3045 }
3046
3047 if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3048 use_queryinfo2,
3049 pwdlastset)) {
3050 ret = false;
3051 }
3052
3053 if (*matched_expected_error == true) {
3054 return ret;
3055 }
3056
3057 if (!test_SamLogon_with_creds(tctx, np,
3058 machine_creds,
3059 acct_name,
3060 *password,
3061 expected_samlogon_result,
3062 false)) {
3063 ret = false;
3064 }
3065
3066 return ret;
3067}
3068
3069static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3070 struct cli_credentials *credentials,
3071 struct dcerpc_pipe **p)
3072{
3073 struct dcerpc_binding *b;
3074
3075 torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3076 "failed to get rpc binding");
3077
3078 /* We have to use schannel, otherwise the SamLogonEx fails
3079 * with INTERNAL_ERROR */
3080
3081 b->flags &= ~DCERPC_AUTH_OPTIONS;
3082 b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
3083
3084 torture_assert_ntstatus_ok(tctx,
3085 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3086 credentials, tctx->ev, tctx->lp_ctx),
3087 "failed to bind to netlogon");
3088
3089 return true;
3090}
3091
3092static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3093 struct torture_context *tctx,
3094 uint32_t acct_flags,
3095 const char *acct_name,
3096 struct policy_handle *handle,
3097 char **password,
3098 struct cli_credentials *machine_credentials)
3099{
3100 int s = 0, q = 0, f = 0, l = 0, z = 0;
3101 bool ret = true;
3102 int delay = 50000;
3103 bool set_levels[] = { false, true };
3104 bool query_levels[] = { false, true };
3105 uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3106 uint32_t nonzeros[] = { 1, 24 };
3107 uint32_t fields_present[] = {
3108 0,
3109 SAMR_FIELD_EXPIRED_FLAG,
3110 SAMR_FIELD_LAST_PWD_CHANGE,
3111 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3112 SAMR_FIELD_COMMENT,
3113 SAMR_FIELD_NT_PASSWORD_PRESENT,
3114 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3115 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3116 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3117 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3118 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3119 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3120 };
3121 struct dcerpc_pipe *np = NULL;
3122
3123 if (torture_setting_bool(tctx, "samba3", false) ||
3124 torture_setting_bool(tctx, "samba4", false)) {
3125 delay = 999999;
3126 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3127 delay);
3128 }
3129
3130 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3131
3132 /* set to 1 to enable testing for all possible opcode
3133 (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3134 combinations */
3135#if 0
3136#define TEST_ALL_LEVELS 1
3137#define TEST_SET_LEVELS 1
3138#define TEST_QUERY_LEVELS 1
3139#endif
3140#ifdef TEST_ALL_LEVELS
3141 for (l=0; l<ARRAY_SIZE(levels); l++) {
3142#else
3143 for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3144#endif
3145 for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3146 for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3147#ifdef TEST_SET_LEVELS
3148 for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3149#endif
3150#ifdef TEST_QUERY_LEVELS
3151 for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3152#endif
3153 NTTIME pwdlastset_old = 0;
3154 NTTIME pwdlastset_new = 0;
3155 bool matched_expected_error = false;
3156 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3157
3158 torture_comment(tctx, "------------------------------\n"
3159 "Testing pwdLastSet attribute for flags: 0x%08x "
3160 "(s: %d (l: %d), q: %d)\n",
3161 acct_flags, s, levels[l], q);
3162
3163 switch (levels[l]) {
3164 case 21:
3165 case 23:
3166 case 25:
3167 if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3168 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3169 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3170 }
3171 break;
3172 }
3173
3174
3175 /* set #1 */
3176
3177 /* set a password and force password change (pwdlastset 0) by
3178 * setting the password expired flag to a non-0 value */
3179
3180 if (!test_SetPassword_level(p, np, tctx, handle,
3181 levels[l],
3182 fields_present[f],
3183 nonzeros[z],
3184 &matched_expected_error,
3185 set_levels[s],
3186 acct_name,
3187 password,
3188 machine_credentials,
3189 query_levels[q],
3190 &pwdlastset_new,
3191 expected_samlogon_result)) {
3192 ret = false;
3193 }
3194
3195 if (matched_expected_error == true) {
3196 /* skipping on expected failure */
3197 continue;
3198 }
3199
3200 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3201 * set without the SAMR_FIELD_EXPIRED_FLAG */
3202
3203 switch (levels[l]) {
3204 case 21:
3205 case 23:
3206 case 25:
3207 if ((pwdlastset_new != 0) &&
3208 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3209 torture_comment(tctx, "not considering a non-0 "
3210 "pwdLastSet as a an error as the "
3211 "SAMR_FIELD_EXPIRED_FLAG has not "
3212 "been set\n");
3213 break;
3214 }
3215 break;
3216 default:
3217 if (pwdlastset_new != 0) {
3218 torture_warning(tctx, "pwdLastSet test failed: "
3219 "expected pwdLastSet 0 but got %llu\n",
3220 (unsigned long long) pwdlastset_old);
3221 ret = false;
3222 }
3223 break;
3224 }
3225
3226 switch (levels[l]) {
3227 case 21:
3228 case 23:
3229 case 25:
3230 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3231 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3232 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3233 (pwdlastset_old >= pwdlastset_new)) {
3234 torture_warning(tctx, "pwdlastset not increasing\n");
3235 ret = false;
3236 }
3237 break;
3238 }
3239
3240 pwdlastset_old = pwdlastset_new;
3241
3242 usleep(delay);
3243
3244 /* set #2 */
3245
3246 /* set a password, pwdlastset needs to get updated (increased
3247 * value), password_expired value used here is 0 */
3248
3249 if (!test_SetPassword_level(p, np, tctx, handle,
3250 levels[l],
3251 fields_present[f],
3252 0,
3253 &matched_expected_error,
3254 set_levels[s],
3255 acct_name,
3256 password,
3257 machine_credentials,
3258 query_levels[q],
3259 &pwdlastset_new,
3260 expected_samlogon_result)) {
3261 ret = false;
3262 }
3263
3264 /* when a password has been changed, pwdlastset must not be 0 afterwards
3265 * and must be larger then the old value */
3266
3267 switch (levels[l]) {
3268 case 21:
3269 case 23:
3270 case 25:
3271 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3272 * password has been changed, old and new pwdlastset
3273 * need to be the same value */
3274
3275 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3276 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3277 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3278 {
3279 torture_assert_int_equal(tctx, pwdlastset_old,
3280 pwdlastset_new, "pwdlastset must be equal");
3281 break;
3282 }
3283 break;
3284 default:
3285 if (pwdlastset_old >= pwdlastset_new) {
3286 torture_warning(tctx, "pwdLastSet test failed: "
3287 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3288 (unsigned long long) pwdlastset_old,
3289 (unsigned long long) pwdlastset_new);
3290 ret = false;
3291 }
3292 if (pwdlastset_new == 0) {
3293 torture_warning(tctx, "pwdLastSet test failed: "
3294 "expected non-0 pwdlastset, got: %llu\n",
3295 (unsigned long long) pwdlastset_new);
3296 ret = false;
3297 }
3298 break;
3299 }
3300
3301 switch (levels[l]) {
3302 case 21:
3303 case 23:
3304 case 25:
3305 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3306 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3307 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3308 (pwdlastset_old >= pwdlastset_new)) {
3309 torture_warning(tctx, "pwdlastset not increasing\n");
3310 ret = false;
3311 }
3312 break;
3313 }
3314
3315 pwdlastset_old = pwdlastset_new;
3316
3317 usleep(delay);
3318
3319 /* set #2b */
3320
3321 /* set a password, pwdlastset needs to get updated (increased
3322 * value), password_expired value used here is 0 */
3323
3324 if (!test_SetPassword_level(p, np, tctx, handle,
3325 levels[l],
3326 fields_present[f],
3327 0,
3328 &matched_expected_error,
3329 set_levels[s],
3330 acct_name,
3331 password,
3332 machine_credentials,
3333 query_levels[q],
3334 &pwdlastset_new,
3335 expected_samlogon_result)) {
3336 ret = false;
3337 }
3338
3339 /* when a password has been changed, pwdlastset must not be 0 afterwards
3340 * and must be larger then the old value */
3341
3342 switch (levels[l]) {
3343 case 21:
3344 case 23:
3345 case 25:
3346
3347 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3348 * password has been changed, old and new pwdlastset
3349 * need to be the same value */
3350
3351 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3352 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3353 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3354 {
3355 torture_assert_int_equal(tctx, pwdlastset_old,
3356 pwdlastset_new, "pwdlastset must be equal");
3357 break;
3358 }
3359 break;
3360 default:
3361 if (pwdlastset_old >= pwdlastset_new) {
3362 torture_warning(tctx, "pwdLastSet test failed: "
3363 "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3364 (unsigned long long) pwdlastset_old,
3365 (unsigned long long) pwdlastset_new);
3366 ret = false;
3367 }
3368 if (pwdlastset_new == 0) {
3369 torture_warning(tctx, "pwdLastSet test failed: "
3370 "expected non-0 pwdlastset, got: %llu\n",
3371 (unsigned long long) pwdlastset_new);
3372 ret = false;
3373 }
3374 break;
3375 }
3376
3377 switch (levels[l]) {
3378 case 21:
3379 case 23:
3380 case 25:
3381 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3382 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3383 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3384 (pwdlastset_old >= pwdlastset_new)) {
3385 torture_warning(tctx, "pwdlastset not increasing\n");
3386 ret = false;
3387 }
3388 break;
3389 }
3390
3391 pwdlastset_old = pwdlastset_new;
3392
3393 usleep(delay);
3394
3395 /* set #3 */
3396
3397 /* set a password and force password change (pwdlastset 0) by
3398 * setting the password expired flag to a non-0 value */
3399
3400 if (!test_SetPassword_level(p, np, tctx, handle,
3401 levels[l],
3402 fields_present[f],
3403 nonzeros[z],
3404 &matched_expected_error,
3405 set_levels[s],
3406 acct_name,
3407 password,
3408 machine_credentials,
3409 query_levels[q],
3410 &pwdlastset_new,
3411 expected_samlogon_result)) {
3412 ret = false;
3413 }
3414
3415 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3416 * set without the SAMR_FIELD_EXPIRED_FLAG */
3417
3418 switch (levels[l]) {
3419 case 21:
3420 case 23:
3421 case 25:
3422 if ((pwdlastset_new != 0) &&
3423 !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3424 torture_comment(tctx, "not considering a non-0 "
3425 "pwdLastSet as a an error as the "
3426 "SAMR_FIELD_EXPIRED_FLAG has not "
3427 "been set\n");
3428 break;
3429 }
3430
3431 /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3432 * password has been changed, old and new pwdlastset
3433 * need to be the same value */
3434
3435 if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3436 !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3437 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3438 {
3439 torture_assert_int_equal(tctx, pwdlastset_old,
3440 pwdlastset_new, "pwdlastset must be equal");
3441 break;
3442 }
3443 break;
3444 default:
3445 if (pwdlastset_new != 0) {
3446 torture_warning(tctx, "pwdLastSet test failed: "
3447 "expected pwdLastSet 0, got %llu\n",
3448 (unsigned long long) pwdlastset_old);
3449 ret = false;
3450 }
3451 break;
3452 }
3453
3454 switch (levels[l]) {
3455 case 21:
3456 case 23:
3457 case 25:
3458 if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3459 (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3460 (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3461 (pwdlastset_old >= pwdlastset_new)) {
3462 torture_warning(tctx, "pwdlastset not increasing\n");
3463 ret = false;
3464 }
3465 break;
3466 }
3467
3468 /* if the level we are testing does not have a fields_present
3469 * field, skip all fields present tests by setting f to to
3470 * arraysize */
3471 switch (levels[l]) {
3472 case 18:
3473 case 24:
3474 case 26:
3475 f = ARRAY_SIZE(fields_present);
3476 break;
3477 }
3478
3479#ifdef TEST_QUERY_LEVELS
3480 }
3481#endif
3482#ifdef TEST_SET_LEVELS
3483 }
3484#endif
3485 } /* fields present */
3486 } /* nonzeros */
3487 } /* levels */
3488
3489#undef TEST_SET_LEVELS
3490#undef TEST_QUERY_LEVELS
3491
3492 talloc_free(np);
3493
3494 return ret;
3495}
3496
3497static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3498 struct torture_context *tctx,
3499 struct policy_handle *handle,
3500 uint32_t *badpwdcount)
3501{
3502 union samr_UserInfo *info;
3503 struct samr_QueryUserInfo r;
3504
3505 r.in.user_handle = handle;
3506 r.in.level = 3;
3507 r.out.info = &info;
3508
3509 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3510
3511 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3512 "failed to query userinfo");
3513 torture_assert_ntstatus_ok(tctx, r.out.result,
3514 "failed to query userinfo");
3515
3516 *badpwdcount = info->info3.bad_password_count;
3517
3518 torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3519
3520 return true;
3521}
3522
3523static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3524 struct torture_context *tctx,
3525 struct policy_handle *user_handle,
3526 uint32_t acct_flags)
3527{
3528 struct samr_SetUserInfo r;
3529 union samr_UserInfo user_info;
3530
3531 torture_comment(tctx, "Testing SetUserInfo level 16\n");
3532
3533 user_info.info16.acct_flags = acct_flags;
3534
3535 r.in.user_handle = user_handle;
3536 r.in.level = 16;
3537 r.in.info = &user_info;
3538
3539 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3540 "failed to set account flags");
3541 torture_assert_ntstatus_ok(tctx, r.out.result,
3542 "failed to set account flags");
3543
3544 return true;
3545}
3546
3547static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3548 struct torture_context *tctx,
3549 struct policy_handle *user_handle,
3550 uint32_t acct_flags,
3551 char **password)
3552{
3553 struct dcerpc_binding_handle *b = p->binding_handle;
3554
3555 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3556 "failed to set password");
3557
3558 torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3559
3560 torture_assert(tctx,
3561 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3562 acct_flags & ~ACB_DISABLED),
3563 "failed to enable user");
3564
3565 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3566 "failed to set password");
3567
3568 return true;
3569}
3570
3571static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3572 struct torture_context *tctx,
3573 struct policy_handle *domain_handle,
3574 enum samr_DomainInfoClass level,
3575 union samr_DomainInfo *info)
3576{
3577 struct samr_SetDomainInfo r;
3578
3579 r.in.domain_handle = domain_handle;
3580 r.in.level = level;
3581 r.in.info = info;
3582
3583 torture_assert_ntstatus_ok(tctx,
3584 dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3585 "failed to set domain info");
3586 torture_assert_ntstatus_ok(tctx, r.out.result,
3587 "failed to set domain info");
3588
3589 return true;
3590}
3591
3592static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3593 struct torture_context *tctx,
3594 struct policy_handle *domain_handle,
3595 enum samr_DomainInfoClass level,
3596 union samr_DomainInfo *info,
3597 NTSTATUS expected)
3598{
3599 struct samr_SetDomainInfo r;
3600
3601 r.in.domain_handle = domain_handle;
3602 r.in.level = level;
3603 r.in.info = info;
3604
3605 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3606 "SetDomainInfo failed");
3607 torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3608
3609 return true;
3610}
3611
3612static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3613 struct torture_context *tctx,
3614 struct policy_handle *domain_handle,
3615 enum samr_DomainInfoClass level,
3616 union samr_DomainInfo **q_info)
3617{
3618 struct samr_QueryDomainInfo2 r;
3619
3620 r.in.domain_handle = domain_handle;
3621 r.in.level = level;
3622 r.out.info = q_info;
3623
3624 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3625 "failed to query domain info");
3626 torture_assert_ntstatus_ok(tctx, r.out.result,
3627 "failed to query domain info");
3628
3629 return true;
3630}
3631
3632static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3633 struct dcerpc_pipe *np,
3634 struct torture_context *tctx,
3635 uint32_t acct_flags,
3636 const char *acct_name,
3637 struct policy_handle *domain_handle,
3638 struct policy_handle *user_handle,
3639 char **password,
3640 struct cli_credentials *machine_credentials,
3641 const char *comment,
3642 bool disable,
3643 bool interactive,
3644 NTSTATUS expected_success_status,
3645 struct samr_DomInfo1 *info1,
3646 struct samr_DomInfo12 *info12)
3647{
3648 union samr_DomainInfo info;
3649 char **passwords;
3650 int i;
3651 uint32_t badpwdcount, tmp;
3652 uint32_t password_history_length = 12;
3653 uint32_t lockout_threshold = 15;
3654 struct dcerpc_binding_handle *b = p->binding_handle;
3655
3656 torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3657
3658 torture_assert(tctx, password_history_length < lockout_threshold,
3659 "password history length needs to be smaller than account lockout threshold for this test");
3660
3661
3662 /* set policies */
3663
3664 info.info1 = *info1;
3665 info.info1.password_history_length = password_history_length;
3666
3667 torture_assert(tctx,
3668 test_SetDomainInfo(b, tctx, domain_handle,
3669 DomainPasswordInformation, &info),
3670 "failed to set password history length");
3671
3672 info.info12 = *info12;
3673 info.info12.lockout_threshold = lockout_threshold;
3674
3675 torture_assert(tctx,
3676 test_SetDomainInfo(b, tctx, domain_handle,
3677 DomainLockoutInformation, &info),
3678 "failed to set lockout threshold");
3679
3680 /* reset bad pwd count */
3681
3682 torture_assert(tctx,
3683 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3684
3685
3686 /* enable or disable account */
3687 if (disable) {
3688 torture_assert(tctx,
3689 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3690 acct_flags | ACB_DISABLED),
3691 "failed to disable user");
3692 } else {
3693 torture_assert(tctx,
3694 test_SetUserInfo_acct_flags(b, tctx, user_handle,
3695 acct_flags & ~ACB_DISABLED),
3696 "failed to enable user");
3697 }
3698
3699
3700 /* setup password history */
3701
3702 passwords = talloc_array(tctx, char *, password_history_length);
3703
3704 for (i=0; i < password_history_length; i++) {
3705
3706 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3707 "failed to set password");
3708 passwords[i] = talloc_strdup(tctx, *password);
3709
3710 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3711 acct_name, passwords[i],
3712 expected_success_status, interactive)) {
3713 torture_fail(tctx, "failed to auth with latest password");
3714 }
3715
3716 torture_assert(tctx,
3717 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3718
3719 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3720 }
3721
3722
3723 /* test with wrong password */
3724
3725 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3726 acct_name, "random_crap",
3727 NT_STATUS_WRONG_PASSWORD, interactive)) {
3728 torture_fail(tctx, "succeeded to authenticate with wrong password");
3729 }
3730
3731 torture_assert(tctx,
3732 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3733
3734 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3735
3736
3737 /* test with latest good password */
3738
3739 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3740 passwords[password_history_length-1],
3741 expected_success_status, interactive)) {
3742 torture_fail(tctx, "succeeded to authenticate with wrong password");
3743 }
3744
3745 torture_assert(tctx,
3746 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3747
3748 if (disable) {
3749 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3750 } else {
3751 /* only enabled accounts get the bad pwd count reset upon
3752 * successful logon */
3753 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3754 }
3755
3756 tmp = badpwdcount;
3757
3758
3759 /* test password history */
3760
3761 for (i=0; i < password_history_length; i++) {
3762
3763 torture_comment(tctx, "Testing bad password count behavior with "
3764 "password #%d of #%d\n", i, password_history_length);
3765
3766 /* - network samlogon will succeed auth and not
3767 * increase badpwdcount for 2 last entries
3768 * - interactive samlogon only for the last one */
3769
3770 if (i == password_history_length - 1 ||
3771 (i == password_history_length - 2 && !interactive)) {
3772
3773 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3774 acct_name, passwords[i],
3775 expected_success_status, interactive)) {
3776 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3777 }
3778
3779 torture_assert(tctx,
3780 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3781
3782 if (disable) {
3783 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3784 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3785 } else {
3786 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3787 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3788 }
3789
3790 tmp = badpwdcount;
3791
3792 continue;
3793 }
3794
3795 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3796 acct_name, passwords[i],
3797 NT_STATUS_WRONG_PASSWORD, interactive)) {
3798 torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
3799 }
3800
3801 torture_assert(tctx,
3802 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3803
3804 /* - network samlogon will fail auth but not increase
3805 * badpwdcount for 3rd last entry
3806 * - interactive samlogon for 3rd and 2nd last entry */
3807
3808 if (i == password_history_length - 3 ||
3809 (i == password_history_length - 2 && interactive)) {
3810 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
3811 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3812 } else {
3813 /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
3814 torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
3815 }
3816
3817 tmp = badpwdcount;
3818 }
3819
3820 return true;
3821}
3822
3823static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
3824 struct torture_context *tctx,
3825 uint32_t acct_flags,
3826 const char *acct_name,
3827 struct policy_handle *domain_handle,
3828 struct policy_handle *user_handle,
3829 char **password,
3830 struct cli_credentials *machine_credentials)
3831{
3832 union samr_DomainInfo *q_info, s_info;
3833 struct samr_DomInfo1 info1, _info1;
3834 struct samr_DomInfo12 info12, _info12;
3835 bool ret = true;
3836 struct dcerpc_binding_handle *b = p->binding_handle;
3837 struct dcerpc_pipe *np;
3838 int i;
3839
3840 struct {
3841 const char *comment;
3842 bool disabled;
3843 bool interactive;
3844 NTSTATUS expected_success_status;
3845 } creds[] = {
3846 {
3847 .comment = "network logon (disabled account)",
3848 .disabled = true,
3849 .interactive = false,
3850 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3851 },
3852 {
3853 .comment = "network logon (enabled account)",
3854 .disabled = false,
3855 .interactive = false,
3856 .expected_success_status= NT_STATUS_OK
3857 },
3858 {
3859 .comment = "interactive logon (disabled account)",
3860 .disabled = true,
3861 .interactive = true,
3862 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
3863 },
3864 {
3865 .comment = "interactive logon (enabled account)",
3866 .disabled = false,
3867 .interactive = true,
3868 .expected_success_status= NT_STATUS_OK
3869 },
3870 };
3871
3872 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3873
3874 /* backup old policies */
3875
3876 torture_assert(tctx,
3877 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3878 DomainPasswordInformation, &q_info),
3879 "failed to query domain info level 1");
3880
3881 info1 = q_info->info1;
3882 _info1 = info1;
3883
3884 torture_assert(tctx,
3885 test_QueryDomainInfo2_level(b, tctx, domain_handle,
3886 DomainLockoutInformation, &q_info),
3887 "failed to query domain info level 12");
3888
3889 info12 = q_info->info12;
3890 _info12 = info12;
3891
3892 /* run tests */
3893
3894 for (i=0; i < ARRAY_SIZE(creds); i++) {
3895
3896 /* skip trust tests for now */
3897 if (acct_flags & ACB_WSTRUST ||
3898 acct_flags & ACB_SVRTRUST ||
3899 acct_flags & ACB_DOMTRUST) {
3900 continue;
3901 }
3902
3903 ret &= test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
3904 domain_handle, user_handle, password,
3905 machine_credentials,
3906 creds[i].comment,
3907 creds[i].disabled,
3908 creds[i].interactive,
3909 creds[i].expected_success_status,
3910 &_info1, &_info12);
3911 if (!ret) {
3912 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
3913 } else {
3914 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
3915 }
3916 }
3917
3918 /* restore policies */
3919
3920 s_info.info1 = info1;
3921
3922 torture_assert(tctx,
3923 test_SetDomainInfo(b, tctx, domain_handle,
3924 DomainPasswordInformation, &s_info),
3925 "failed to set password information");
3926
3927 s_info.info12 = info12;
3928
3929 torture_assert(tctx,
3930 test_SetDomainInfo(b, tctx, domain_handle,
3931 DomainLockoutInformation, &s_info),
3932 "failed to set lockout information");
3933
3934 return ret;
3935}
3936
3937static bool test_QueryUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3938 struct torture_context *tctx,
3939 struct policy_handle *handle,
3940 uint32_t *acct_flags)
3941{
3942 union samr_UserInfo *info;
3943 struct samr_QueryUserInfo r;
3944
3945 r.in.user_handle = handle;
3946 r.in.level = 16;
3947 r.out.info = &info;
3948
3949 torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3950
3951 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3952 "failed to query userinfo");
3953 torture_assert_ntstatus_ok(tctx, r.out.result,
3954 "failed to query userinfo");
3955
3956 *acct_flags = info->info16.acct_flags;
3957
3958 torture_comment(tctx, " (acct_flags: 0x%08x)\n", *acct_flags);
3959
3960 return true;
3961}
3962
3963static bool test_Password_lockout(struct dcerpc_pipe *p,
3964 struct dcerpc_pipe *np,
3965 struct torture_context *tctx,
3966 uint32_t acct_flags,
3967 const char *acct_name,
3968 struct policy_handle *domain_handle,
3969 struct policy_handle *user_handle,
3970 char **password,
3971 struct cli_credentials *machine_credentials,
3972 const char *comment,
3973 bool disable,
3974 bool interactive,
3975 NTSTATUS expected_success_status,
3976 struct samr_DomInfo1 *info1,
3977 struct samr_DomInfo12 *info12)
3978{
3979 union samr_DomainInfo info;
3980 uint32_t badpwdcount;
3981 uint32_t password_history_length = 1;
3982 uint64_t lockout_threshold = 1;
3983 uint32_t lockout_seconds = 5;
3984 uint64_t delta_time_factor = 10 * 1000 * 1000;
3985 struct dcerpc_binding_handle *b = p->binding_handle;
3986
3987 torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
3988
3989 /* set policies */
3990
3991 info.info1 = *info1;
3992
3993 torture_comment(tctx, "setting password history length.\n");
3994 info.info1.password_history_length = password_history_length;
3995
3996 torture_assert(tctx,
3997 test_SetDomainInfo(b, tctx, domain_handle,
3998 DomainPasswordInformation, &info),
3999 "failed to set password history length");
4000
4001 info.info12 = *info12;
4002 info.info12.lockout_threshold = lockout_threshold;
4003
4004 /* set lockout duration < lockout window: should fail */
4005 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4006 info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4007
4008 torture_assert(tctx,
4009 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4010 DomainLockoutInformation, &info,
4011 NT_STATUS_INVALID_PARAMETER),
4012 "setting lockout duration < lockout window gave unexpected result");
4013
4014 info.info12.lockout_duration = 0;
4015 info.info12.lockout_window = 0;
4016
4017 torture_assert(tctx,
4018 test_SetDomainInfo(b, tctx, domain_handle,
4019 DomainLockoutInformation, &info),
4020 "failed to set lockout window and duration to 0");
4021
4022
4023 /* set lockout duration of 5 seconds */
4024 info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4025 info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4026
4027 torture_assert(tctx,
4028 test_SetDomainInfo(b, tctx, domain_handle,
4029 DomainLockoutInformation, &info),
4030 "failed to set lockout window and duration to 5 seconds");
4031
4032 /* reset bad pwd count */
4033
4034 torture_assert(tctx,
4035 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4036
4037
4038 /* enable or disable account */
4039
4040 if (disable) {
4041 torture_assert(tctx,
4042 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4043 acct_flags | ACB_DISABLED),
4044 "failed to disable user");
4045 } else {
4046 torture_assert(tctx,
4047 test_SetUserInfo_acct_flags(b, tctx, user_handle,
4048 acct_flags & ~ACB_DISABLED),
4049 "failed to enable user");
4050 }
4051
4052
4053 /* test logon with right password */
4054
4055 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4056 acct_name, *password,
4057 expected_success_status, interactive)) {
4058 torture_fail(tctx, "failed to auth with latest password");
4059 }
4060
4061 torture_assert(tctx,
4062 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4063 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4064
4065
4066 /* test with wrong password ==> lockout */
4067
4068 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4069 acct_name, "random_crap",
4070 NT_STATUS_WRONG_PASSWORD, interactive)) {
4071 torture_fail(tctx, "succeeded to authenticate with wrong password");
4072 }
4073
4074 torture_assert(tctx,
4075 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4076 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4077
4078 torture_assert(tctx,
4079 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4080 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4081 "expected account to be locked");
4082
4083
4084 /* test with good password */
4085
4086 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4087 *password,
4088 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4089 {
4090 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4091 }
4092
4093 /* bad pwd count should not get updated */
4094 torture_assert(tctx,
4095 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4096 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4097
4098 /* curiously, windows does _not_ set the autlock flag */
4099 torture_assert(tctx,
4100 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4101 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4102 "expected account to be locked");
4103
4104
4105 /* with bad password */
4106
4107 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4108 acct_name, "random_crap2",
4109 NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4110 {
4111 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4112 }
4113
4114 /* bad pwd count should not get updated */
4115 torture_assert(tctx,
4116 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4117 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4118
4119 /* curiously, windows does _not_ set the autlock flag */
4120 torture_assert(tctx,
4121 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4122 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4123 "expected account to be locked");
4124
4125
4126 /* let lockout duration expire ==> unlock */
4127
4128 torture_comment(tctx, "let lockout duration expire...\n");
4129 sleep(lockout_seconds + 1);
4130
4131 if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4132 *password,
4133 expected_success_status, interactive))
4134 {
4135 torture_fail(tctx, "failed to authenticate after lockout expired");
4136 }
4137
4138 torture_assert(tctx,
4139 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4140 torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4141 "expected account not to be locked");
4142
4143 return true;
4144}
4145
4146static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4147 struct torture_context *tctx,
4148 uint32_t acct_flags,
4149 const char *acct_name,
4150 struct policy_handle *domain_handle,
4151 struct policy_handle *user_handle,
4152 char **password,
4153 struct cli_credentials *machine_credentials)
4154{
4155 union samr_DomainInfo *q_info, s_info;
4156 struct samr_DomInfo1 info1, _info1;
4157 struct samr_DomInfo12 info12, _info12;
4158 bool ret = true;
4159 struct dcerpc_binding_handle *b = p->binding_handle;
4160 struct dcerpc_pipe *np;
4161 int i;
4162
4163 struct {
4164 const char *comment;
4165 bool disabled;
4166 bool interactive;
4167 NTSTATUS expected_success_status;
4168 } creds[] = {
4169 {
4170 .comment = "network logon (disabled account)",
4171 .disabled = true,
4172 .interactive = false,
4173 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4174 },
4175 {
4176 .comment = "network logon (enabled account)",
4177 .disabled = false,
4178 .interactive = false,
4179 .expected_success_status= NT_STATUS_OK
4180 },
4181 {
4182 .comment = "interactive logon (disabled account)",
4183 .disabled = true,
4184 .interactive = true,
4185 .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4186 },
4187 {
4188 .comment = "interactive logon (enabled account)",
4189 .disabled = false,
4190 .interactive = true,
4191 .expected_success_status= NT_STATUS_OK
4192 },
4193 };
4194
4195 torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4196
4197 /* backup old policies */
4198
4199 torture_assert(tctx,
4200 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4201 DomainPasswordInformation, &q_info),
4202 "failed to query domain info level 1");
4203
4204 info1 = q_info->info1;
4205 _info1 = info1;
4206
4207 torture_assert(tctx,
4208 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4209 DomainLockoutInformation, &q_info),
4210 "failed to query domain info level 12");
4211
4212 info12 = q_info->info12;
4213 _info12 = info12;
4214
4215 /* run tests */
4216
4217 for (i=0; i < ARRAY_SIZE(creds); i++) {
4218
4219 /* skip trust tests for now */
4220 if (acct_flags & ACB_WSTRUST ||
4221 acct_flags & ACB_SVRTRUST ||
4222 acct_flags & ACB_DOMTRUST) {
4223 continue;
4224 }
4225
4226 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4227 domain_handle, user_handle, password,
4228 machine_credentials,
4229 creds[i].comment,
4230 creds[i].disabled,
4231 creds[i].interactive,
4232 creds[i].expected_success_status,
4233 &_info1, &_info12);
4234 if (!ret) {
4235 torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4236 } else {
4237 torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4238 }
4239 }
4240
4241 /* restore policies */
4242
4243 s_info.info1 = info1;
4244
4245 torture_assert(tctx,
4246 test_SetDomainInfo(b, tctx, domain_handle,
4247 DomainPasswordInformation, &s_info),
4248 "failed to set password information");
4249
4250 s_info.info12 = info12;
4251
4252 torture_assert(tctx,
4253 test_SetDomainInfo(b, tctx, domain_handle,
4254 DomainLockoutInformation, &s_info),
4255 "failed to set lockout information");
4256
4257 return ret;
4258}
4259
4260static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4261 struct dcerpc_pipe *lp,
4262 struct torture_context *tctx,
4263 struct policy_handle *domain_handle,
4264 struct policy_handle *lsa_handle,
4265 struct policy_handle *user_handle,
4266 const struct dom_sid *domain_sid,
4267 uint32_t rid,
4268 struct cli_credentials *machine_credentials)
4269{
4270 bool ret = true;
4271 struct dcerpc_binding_handle *b = p->binding_handle;
4272 struct dcerpc_binding_handle *lb = lp->binding_handle;
4273
4274 struct policy_handle lsa_acct_handle;
4275 struct dom_sid *user_sid;
4276
4277 user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4278
4279 {
4280 struct lsa_EnumAccountRights r;
4281 struct lsa_RightSet rights;
4282
4283 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4284
4285 r.in.handle = lsa_handle;
4286 r.in.sid = user_sid;
4287 r.out.rights = &rights;
4288
4289 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4290 "lsa_EnumAccountRights failed");
4291 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4292 "Expected enum rights for account to fail");
4293 }
4294
4295 {
4296 struct lsa_RightSet rights;
4297 struct lsa_StringLarge names[2];
4298 struct lsa_AddAccountRights r;
4299
4300 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4301
4302 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4303 init_lsa_StringLarge(&names[1], NULL);
4304
4305 rights.count = 1;
4306 rights.names = names;
4307
4308 r.in.handle = lsa_handle;
4309 r.in.sid = user_sid;
4310 r.in.rights = &rights;
4311
4312 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4313 "lsa_AddAccountRights failed");
4314 torture_assert_ntstatus_ok(tctx, r.out.result,
4315 "Failed to add privileges");
4316 }
4317
4318 {
4319 struct lsa_EnumAccounts r;
4320 uint32_t resume_handle = 0;
4321 struct lsa_SidArray lsa_sid_array;
4322 int i;
4323 bool found_sid = false;
4324
4325 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4326
4327 r.in.handle = lsa_handle;
4328 r.in.num_entries = 0x1000;
4329 r.in.resume_handle = &resume_handle;
4330 r.out.sids = &lsa_sid_array;
4331 r.out.resume_handle = &resume_handle;
4332
4333 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4334 "lsa_EnumAccounts failed");
4335 torture_assert_ntstatus_ok(tctx, r.out.result,
4336 "Failed to enum accounts");
4337
4338 for (i=0; i < lsa_sid_array.num_sids; i++) {
4339 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4340 found_sid = true;
4341 }
4342 }
4343
4344 torture_assert(tctx, found_sid,
4345 "failed to list privileged account");
4346 }
4347
4348 {
4349 struct lsa_EnumAccountRights r;
4350 struct lsa_RightSet user_rights;
4351
4352 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4353
4354 r.in.handle = lsa_handle;
4355 r.in.sid = user_sid;
4356 r.out.rights = &user_rights;
4357
4358 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4359 "lsa_EnumAccountRights failed");
4360 torture_assert_ntstatus_ok(tctx, r.out.result,
4361 "Failed to enum rights for account");
4362
4363 if (user_rights.count < 1) {
4364 torture_warning(tctx, "failed to find newly added rights");
4365 return false;
4366 }
4367 }
4368
4369 {
4370 struct lsa_OpenAccount r;
4371
4372 torture_comment(tctx, "Testing LSA OpenAccount\n");
4373
4374 r.in.handle = lsa_handle;
4375 r.in.sid = user_sid;
4376 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4377 r.out.acct_handle = &lsa_acct_handle;
4378
4379 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4380 "lsa_OpenAccount failed");
4381 torture_assert_ntstatus_ok(tctx, r.out.result,
4382 "Failed to open lsa account");
4383 }
4384
4385 {
4386 struct lsa_GetSystemAccessAccount r;
4387 uint32_t access_mask;
4388
4389 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4390
4391 r.in.handle = &lsa_acct_handle;
4392 r.out.access_mask = &access_mask;
4393
4394 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4395 "lsa_GetSystemAccessAccount failed");
4396 torture_assert_ntstatus_ok(tctx, r.out.result,
4397 "Failed to get lsa system access account");
4398 }
4399
4400 {
4401 struct lsa_Close r;
4402
4403 torture_comment(tctx, "Testing LSA Close\n");
4404
4405 r.in.handle = &lsa_acct_handle;
4406 r.out.handle = &lsa_acct_handle;
4407
4408 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4409 "lsa_Close failed");
4410 torture_assert_ntstatus_ok(tctx, r.out.result,
4411 "Failed to close lsa");
4412 }
4413
4414 {
4415 struct samr_DeleteUser r;
4416
4417 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4418
4419 r.in.user_handle = user_handle;
4420 r.out.user_handle = user_handle;
4421
4422 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4423 "DeleteUser failed");
4424 torture_assert_ntstatus_ok(tctx, r.out.result,
4425 "DeleteUser failed");
4426 }
4427
4428 {
4429 struct lsa_EnumAccounts r;
4430 uint32_t resume_handle = 0;
4431 struct lsa_SidArray lsa_sid_array;
4432 int i;
4433 bool found_sid = false;
4434
4435 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4436
4437 r.in.handle = lsa_handle;
4438 r.in.num_entries = 0x1000;
4439 r.in.resume_handle = &resume_handle;
4440 r.out.sids = &lsa_sid_array;
4441 r.out.resume_handle = &resume_handle;
4442
4443 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4444 "lsa_EnumAccounts failed");
4445 torture_assert_ntstatus_ok(tctx, r.out.result,
4446 "Failed to enum accounts");
4447
4448 for (i=0; i < lsa_sid_array.num_sids; i++) {
4449 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4450 found_sid = true;
4451 }
4452 }
4453
4454 torture_assert(tctx, found_sid,
4455 "failed to list privileged account");
4456 }
4457
4458 {
4459 struct lsa_EnumAccountRights r;
4460 struct lsa_RightSet user_rights;
4461
4462 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4463
4464 r.in.handle = lsa_handle;
4465 r.in.sid = user_sid;
4466 r.out.rights = &user_rights;
4467
4468 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4469 "lsa_EnumAccountRights failed");
4470 torture_assert_ntstatus_ok(tctx, r.out.result,
4471 "Failed to enum rights for account");
4472
4473 if (user_rights.count < 1) {
4474 torture_warning(tctx, "failed to find newly added rights");
4475 return false;
4476 }
4477 }
4478
4479 {
4480 struct lsa_OpenAccount r;
4481
4482 torture_comment(tctx, "Testing LSA OpenAccount\n");
4483
4484 r.in.handle = lsa_handle;
4485 r.in.sid = user_sid;
4486 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4487 r.out.acct_handle = &lsa_acct_handle;
4488
4489 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4490 "lsa_OpenAccount failed");
4491 torture_assert_ntstatus_ok(tctx, r.out.result,
4492 "Failed to open lsa account");
4493 }
4494
4495 {
4496 struct lsa_GetSystemAccessAccount r;
4497 uint32_t access_mask;
4498
4499 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4500
4501 r.in.handle = &lsa_acct_handle;
4502 r.out.access_mask = &access_mask;
4503
4504 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4505 "lsa_GetSystemAccessAccount failed");
4506 torture_assert_ntstatus_ok(tctx, r.out.result,
4507 "Failed to get lsa system access account");
4508 }
4509
4510 {
4511 struct lsa_DeleteObject r;
4512
4513 torture_comment(tctx, "Testing LSA DeleteObject\n");
4514
4515 r.in.handle = &lsa_acct_handle;
4516 r.out.handle = &lsa_acct_handle;
4517
4518 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4519 "lsa_DeleteObject failed");
4520 torture_assert_ntstatus_ok(tctx, r.out.result,
4521 "Failed to delete object");
4522 }
4523
4524 {
4525 struct lsa_EnumAccounts r;
4526 uint32_t resume_handle = 0;
4527 struct lsa_SidArray lsa_sid_array;
4528 int i;
4529 bool found_sid = false;
4530
4531 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4532
4533 r.in.handle = lsa_handle;
4534 r.in.num_entries = 0x1000;
4535 r.in.resume_handle = &resume_handle;
4536 r.out.sids = &lsa_sid_array;
4537 r.out.resume_handle = &resume_handle;
4538
4539 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4540 "lsa_EnumAccounts failed");
4541 torture_assert_ntstatus_ok(tctx, r.out.result,
4542 "Failed to enum accounts");
4543
4544 for (i=0; i < lsa_sid_array.num_sids; i++) {
4545 if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4546 found_sid = true;
4547 }
4548 }
4549
4550 torture_assert(tctx, !found_sid,
4551 "should not have listed privileged account");
4552 }
4553
4554 {
4555 struct lsa_EnumAccountRights r;
4556 struct lsa_RightSet user_rights;
4557
4558 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4559
4560 r.in.handle = lsa_handle;
4561 r.in.sid = user_sid;
4562 r.out.rights = &user_rights;
4563
4564 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4565 "lsa_EnumAccountRights failed");
4566 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4567 "Failed to enum rights for account");
4568 }
4569
4570 return ret;
4571}
4572
4573static bool test_user_ops(struct dcerpc_pipe *p,
4574 struct torture_context *tctx,
4575 struct policy_handle *user_handle,
4576 struct policy_handle *domain_handle,
4577 const struct dom_sid *domain_sid,
4578 uint32_t base_acct_flags,
4579 const char *base_acct_name, enum torture_samr_choice which_ops,
4580 struct cli_credentials *machine_credentials)
4581{
4582 char *password = NULL;
4583 struct samr_QueryUserInfo q;
4584 union samr_UserInfo *info;
4585 NTSTATUS status;
4586 struct dcerpc_binding_handle *b = p->binding_handle;
4587
4588 bool ret = true;
4589 int i;
4590 uint32_t rid;
4591 const uint32_t password_fields[] = {
4592 SAMR_FIELD_NT_PASSWORD_PRESENT,
4593 SAMR_FIELD_LM_PASSWORD_PRESENT,
4594 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4595 0
4596 };
4597
4598 status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4599 if (!NT_STATUS_IS_OK(status)) {
4600 ret = false;
4601 }
4602
4603 switch (which_ops) {
4604 case TORTURE_SAMR_USER_ATTRIBUTES:
4605 if (!test_QuerySecurity(b, tctx, user_handle)) {
4606 ret = false;
4607 }
4608
4609 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4610 ret = false;
4611 }
4612
4613 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4614 ret = false;
4615 }
4616
4617 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4618 base_acct_name)) {
4619 ret = false;
4620 }
4621
4622 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4623 ret = false;
4624 }
4625
4626 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4627 ret = false;
4628 }
4629
4630 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4631 ret = false;
4632 }
4633 break;
4634 case TORTURE_SAMR_PASSWORDS:
4635 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4636 char simple_pass[9];
4637 char *v = generate_random_str(tctx, 1);
4638
4639 ZERO_STRUCT(simple_pass);
4640 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4641
4642 torture_comment(tctx, "Testing machine account password policy rules\n");
4643
4644 /* Workstation trust accounts don't seem to need to honour password quality policy */
4645 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4646 ret = false;
4647 }
4648
4649 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4650 ret = false;
4651 }
4652
4653 /* reset again, to allow another 'user' password change */
4654 if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4655 ret = false;
4656 }
4657
4658 /* Try a 'short' password */
4659 if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4660 ret = false;
4661 }
4662
4663 /* Try a compleatly random password */
4664 if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4665 ret = false;
4666 }
4667 }
4668
4669 for (i = 0; password_fields[i]; i++) {
4670 if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4671 ret = false;
4672 }
4673
4674 /* check it was set right */
4675 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4676 ret = false;
4677 }
4678 }
4679
4680 for (i = 0; password_fields[i]; i++) {
4681 if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4682 ret = false;
4683 }
4684
4685 /* check it was set right */
4686 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4687 ret = false;
4688 }
4689 }
4690
4691 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4692 ret = false;
4693 }
4694
4695 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4696 ret = false;
4697 }
4698
4699 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4700 ret = false;
4701 }
4702
4703 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4704 ret = false;
4705 }
4706
4707 for (i = 0; password_fields[i]; i++) {
4708
4709 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4710 /* we need to skip as that would break
4711 * the ChangePasswordUser3 verify */
4712 continue;
4713 }
4714
4715 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4716 ret = false;
4717 }
4718
4719 /* check it was set right */
4720 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4721 ret = false;
4722 }
4723 }
4724
4725 q.in.user_handle = user_handle;
4726 q.in.level = 5;
4727 q.out.info = &info;
4728
4729 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4730 "QueryUserInfo failed");
4731 if (!NT_STATUS_IS_OK(q.out.result)) {
4732 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4733 q.in.level, nt_errstr(q.out.result));
4734 ret = false;
4735 } else {
4736 uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4737 if ((info->info5.acct_flags) != expected_flags) {
4738 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4739 info->info5.acct_flags,
4740 expected_flags);
4741 /* FIXME: GD */
4742 if (!torture_setting_bool(tctx, "samba3", false)) {
4743 ret = false;
4744 }
4745 }
4746 if (info->info5.rid != rid) {
4747 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4748 info->info5.rid, rid);
4749
4750 }
4751 }
4752
4753 break;
4754
4755 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4756
4757 /* test last password change timestamp behaviour */
4758 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4759 base_acct_name,
4760 user_handle, &password,
4761 machine_credentials)) {
4762 ret = false;
4763 }
4764
4765 if (ret == true) {
4766 torture_comment(tctx, "pwdLastSet test succeeded\n");
4767 } else {
4768 torture_warning(tctx, "pwdLastSet test failed\n");
4769 }
4770
4771 break;
4772
4773 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4774
4775 /* test bad pwd count change behaviour */
4776 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4777 base_acct_name,
4778 domain_handle,
4779 user_handle, &password,
4780 machine_credentials)) {
4781 ret = false;
4782 }
4783
4784 if (ret == true) {
4785 torture_comment(tctx, "badPwdCount test succeeded\n");
4786 } else {
4787 torture_warning(tctx, "badPwdCount test failed\n");
4788 }
4789
4790 break;
4791
4792 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4793
4794 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4795 base_acct_name,
4796 domain_handle,
4797 user_handle, &password,
4798 machine_credentials))
4799 {
4800 ret = false;
4801 }
4802
4803 if (ret == true) {
4804 torture_comment(tctx, "lockout test succeeded\n");
4805 } else {
4806 torture_warning(tctx, "lockout test failed\n");
4807 }
4808
4809 break;
4810
4811
4812 case TORTURE_SAMR_USER_PRIVILEGES: {
4813
4814 struct dcerpc_pipe *lp;
4815 struct policy_handle *lsa_handle;
4816 struct dcerpc_binding_handle *lb;
4817
4818 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4819 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4820 lb = lp->binding_handle;
4821
4822 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4823 ret = false;
4824 }
4825
4826 if (!test_DeleteUser_with_privs(p, lp, tctx,
4827 domain_handle, lsa_handle, user_handle,
4828 domain_sid, rid,
4829 machine_credentials)) {
4830 ret = false;
4831 }
4832
4833 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4834 ret = false;
4835 }
4836
4837 if (!ret) {
4838 torture_warning(tctx, "privileged user delete test failed\n");
4839 }
4840
4841 break;
4842 }
4843 case TORTURE_SAMR_OTHER:
4844 case TORTURE_SAMR_MANY_ACCOUNTS:
4845 case TORTURE_SAMR_MANY_GROUPS:
4846 case TORTURE_SAMR_MANY_ALIASES:
4847 /* We just need the account to exist */
4848 break;
4849 }
4850 return ret;
4851}
4852
4853static bool test_alias_ops(struct dcerpc_binding_handle *b,
4854 struct torture_context *tctx,
4855 struct policy_handle *alias_handle,
4856 const struct dom_sid *domain_sid)
4857{
4858 bool ret = true;
4859
4860 if (!torture_setting_bool(tctx, "samba3", false)) {
4861 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4862 ret = false;
4863 }
4864 }
4865
4866 if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4867 ret = false;
4868 }
4869
4870 if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4871 ret = false;
4872 }
4873
4874 if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4875 ret = false;
4876 }
4877
4878 if (torture_setting_bool(tctx, "samba3", false) ||
4879 torture_setting_bool(tctx, "samba4", false)) {
4880 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
4881 return ret;
4882 }
4883
4884 if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
4885 ret = false;
4886 }
4887
4888 return ret;
4889}
4890
4891
4892static bool test_DeleteUser(struct dcerpc_binding_handle *b,
4893 struct torture_context *tctx,
4894 struct policy_handle *user_handle)
4895{
4896 struct samr_DeleteUser d;
4897 torture_comment(tctx, "Testing DeleteUser\n");
4898
4899 d.in.user_handle = user_handle;
4900 d.out.user_handle = user_handle;
4901
4902 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4903 "DeleteUser failed");
4904 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
4905
4906 return true;
4907}
4908
4909bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
4910 struct torture_context *tctx,
4911 struct policy_handle *handle, const char *name)
4912{
4913 NTSTATUS status;
4914 struct samr_DeleteUser d;
4915 struct policy_handle user_handle;
4916 uint32_t rid;
4917
4918 status = test_LookupName(b, tctx, handle, name, &rid);
4919 if (!NT_STATUS_IS_OK(status)) {
4920 goto failed;
4921 }
4922
4923 status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
4924 if (!NT_STATUS_IS_OK(status)) {
4925 goto failed;
4926 }
4927
4928 d.in.user_handle = &user_handle;
4929 d.out.user_handle = &user_handle;
4930 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
4931 "DeleteUser failed");
4932 if (!NT_STATUS_IS_OK(d.out.result)) {
4933 status = d.out.result;
4934 goto failed;
4935 }
4936
4937 return true;
4938
4939failed:
4940 torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
4941 return false;
4942}
4943
4944
4945static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
4946 struct torture_context *tctx,
4947 struct policy_handle *handle, const char *name)
4948{
4949 NTSTATUS status;
4950 struct samr_OpenGroup r;
4951 struct samr_DeleteDomainGroup d;
4952 struct policy_handle group_handle;
4953 uint32_t rid;
4954
4955 status = test_LookupName(b, tctx, handle, name, &rid);
4956 if (!NT_STATUS_IS_OK(status)) {
4957 goto failed;
4958 }
4959
4960 r.in.domain_handle = handle;
4961 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4962 r.in.rid = rid;
4963 r.out.group_handle = &group_handle;
4964 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
4965 "OpenGroup failed");
4966 if (!NT_STATUS_IS_OK(r.out.result)) {
4967 status = r.out.result;
4968 goto failed;
4969 }
4970
4971 d.in.group_handle = &group_handle;
4972 d.out.group_handle = &group_handle;
4973 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
4974 "DeleteDomainGroup failed");
4975 if (!NT_STATUS_IS_OK(d.out.result)) {
4976 status = d.out.result;
4977 goto failed;
4978 }
4979
4980 return true;
4981
4982failed:
4983 torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
4984 return false;
4985}
4986
4987
4988static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
4989 struct torture_context *tctx,
4990 struct policy_handle *domain_handle,
4991 const char *name)
4992{
4993 NTSTATUS status;
4994 struct samr_OpenAlias r;
4995 struct samr_DeleteDomAlias d;
4996 struct policy_handle alias_handle;
4997 uint32_t rid;
4998
4999 torture_comment(tctx, "Testing DeleteAlias_byname\n");
5000
5001 status = test_LookupName(b, tctx, domain_handle, name, &rid);
5002 if (!NT_STATUS_IS_OK(status)) {
5003 goto failed;
5004 }
5005
5006 r.in.domain_handle = domain_handle;
5007 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5008 r.in.rid = rid;
5009 r.out.alias_handle = &alias_handle;
5010 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5011 "OpenAlias failed");
5012 if (!NT_STATUS_IS_OK(r.out.result)) {
5013 status = r.out.result;
5014 goto failed;
5015 }
5016
5017 d.in.alias_handle = &alias_handle;
5018 d.out.alias_handle = &alias_handle;
5019 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5020 "DeleteDomAlias failed");
5021 if (!NT_STATUS_IS_OK(d.out.result)) {
5022 status = d.out.result;
5023 goto failed;
5024 }
5025
5026 return true;
5027
5028failed:
5029 torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5030 return false;
5031}
5032
5033static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5034 struct torture_context *tctx,
5035 struct policy_handle *alias_handle)
5036{
5037 struct samr_DeleteDomAlias d;
5038 bool ret = true;
5039
5040 torture_comment(tctx, "Testing DeleteAlias\n");
5041
5042 d.in.alias_handle = alias_handle;
5043 d.out.alias_handle = alias_handle;
5044
5045 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5046 "DeleteDomAlias failed");
5047 if (!NT_STATUS_IS_OK(d.out.result)) {
5048 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5049 ret = false;
5050 }
5051
5052 return ret;
5053}
5054
5055static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5056 struct torture_context *tctx,
5057 struct policy_handle *domain_handle,
5058 const char *alias_name,
5059 struct policy_handle *alias_handle,
5060 const struct dom_sid *domain_sid,
5061 bool test_alias)
5062{
5063 struct samr_CreateDomAlias r;
5064 struct lsa_String name;
5065 uint32_t rid;
5066 bool ret = true;
5067
5068 init_lsa_String(&name, alias_name);
5069 r.in.domain_handle = domain_handle;
5070 r.in.alias_name = &name;
5071 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5072 r.out.alias_handle = alias_handle;
5073 r.out.rid = &rid;
5074
5075 torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5076
5077 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5078 "CreateDomAlias failed");
5079
5080 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5081 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5082 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5083 return true;
5084 } else {
5085 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5086 nt_errstr(r.out.result));
5087 return false;
5088 }
5089 }
5090
5091 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5092 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5093 return false;
5094 }
5095 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5096 "CreateDomAlias failed");
5097 }
5098
5099 if (!NT_STATUS_IS_OK(r.out.result)) {
5100 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5101 return false;
5102 }
5103
5104 if (!test_alias) {
5105 return ret;
5106 }
5107
5108 if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5109 ret = false;
5110 }
5111
5112 return ret;
5113}
5114
5115static bool test_ChangePassword(struct dcerpc_pipe *p,
5116 struct torture_context *tctx,
5117 const char *acct_name,
5118 struct policy_handle *domain_handle, char **password)
5119{
5120 bool ret = true;
5121 struct dcerpc_binding_handle *b = p->binding_handle;
5122
5123 if (!*password) {
5124 return false;
5125 }
5126
5127 if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5128 ret = false;
5129 }
5130
5131 if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5132 ret = false;
5133 }
5134
5135 if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5136 ret = false;
5137 }
5138
5139 /* test what happens when setting the old password again */
5140 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5141 ret = false;
5142 }
5143
5144 {
5145 char simple_pass[9];
5146 char *v = generate_random_str(tctx, 1);
5147
5148 ZERO_STRUCT(simple_pass);
5149 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5150
5151 /* test what happens when picking a simple password */
5152 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5153 ret = false;
5154 }
5155 }
5156
5157 /* set samr_SetDomainInfo level 1 with min_length 5 */
5158 {
5159 struct samr_QueryDomainInfo r;
5160 union samr_DomainInfo *info = NULL;
5161 struct samr_SetDomainInfo s;
5162 uint16_t len_old, len;
5163 uint32_t pwd_prop_old;
5164 int64_t min_pwd_age_old;
5165
5166 len = 5;
5167
5168 r.in.domain_handle = domain_handle;
5169 r.in.level = 1;
5170 r.out.info = &info;
5171
5172 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5173 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5174 "QueryDomainInfo failed");
5175 if (!NT_STATUS_IS_OK(r.out.result)) {
5176 return false;
5177 }
5178
5179 s.in.domain_handle = domain_handle;
5180 s.in.level = 1;
5181 s.in.info = info;
5182
5183 /* remember the old min length, so we can reset it */
5184 len_old = s.in.info->info1.min_password_length;
5185 s.in.info->info1.min_password_length = len;
5186 pwd_prop_old = s.in.info->info1.password_properties;
5187 /* turn off password complexity checks for this test */
5188 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5189
5190 min_pwd_age_old = s.in.info->info1.min_password_age;
5191 s.in.info->info1.min_password_age = 0;
5192
5193 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5194 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5195 "SetDomainInfo failed");
5196 if (!NT_STATUS_IS_OK(s.out.result)) {
5197 return false;
5198 }
5199
5200 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5201
5202 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5203 ret = false;
5204 }
5205
5206 s.in.info->info1.min_password_length = len_old;
5207 s.in.info->info1.password_properties = pwd_prop_old;
5208 s.in.info->info1.min_password_age = min_pwd_age_old;
5209
5210 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5211 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5212 "SetDomainInfo failed");
5213 if (!NT_STATUS_IS_OK(s.out.result)) {
5214 return false;
5215 }
5216
5217 }
5218
5219 {
5220 struct samr_OpenUser r;
5221 struct samr_QueryUserInfo q;
5222 union samr_UserInfo *info;
5223 struct samr_LookupNames n;
5224 struct policy_handle user_handle;
5225 struct samr_Ids rids, types;
5226
5227 n.in.domain_handle = domain_handle;
5228 n.in.num_names = 1;
5229 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5230 n.in.names[0].string = acct_name;
5231 n.out.rids = &rids;
5232 n.out.types = &types;
5233
5234 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5235 "LookupNames failed");
5236 if (!NT_STATUS_IS_OK(n.out.result)) {
5237 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5238 return false;
5239 }
5240
5241 r.in.domain_handle = domain_handle;
5242 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5243 r.in.rid = n.out.rids->ids[0];
5244 r.out.user_handle = &user_handle;
5245
5246 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5247 "OpenUser failed");
5248 if (!NT_STATUS_IS_OK(r.out.result)) {
5249 torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5250 return false;
5251 }
5252
5253 q.in.user_handle = &user_handle;
5254 q.in.level = 5;
5255 q.out.info = &info;
5256
5257 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5258 "QueryUserInfo failed");
5259 if (!NT_STATUS_IS_OK(q.out.result)) {
5260 torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5261 return false;
5262 }
5263
5264 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5265
5266 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5267 info->info5.last_password_change, true)) {
5268 ret = false;
5269 }
5270 }
5271
5272 /* we change passwords twice - this has the effect of verifying
5273 they were changed correctly for the final call */
5274 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5275 ret = false;
5276 }
5277
5278 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5279 ret = false;
5280 }
5281
5282 return ret;
5283}
5284
5285static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5286 struct policy_handle *domain_handle,
5287 const char *user_name,
5288 struct policy_handle *user_handle_out,
5289 struct dom_sid *domain_sid,
5290 enum torture_samr_choice which_ops,
5291 struct cli_credentials *machine_credentials,
5292 bool test_user)
5293{
5294
5295 TALLOC_CTX *user_ctx;
5296
5297 struct samr_CreateUser r;
5298 struct samr_QueryUserInfo q;
5299 union samr_UserInfo *info;
5300 struct samr_DeleteUser d;
5301 uint32_t rid;
5302
5303 /* This call creates a 'normal' account - check that it really does */
5304 const uint32_t acct_flags = ACB_NORMAL;
5305 struct lsa_String name;
5306 bool ret = true;
5307 struct dcerpc_binding_handle *b = p->binding_handle;
5308
5309 struct policy_handle user_handle;
5310 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5311 init_lsa_String(&name, user_name);
5312
5313 r.in.domain_handle = domain_handle;
5314 r.in.account_name = &name;
5315 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5316 r.out.user_handle = &user_handle;
5317 r.out.rid = &rid;
5318
5319 torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5320
5321 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5322 "CreateUser failed");
5323
5324 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5325 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5326 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5327 return true;
5328 } else {
5329 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5330 nt_errstr(r.out.result));
5331 return false;
5332 }
5333 }
5334
5335 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5336 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5337 talloc_free(user_ctx);
5338 return false;
5339 }
5340 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5341 "CreateUser failed");
5342 }
5343
5344 if (!NT_STATUS_IS_OK(r.out.result)) {
5345 talloc_free(user_ctx);
5346 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5347 return false;
5348 }
5349
5350 if (!test_user) {
5351 if (user_handle_out) {
5352 *user_handle_out = user_handle;
5353 }
5354 return ret;
5355 }
5356
5357 {
5358 q.in.user_handle = &user_handle;
5359 q.in.level = 16;
5360 q.out.info = &info;
5361
5362 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5363 "QueryUserInfo failed");
5364 if (!NT_STATUS_IS_OK(q.out.result)) {
5365 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5366 q.in.level, nt_errstr(q.out.result));
5367 ret = false;
5368 } else {
5369 if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5370 torture_warning(tctx, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5371 info->info16.acct_flags,
5372 acct_flags);
5373 ret = false;
5374 }
5375 }
5376
5377 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5378 domain_sid, acct_flags, name.string, which_ops,
5379 machine_credentials)) {
5380 ret = false;
5381 }
5382
5383 if (user_handle_out) {
5384 *user_handle_out = user_handle;
5385 } else {
5386 torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5387
5388 d.in.user_handle = &user_handle;
5389 d.out.user_handle = &user_handle;
5390
5391 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5392 "DeleteUser failed");
5393 if (!NT_STATUS_IS_OK(d.out.result)) {
5394 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5395 ret = false;
5396 }
5397 }
5398
5399 }
5400
5401 talloc_free(user_ctx);
5402
5403 return ret;
5404}
5405
5406
5407static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5408 struct policy_handle *domain_handle,
5409 struct dom_sid *domain_sid,
5410 enum torture_samr_choice which_ops,
5411 struct cli_credentials *machine_credentials)
5412{
5413 struct samr_CreateUser2 r;
5414 struct samr_QueryUserInfo q;
5415 union samr_UserInfo *info;
5416 struct samr_DeleteUser d;
5417 struct policy_handle user_handle;
5418 uint32_t rid;
5419 struct lsa_String name;
5420 bool ret = true;
5421 int i;
5422 struct dcerpc_binding_handle *b = p->binding_handle;
5423
5424 struct {
5425 uint32_t acct_flags;
5426 const char *account_name;
5427 NTSTATUS nt_status;
5428 } account_types[] = {
5429 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5430 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5431 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5432 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5433 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5434 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5435 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5436 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5437 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5438 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5439 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5440 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5441 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5442 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5443 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5444 };
5445
5446 for (i = 0; account_types[i].account_name; i++) {
5447 TALLOC_CTX *user_ctx;
5448 uint32_t acct_flags = account_types[i].acct_flags;
5449 uint32_t access_granted;
5450 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5451 init_lsa_String(&name, account_types[i].account_name);
5452
5453 r.in.domain_handle = domain_handle;
5454 r.in.account_name = &name;
5455 r.in.acct_flags = acct_flags;
5456 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5457 r.out.user_handle = &user_handle;
5458 r.out.access_granted = &access_granted;
5459 r.out.rid = &rid;
5460
5461 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5462
5463 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5464 "CreateUser2 failed");
5465
5466 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5467 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5468 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5469 continue;
5470 } else {
5471 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5472 nt_errstr(r.out.result));
5473 ret = false;
5474 continue;
5475 }
5476 }
5477
5478 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5479 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5480 talloc_free(user_ctx);
5481 ret = false;
5482 continue;
5483 }
5484 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5485 "CreateUser2 failed");
5486
5487 }
5488 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5489 torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5490 nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5491 ret = false;
5492 }
5493
5494 if (NT_STATUS_IS_OK(r.out.result)) {
5495 q.in.user_handle = &user_handle;
5496 q.in.level = 5;
5497 q.out.info = &info;
5498
5499 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5500 "QueryUserInfo failed");
5501 if (!NT_STATUS_IS_OK(q.out.result)) {
5502 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5503 q.in.level, nt_errstr(q.out.result));
5504 ret = false;
5505 } else {
5506 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5507 if (acct_flags == ACB_NORMAL) {
5508 expected_flags |= ACB_PW_EXPIRED;
5509 }
5510 if ((info->info5.acct_flags) != expected_flags) {
5511 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5512 info->info5.acct_flags,
5513 expected_flags);
5514 ret = false;
5515 }
5516 switch (acct_flags) {
5517 case ACB_SVRTRUST:
5518 if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5519 torture_warning(tctx, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5520 DOMAIN_RID_DCS, info->info5.primary_gid);
5521 ret = false;
5522 }
5523 break;
5524 case ACB_WSTRUST:
5525 if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5526 torture_warning(tctx, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5527 DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5528 ret = false;
5529 }
5530 break;
5531 case ACB_NORMAL:
5532 if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5533 torture_warning(tctx, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5534 DOMAIN_RID_USERS, info->info5.primary_gid);
5535 ret = false;
5536 }
5537 break;
5538 }
5539 }
5540
5541 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5542 domain_sid, acct_flags, name.string, which_ops,
5543 machine_credentials)) {
5544 ret = false;
5545 }
5546
5547 if (!policy_handle_empty(&user_handle)) {
5548 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5549
5550 d.in.user_handle = &user_handle;
5551 d.out.user_handle = &user_handle;
5552
5553 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5554 "DeleteUser failed");
5555 if (!NT_STATUS_IS_OK(d.out.result)) {
5556 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5557 ret = false;
5558 }
5559 }
5560 }
5561 talloc_free(user_ctx);
5562 }
5563
5564 return ret;
5565}
5566
5567static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5568 struct torture_context *tctx,
5569 struct policy_handle *handle)
5570{
5571 struct samr_QueryAliasInfo r;
5572 union samr_AliasInfo *info;
5573 uint16_t levels[] = {1, 2, 3};
5574 int i;
5575 bool ret = true;
5576
5577 for (i=0;i<ARRAY_SIZE(levels);i++) {
5578 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5579
5580 r.in.alias_handle = handle;
5581 r.in.level = levels[i];
5582 r.out.info = &info;
5583
5584 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5585 "QueryAliasInfo failed");
5586 if (!NT_STATUS_IS_OK(r.out.result)) {
5587 torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5588 levels[i], nt_errstr(r.out.result));
5589 ret = false;
5590 }
5591 }
5592
5593 return ret;
5594}
5595
5596static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5597 struct torture_context *tctx,
5598 struct policy_handle *handle)
5599{
5600 struct samr_QueryGroupInfo r;
5601 union samr_GroupInfo *info;
5602 uint16_t levels[] = {1, 2, 3, 4, 5};
5603 int i;
5604 bool ret = true;
5605
5606 for (i=0;i<ARRAY_SIZE(levels);i++) {
5607 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5608
5609 r.in.group_handle = handle;
5610 r.in.level = levels[i];
5611 r.out.info = &info;
5612
5613 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5614 "QueryGroupInfo failed");
5615 if (!NT_STATUS_IS_OK(r.out.result)) {
5616 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5617 levels[i], nt_errstr(r.out.result));
5618 ret = false;
5619 }
5620 }
5621
5622 return ret;
5623}
5624
5625static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5626 struct torture_context *tctx,
5627 struct policy_handle *handle)
5628{
5629 struct samr_QueryGroupMember r;
5630 struct samr_RidAttrArray *rids = NULL;
5631 bool ret = true;
5632
5633 torture_comment(tctx, "Testing QueryGroupMember\n");
5634
5635 r.in.group_handle = handle;
5636 r.out.rids = &rids;
5637
5638 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5639 "QueryGroupMember failed");
5640 if (!NT_STATUS_IS_OK(r.out.result)) {
5641 torture_warning(tctx, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
5642 ret = false;
5643 }
5644
5645 return ret;
5646}
5647
5648
5649static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5650 struct torture_context *tctx,
5651 struct policy_handle *handle)
5652{
5653 struct samr_QueryGroupInfo r;
5654 union samr_GroupInfo *info;
5655 struct samr_SetGroupInfo s;
5656 uint16_t levels[] = {1, 2, 3, 4};
5657 uint16_t set_ok[] = {0, 1, 1, 1};
5658 int i;
5659 bool ret = true;
5660
5661 for (i=0;i<ARRAY_SIZE(levels);i++) {
5662 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5663
5664 r.in.group_handle = handle;
5665 r.in.level = levels[i];
5666 r.out.info = &info;
5667
5668 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5669 "QueryGroupInfo failed");
5670 if (!NT_STATUS_IS_OK(r.out.result)) {
5671 torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5672 levels[i], nt_errstr(r.out.result));
5673 ret = false;
5674 }
5675
5676 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5677
5678 s.in.group_handle = handle;
5679 s.in.level = levels[i];
5680 s.in.info = *r.out.info;
5681
5682#if 0
5683 /* disabled this, as it changes the name only from the point of view of samr,
5684 but leaves the name from the point of view of w2k3 internals (and ldap). This means
5685 the name is still reserved, so creating the old name fails, but deleting by the old name
5686 also fails */
5687 if (s.in.level == 2) {
5688 init_lsa_String(&s.in.info->string, "NewName");
5689 }
5690#endif
5691
5692 if (s.in.level == 4) {
5693 init_lsa_String(&s.in.info->description, "test description");
5694 }
5695
5696 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5697 "SetGroupInfo failed");
5698 if (set_ok[i]) {
5699 if (!NT_STATUS_IS_OK(s.out.result)) {
5700 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5701 r.in.level, nt_errstr(s.out.result));
5702 ret = false;
5703 continue;
5704 }
5705 } else {
5706 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5707 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5708 r.in.level, nt_errstr(s.out.result));
5709 ret = false;
5710 continue;
5711 }
5712 }
5713 }
5714
5715 return ret;
5716}
5717
5718static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5719 struct torture_context *tctx,
5720 struct policy_handle *handle)
5721{
5722 struct samr_QueryUserInfo r;
5723 union samr_UserInfo *info;
5724 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5725 11, 12, 13, 14, 16, 17, 20, 21};
5726 int i;
5727 bool ret = true;
5728
5729 for (i=0;i<ARRAY_SIZE(levels);i++) {
5730 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5731
5732 r.in.user_handle = handle;
5733 r.in.level = levels[i];
5734 r.out.info = &info;
5735
5736 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5737 "QueryUserInfo failed");
5738 if (!NT_STATUS_IS_OK(r.out.result)) {
5739 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5740 levels[i], nt_errstr(r.out.result));
5741 ret = false;
5742 }
5743 }
5744
5745 return ret;
5746}
5747
5748static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5749 struct torture_context *tctx,
5750 struct policy_handle *handle)
5751{
5752 struct samr_QueryUserInfo2 r;
5753 union samr_UserInfo *info;
5754 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5755 11, 12, 13, 14, 16, 17, 20, 21};
5756 int i;
5757 bool ret = true;
5758
5759 for (i=0;i<ARRAY_SIZE(levels);i++) {
5760 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5761
5762 r.in.user_handle = handle;
5763 r.in.level = levels[i];
5764 r.out.info = &info;
5765
5766 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5767 "QueryUserInfo2 failed");
5768 if (!NT_STATUS_IS_OK(r.out.result)) {
5769 torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5770 levels[i], nt_errstr(r.out.result));
5771 ret = false;
5772 }
5773 }
5774
5775 return ret;
5776}
5777
5778static bool test_OpenUser(struct dcerpc_binding_handle *b,
5779 struct torture_context *tctx,
5780 struct policy_handle *handle, uint32_t rid)
5781{
5782 struct samr_OpenUser r;
5783 struct policy_handle user_handle;
5784 bool ret = true;
5785
5786 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5787
5788 r.in.domain_handle = handle;
5789 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5790 r.in.rid = rid;
5791 r.out.user_handle = &user_handle;
5792
5793 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5794 "OpenUser failed");
5795 if (!NT_STATUS_IS_OK(r.out.result)) {
5796 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5797 return false;
5798 }
5799
5800 if (!test_QuerySecurity(b, tctx, &user_handle)) {
5801 ret = false;
5802 }
5803
5804 if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5805 ret = false;
5806 }
5807
5808 if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5809 ret = false;
5810 }
5811
5812 if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5813 ret = false;
5814 }
5815
5816 if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5817 ret = false;
5818 }
5819
5820 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5821 ret = false;
5822 }
5823
5824 return ret;
5825}
5826
5827static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5828 struct torture_context *tctx,
5829 struct policy_handle *handle, uint32_t rid)
5830{
5831 struct samr_OpenGroup r;
5832 struct policy_handle group_handle;
5833 bool ret = true;
5834
5835 torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5836
5837 r.in.domain_handle = handle;
5838 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5839 r.in.rid = rid;
5840 r.out.group_handle = &group_handle;
5841
5842 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5843 "OpenGroup failed");
5844 if (!NT_STATUS_IS_OK(r.out.result)) {
5845 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5846 return false;
5847 }
5848
5849 if (!torture_setting_bool(tctx, "samba3", false)) {
5850 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5851 ret = false;
5852 }
5853 }
5854
5855 if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5856 ret = false;
5857 }
5858
5859 if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5860 ret = false;
5861 }
5862
5863 if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5864 ret = false;
5865 }
5866
5867 return ret;
5868}
5869
5870static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5871 struct torture_context *tctx,
5872 struct policy_handle *handle, uint32_t rid)
5873{
5874 struct samr_OpenAlias r;
5875 struct policy_handle alias_handle;
5876 bool ret = true;
5877
5878 torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5879
5880 r.in.domain_handle = handle;
5881 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5882 r.in.rid = rid;
5883 r.out.alias_handle = &alias_handle;
5884
5885 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5886 "OpenAlias failed");
5887 if (!NT_STATUS_IS_OK(r.out.result)) {
5888 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5889 return false;
5890 }
5891
5892 if (!torture_setting_bool(tctx, "samba3", false)) {
5893 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
5894 ret = false;
5895 }
5896 }
5897
5898 if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
5899 ret = false;
5900 }
5901
5902 if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
5903 ret = false;
5904 }
5905
5906 if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
5907 ret = false;
5908 }
5909
5910 return ret;
5911}
5912
5913static bool check_mask(struct dcerpc_binding_handle *b,
5914 struct torture_context *tctx,
5915 struct policy_handle *handle, uint32_t rid,
5916 uint32_t acct_flag_mask)
5917{
5918 struct samr_OpenUser r;
5919 struct samr_QueryUserInfo q;
5920 union samr_UserInfo *info;
5921 struct policy_handle user_handle;
5922 bool ret = true;
5923
5924 torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5925
5926 r.in.domain_handle = handle;
5927 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5928 r.in.rid = rid;
5929 r.out.user_handle = &user_handle;
5930
5931 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5932 "OpenUser failed");
5933 if (!NT_STATUS_IS_OK(r.out.result)) {
5934 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5935 return false;
5936 }
5937
5938 q.in.user_handle = &user_handle;
5939 q.in.level = 16;
5940 q.out.info = &info;
5941
5942 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5943 "QueryUserInfo failed");
5944 if (!NT_STATUS_IS_OK(q.out.result)) {
5945 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
5946 nt_errstr(q.out.result));
5947 ret = false;
5948 } else {
5949 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
5950 torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
5951 acct_flag_mask, info->info16.acct_flags, rid);
5952 ret = false;
5953 }
5954 }
5955
5956 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5957 ret = false;
5958 }
5959
5960 return ret;
5961}
5962
5963static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
5964 struct torture_context *tctx,
5965 struct policy_handle *handle)
5966{
5967 struct samr_EnumDomainUsers r;
5968 uint32_t mask, resume_handle=0;
5969 int i, mask_idx;
5970 bool ret = true;
5971 struct samr_LookupNames n;
5972 struct samr_LookupRids lr ;
5973 struct lsa_Strings names;
5974 struct samr_Ids rids, types;
5975 struct samr_SamArray *sam = NULL;
5976 uint32_t num_entries = 0;
5977
5978 uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
5979 ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
5980 ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
5981 ACB_PWNOEXP, 0};
5982
5983 torture_comment(tctx, "Testing EnumDomainUsers\n");
5984
5985 for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
5986 r.in.domain_handle = handle;
5987 r.in.resume_handle = &resume_handle;
5988 r.in.acct_flags = mask = masks[mask_idx];
5989 r.in.max_size = (uint32_t)-1;
5990 r.out.resume_handle = &resume_handle;
5991 r.out.num_entries = &num_entries;
5992 r.out.sam = &sam;
5993
5994 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
5995 "EnumDomainUsers failed");
5996 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
5997 !NT_STATUS_IS_OK(r.out.result)) {
5998 torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
5999 return false;
6000 }
6001
6002 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6003
6004 if (sam->count == 0) {
6005 continue;
6006 }
6007
6008 for (i=0;i<sam->count;i++) {
6009 if (mask) {
6010 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6011 ret = false;
6012 }
6013 } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6014 ret = false;
6015 }
6016 }
6017 }
6018
6019 torture_comment(tctx, "Testing LookupNames\n");
6020 n.in.domain_handle = handle;
6021 n.in.num_names = sam->count;
6022 n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6023 n.out.rids = &rids;
6024 n.out.types = &types;
6025 for (i=0;i<sam->count;i++) {
6026 n.in.names[i].string = sam->entries[i].name.string;
6027 }
6028 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6029 "LookupNames failed");
6030 if (!NT_STATUS_IS_OK(n.out.result)) {
6031 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6032 ret = false;
6033 }
6034
6035
6036 torture_comment(tctx, "Testing LookupRids\n");
6037 lr.in.domain_handle = handle;
6038 lr.in.num_rids = sam->count;
6039 lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6040 lr.out.names = &names;
6041 lr.out.types = &types;
6042 for (i=0;i<sam->count;i++) {
6043 lr.in.rids[i] = sam->entries[i].idx;
6044 }
6045 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6046 "LookupRids failed");
6047 torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6048
6049 return ret;
6050}
6051
6052/*
6053 try blasting the server with a bunch of sync requests
6054*/
6055static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6056 struct policy_handle *handle)
6057{
6058 struct samr_EnumDomainUsers r;
6059 uint32_t resume_handle=0;
6060 int i;
6061#define ASYNC_COUNT 100
6062 struct tevent_req *req[ASYNC_COUNT];
6063
6064 if (!torture_setting_bool(tctx, "dangerous", false)) {
6065 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6066 }
6067
6068 torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6069
6070 r.in.domain_handle = handle;
6071 r.in.resume_handle = &resume_handle;
6072 r.in.acct_flags = 0;
6073 r.in.max_size = (uint32_t)-1;
6074 r.out.resume_handle = &resume_handle;
6075
6076 for (i=0;i<ASYNC_COUNT;i++) {
6077 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6078 }
6079
6080 for (i=0;i<ASYNC_COUNT;i++) {
6081 tevent_req_poll(req[i], tctx->ev);
6082 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6083 talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6084 i, nt_errstr(r.out.result)));
6085 }
6086
6087 torture_comment(tctx, "%d async requests OK\n", i);
6088
6089 return true;
6090}
6091
6092static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6093 struct torture_context *tctx,
6094 struct policy_handle *handle)
6095{
6096 struct samr_EnumDomainGroups r;
6097 uint32_t resume_handle=0;
6098 struct samr_SamArray *sam = NULL;
6099 uint32_t num_entries = 0;
6100 int i;
6101 bool ret = true;
6102 bool universal_group_found = false;
6103
6104 torture_comment(tctx, "Testing EnumDomainGroups\n");
6105
6106 r.in.domain_handle = handle;
6107 r.in.resume_handle = &resume_handle;
6108 r.in.max_size = (uint32_t)-1;
6109 r.out.resume_handle = &resume_handle;
6110 r.out.num_entries = &num_entries;
6111 r.out.sam = &sam;
6112
6113 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6114 "EnumDomainGroups failed");
6115 if (!NT_STATUS_IS_OK(r.out.result)) {
6116 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6117 return false;
6118 }
6119
6120 if (!sam) {
6121 return false;
6122 }
6123
6124 for (i=0;i<sam->count;i++) {
6125 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6126 ret = false;
6127 }
6128 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6129 "Enterprise Admins") == 0)) {
6130 universal_group_found = true;
6131 }
6132 }
6133
6134 /* when we are running this on s4 we should get back at least the
6135 * "Enterprise Admins" universal group. If we don't get a group entry
6136 * at all we probably are performing the test on the builtin domain.
6137 * So ignore this case. */
6138 if (torture_setting_bool(tctx, "samba4", false)) {
6139 if ((sam->count > 0) && (!universal_group_found)) {
6140 ret = false;
6141 }
6142 }
6143
6144 return ret;
6145}
6146
6147static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6148 struct torture_context *tctx,
6149 struct policy_handle *handle)
6150{
6151 struct samr_EnumDomainAliases r;
6152 uint32_t resume_handle=0;
6153 struct samr_SamArray *sam = NULL;
6154 uint32_t num_entries = 0;
6155 int i;
6156 bool ret = true;
6157
6158 torture_comment(tctx, "Testing EnumDomainAliases\n");
6159
6160 r.in.domain_handle = handle;
6161 r.in.resume_handle = &resume_handle;
6162 r.in.max_size = (uint32_t)-1;
6163 r.out.sam = &sam;
6164 r.out.num_entries = &num_entries;
6165 r.out.resume_handle = &resume_handle;
6166
6167 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6168 "EnumDomainAliases failed");
6169 if (!NT_STATUS_IS_OK(r.out.result)) {
6170 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6171 return false;
6172 }
6173
6174 if (!sam) {
6175 return false;
6176 }
6177
6178 for (i=0;i<sam->count;i++) {
6179 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6180 ret = false;
6181 }
6182 }
6183
6184 return ret;
6185}
6186
6187static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6188 struct torture_context *tctx,
6189 struct policy_handle *handle)
6190{
6191 struct samr_GetDisplayEnumerationIndex r;
6192 bool ret = true;
6193 uint16_t levels[] = {1, 2, 3, 4, 5};
6194 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6195 struct lsa_String name;
6196 uint32_t idx = 0;
6197 int i;
6198
6199 for (i=0;i<ARRAY_SIZE(levels);i++) {
6200 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6201
6202 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6203
6204 r.in.domain_handle = handle;
6205 r.in.level = levels[i];
6206 r.in.name = &name;
6207 r.out.idx = &idx;
6208
6209 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6210 "GetDisplayEnumerationIndex failed");
6211
6212 if (ok_lvl[i] &&
6213 !NT_STATUS_IS_OK(r.out.result) &&
6214 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6215 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6216 levels[i], nt_errstr(r.out.result));
6217 ret = false;
6218 }
6219
6220 init_lsa_String(&name, "zzzzzzzz");
6221
6222 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6223 "GetDisplayEnumerationIndex failed");
6224
6225 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6226 torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6227 levels[i], nt_errstr(r.out.result));
6228 ret = false;
6229 }
6230 }
6231
6232 return ret;
6233}
6234
6235static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6236 struct torture_context *tctx,
6237 struct policy_handle *handle)
6238{
6239 struct samr_GetDisplayEnumerationIndex2 r;
6240 bool ret = true;
6241 uint16_t levels[] = {1, 2, 3, 4, 5};
6242 uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6243 struct lsa_String name;
6244 uint32_t idx = 0;
6245 int i;
6246
6247 for (i=0;i<ARRAY_SIZE(levels);i++) {
6248 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6249
6250 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6251
6252 r.in.domain_handle = handle;
6253 r.in.level = levels[i];
6254 r.in.name = &name;
6255 r.out.idx = &idx;
6256
6257 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6258 "GetDisplayEnumerationIndex2 failed");
6259 if (ok_lvl[i] &&
6260 !NT_STATUS_IS_OK(r.out.result) &&
6261 !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6262 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6263 levels[i], nt_errstr(r.out.result));
6264 ret = false;
6265 }
6266
6267 init_lsa_String(&name, "zzzzzzzz");
6268
6269 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6270 "GetDisplayEnumerationIndex2 failed");
6271 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6272 torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6273 levels[i], nt_errstr(r.out.result));
6274 ret = false;
6275 }
6276 }
6277
6278 return ret;
6279}
6280
6281#define STRING_EQUAL_QUERY(s1, s2, user) \
6282 if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6283 /* odd, but valid */ \
6284 } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6285 torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6286 #s1, user.string, s1.string, s2.string, __location__); \
6287 ret = false; \
6288 }
6289#define INT_EQUAL_QUERY(s1, s2, user) \
6290 if (s1 != s2) { \
6291 torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6292 #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6293 ret = false; \
6294 }
6295
6296static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6297 struct torture_context *tctx,
6298 struct samr_QueryDisplayInfo *querydisplayinfo,
6299 bool *seen_testuser)
6300{
6301 struct samr_OpenUser r;
6302 struct samr_QueryUserInfo q;
6303 union samr_UserInfo *info;
6304 struct policy_handle user_handle;
6305 int i, ret = true;
6306 r.in.domain_handle = querydisplayinfo->in.domain_handle;
6307 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6308 for (i = 0; ; i++) {
6309 switch (querydisplayinfo->in.level) {
6310 case 1:
6311 if (i >= querydisplayinfo->out.info->info1.count) {
6312 return ret;
6313 }
6314 r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6315 break;
6316 case 2:
6317 if (i >= querydisplayinfo->out.info->info2.count) {
6318 return ret;
6319 }
6320 r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6321 break;
6322 case 3:
6323 /* Groups */
6324 case 4:
6325 case 5:
6326 /* Not interested in validating just the account name */
6327 return true;
6328 }
6329
6330 r.out.user_handle = &user_handle;
6331
6332 switch (querydisplayinfo->in.level) {
6333 case 1:
6334 case 2:
6335 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6336 "OpenUser failed");
6337 if (!NT_STATUS_IS_OK(r.out.result)) {
6338 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6339 return false;
6340 }
6341 }
6342
6343 q.in.user_handle = &user_handle;
6344 q.in.level = 21;
6345 q.out.info = &info;
6346 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6347 "QueryUserInfo failed");
6348 if (!NT_STATUS_IS_OK(r.out.result)) {
6349 torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6350 return false;
6351 }
6352
6353 switch (querydisplayinfo->in.level) {
6354 case 1:
6355 if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6356 *seen_testuser = true;
6357 }
6358 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6359 info->info21.full_name, info->info21.account_name);
6360 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6361 info->info21.account_name, info->info21.account_name);
6362 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6363 info->info21.description, info->info21.account_name);
6364 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6365 info->info21.rid, info->info21.account_name);
6366 INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6367 info->info21.acct_flags, info->info21.account_name);
6368
6369 break;
6370 case 2:
6371 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6372 info->info21.account_name, info->info21.account_name);
6373 STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6374 info->info21.description, info->info21.account_name);
6375 INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6376 info->info21.rid, info->info21.account_name);
6377 INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6378 info->info21.acct_flags, info->info21.account_name);
6379
6380 if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6381 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6382 info->info21.account_name.string);
6383 }
6384
6385 if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6386 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6387 info->info21.account_name.string,
6388 querydisplayinfo->out.info->info2.entries[i].acct_flags,
6389 info->info21.acct_flags);
6390 return false;
6391 }
6392
6393 break;
6394 }
6395
6396 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6397 return false;
6398 }
6399 }
6400 return ret;
6401}
6402
6403static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6404 struct torture_context *tctx,
6405 struct policy_handle *handle)
6406{
6407 struct samr_QueryDisplayInfo r;
6408 struct samr_QueryDomainInfo dom_info;
6409 union samr_DomainInfo *info = NULL;
6410 bool ret = true;
6411 uint16_t levels[] = {1, 2, 3, 4, 5};
6412 int i;
6413 bool seen_testuser = false;
6414 uint32_t total_size;
6415 uint32_t returned_size;
6416 union samr_DispInfo disp_info;
6417
6418
6419 for (i=0;i<ARRAY_SIZE(levels);i++) {
6420 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6421
6422 r.in.start_idx = 0;
6423 r.out.result = STATUS_MORE_ENTRIES;
6424 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6425 r.in.domain_handle = handle;
6426 r.in.level = levels[i];
6427 r.in.max_entries = 2;
6428 r.in.buf_size = (uint32_t)-1;
6429 r.out.total_size = &total_size;
6430 r.out.returned_size = &returned_size;
6431 r.out.info = &disp_info;
6432
6433 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6434 "QueryDisplayInfo failed");
6435 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6436 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6437 levels[i], nt_errstr(r.out.result));
6438 ret = false;
6439 }
6440 switch (r.in.level) {
6441 case 1:
6442 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6443 ret = false;
6444 }
6445 r.in.start_idx += r.out.info->info1.count;
6446 break;
6447 case 2:
6448 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6449 ret = false;
6450 }
6451 r.in.start_idx += r.out.info->info2.count;
6452 break;
6453 case 3:
6454 r.in.start_idx += r.out.info->info3.count;
6455 break;
6456 case 4:
6457 r.in.start_idx += r.out.info->info4.count;
6458 break;
6459 case 5:
6460 r.in.start_idx += r.out.info->info5.count;
6461 break;
6462 }
6463 }
6464 dom_info.in.domain_handle = handle;
6465 dom_info.in.level = 2;
6466 dom_info.out.info = &info;
6467
6468 /* Check number of users returned is correct */
6469 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6470 "QueryDomainInfo failed");
6471 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6472 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6473 r.in.level, nt_errstr(dom_info.out.result));
6474 ret = false;
6475 break;
6476 }
6477 switch (r.in.level) {
6478 case 1:
6479 case 4:
6480 if (info->general.num_users < r.in.start_idx) {
6481 /* On AD deployments this numbers don't match
6482 * since QueryDisplayInfo returns universal and
6483 * global groups, QueryDomainInfo only global
6484 * ones. */
6485 if (torture_setting_bool(tctx, "samba3", false)) {
6486 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6487 r.in.start_idx, info->general.num_groups,
6488 info->general.domain_name.string);
6489 ret = false;
6490 }
6491 }
6492 if (!seen_testuser) {
6493 struct policy_handle user_handle;
6494 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6495 torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6496 info->general.domain_name.string);
6497 ret = false;
6498 test_samr_handle_Close(b, tctx, &user_handle);
6499 }
6500 }
6501 break;
6502 case 3:
6503 case 5:
6504 if (info->general.num_groups != r.in.start_idx) {
6505 /* On AD deployments this numbers don't match
6506 * since QueryDisplayInfo returns universal and
6507 * global groups, QueryDomainInfo only global
6508 * ones. */
6509 if (torture_setting_bool(tctx, "samba3", false)) {
6510 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6511 r.in.start_idx, info->general.num_groups,
6512 info->general.domain_name.string);
6513 ret = false;
6514 }
6515 }
6516
6517 break;
6518 }
6519
6520 }
6521
6522 return ret;
6523}
6524
6525static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6526 struct torture_context *tctx,
6527 struct policy_handle *handle)
6528{
6529 struct samr_QueryDisplayInfo2 r;
6530 bool ret = true;
6531 uint16_t levels[] = {1, 2, 3, 4, 5};
6532 int i;
6533 uint32_t total_size;
6534 uint32_t returned_size;
6535 union samr_DispInfo info;
6536
6537 for (i=0;i<ARRAY_SIZE(levels);i++) {
6538 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6539
6540 r.in.domain_handle = handle;
6541 r.in.level = levels[i];
6542 r.in.start_idx = 0;
6543 r.in.max_entries = 1000;
6544 r.in.buf_size = (uint32_t)-1;
6545 r.out.total_size = &total_size;
6546 r.out.returned_size = &returned_size;
6547 r.out.info = &info;
6548
6549 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6550 "QueryDisplayInfo2 failed");
6551 if (!NT_STATUS_IS_OK(r.out.result)) {
6552 torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6553 levels[i], nt_errstr(r.out.result));
6554 ret = false;
6555 }
6556 }
6557
6558 return ret;
6559}
6560
6561static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6562 struct torture_context *tctx,
6563 struct policy_handle *handle)
6564{
6565 struct samr_QueryDisplayInfo3 r;
6566 bool ret = true;
6567 uint16_t levels[] = {1, 2, 3, 4, 5};
6568 int i;
6569 uint32_t total_size;
6570 uint32_t returned_size;
6571 union samr_DispInfo info;
6572
6573 for (i=0;i<ARRAY_SIZE(levels);i++) {
6574 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6575
6576 r.in.domain_handle = handle;
6577 r.in.level = levels[i];
6578 r.in.start_idx = 0;
6579 r.in.max_entries = 1000;
6580 r.in.buf_size = (uint32_t)-1;
6581 r.out.total_size = &total_size;
6582 r.out.returned_size = &returned_size;
6583 r.out.info = &info;
6584
6585 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6586 "QueryDisplayInfo3 failed");
6587 if (!NT_STATUS_IS_OK(r.out.result)) {
6588 torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6589 levels[i], nt_errstr(r.out.result));
6590 ret = false;
6591 }
6592 }
6593
6594 return ret;
6595}
6596
6597
6598static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6599 struct torture_context *tctx,
6600 struct policy_handle *handle)
6601{
6602 struct samr_QueryDisplayInfo r;
6603 bool ret = true;
6604 uint32_t total_size;
6605 uint32_t returned_size;
6606 union samr_DispInfo info;
6607
6608 torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6609
6610 r.in.domain_handle = handle;
6611 r.in.level = 1;
6612 r.in.start_idx = 0;
6613 r.in.max_entries = 1;
6614 r.in.buf_size = (uint32_t)-1;
6615 r.out.total_size = &total_size;
6616 r.out.returned_size = &returned_size;
6617 r.out.info = &info;
6618
6619 do {
6620 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6621 "QueryDisplayInfo failed");
6622 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6623 if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6624 torture_warning(tctx, "expected idx %d but got %d\n",
6625 r.in.start_idx + 1,
6626 r.out.info->info1.entries[0].idx);
6627 break;
6628 }
6629 }
6630 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6631 !NT_STATUS_IS_OK(r.out.result)) {
6632 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6633 r.in.level, nt_errstr(r.out.result));
6634 ret = false;
6635 break;
6636 }
6637 r.in.start_idx++;
6638 } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6639 NT_STATUS_IS_OK(r.out.result)) &&
6640 *r.out.returned_size != 0);
6641
6642 return ret;
6643}
6644
6645static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6646 struct torture_context *tctx,
6647 struct policy_handle *handle)
6648{
6649 struct samr_QueryDomainInfo r;
6650 union samr_DomainInfo *info = NULL;
6651 struct samr_SetDomainInfo s;
6652 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6653 uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
6654 int i;
6655 bool ret = true;
6656 struct dcerpc_binding_handle *b = p->binding_handle;
6657 const char *domain_comment = talloc_asprintf(tctx,
6658 "Tortured by Samba4 RPC-SAMR: %s",
6659 timestring(tctx, time(NULL)));
6660
6661 s.in.domain_handle = handle;
6662 s.in.level = 4;
6663 s.in.info = talloc(tctx, union samr_DomainInfo);
6664
6665 s.in.info->oem.oem_information.string = domain_comment;
6666 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6667 "SetDomainInfo failed");
6668 if (!NT_STATUS_IS_OK(s.out.result)) {
6669 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6670 s.in.level, nt_errstr(s.out.result));
6671 return false;
6672 }
6673
6674 for (i=0;i<ARRAY_SIZE(levels);i++) {
6675 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6676
6677 r.in.domain_handle = handle;
6678 r.in.level = levels[i];
6679 r.out.info = &info;
6680
6681 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6682 "QueryDomainInfo failed");
6683 if (!NT_STATUS_IS_OK(r.out.result)) {
6684 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6685 r.in.level, nt_errstr(r.out.result));
6686 ret = false;
6687 continue;
6688 }
6689
6690 switch (levels[i]) {
6691 case 2:
6692 if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6693 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6694 levels[i], info->general.oem_information.string, domain_comment);
6695 if (!torture_setting_bool(tctx, "samba3", false)) {
6696 ret = false;
6697 }
6698 }
6699 if (!info->general.primary.string) {
6700 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6701 levels[i]);
6702 ret = false;
6703 } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6704 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6705 if (torture_setting_bool(tctx, "samba3", false)) {
6706 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6707 levels[i], info->general.primary.string, dcerpc_server_name(p));
6708 }
6709 }
6710 }
6711 break;
6712 case 4:
6713 if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6714 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6715 levels[i], info->oem.oem_information.string, domain_comment);
6716 if (!torture_setting_bool(tctx, "samba3", false)) {
6717 ret = false;
6718 }
6719 }
6720 break;
6721 case 6:
6722 if (!info->info6.primary.string) {
6723 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6724 levels[i]);
6725 ret = false;
6726 }
6727 break;
6728 case 11:
6729 if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6730 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6731 levels[i], info->general2.general.oem_information.string, domain_comment);
6732 if (!torture_setting_bool(tctx, "samba3", false)) {
6733 ret = false;
6734 }
6735 }
6736 break;
6737 }
6738
6739 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6740
6741 s.in.domain_handle = handle;
6742 s.in.level = levels[i];
6743 s.in.info = info;
6744
6745 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6746 "SetDomainInfo failed");
6747 if (set_ok[i]) {
6748 if (!NT_STATUS_IS_OK(s.out.result)) {
6749 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6750 r.in.level, nt_errstr(s.out.result));
6751 ret = false;
6752 continue;
6753 }
6754 } else {
6755 if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6756 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6757 r.in.level, nt_errstr(s.out.result));
6758 ret = false;
6759 continue;
6760 }
6761 }
6762
6763 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6764 "QueryDomainInfo failed");
6765 if (!NT_STATUS_IS_OK(r.out.result)) {
6766 torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6767 r.in.level, nt_errstr(r.out.result));
6768 ret = false;
6769 continue;
6770 }
6771 }
6772
6773 return ret;
6774}
6775
6776
6777static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6778 struct torture_context *tctx,
6779 struct policy_handle *handle)
6780{
6781 struct samr_QueryDomainInfo2 r;
6782 union samr_DomainInfo *info = NULL;
6783 uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6784 int i;
6785 bool ret = true;
6786
6787 for (i=0;i<ARRAY_SIZE(levels);i++) {
6788 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6789
6790 r.in.domain_handle = handle;
6791 r.in.level = levels[i];
6792 r.out.info = &info;
6793
6794 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6795 "QueryDomainInfo2 failed");
6796 if (!NT_STATUS_IS_OK(r.out.result)) {
6797 torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6798 r.in.level, nt_errstr(r.out.result));
6799 ret = false;
6800 continue;
6801 }
6802 }
6803
6804 return true;
6805}
6806
6807/* Test whether querydispinfo level 5 and enumdomgroups return the same
6808 set of group names. */
6809static bool test_GroupList(struct dcerpc_binding_handle *b,
6810 struct torture_context *tctx,
6811 struct dom_sid *domain_sid,
6812 struct policy_handle *handle)
6813{
6814 struct samr_EnumDomainGroups q1;
6815 struct samr_QueryDisplayInfo q2;
6816 NTSTATUS status;
6817 uint32_t resume_handle=0;
6818 struct samr_SamArray *sam = NULL;
6819 uint32_t num_entries = 0;
6820 int i;
6821 bool ret = true;
6822 uint32_t total_size;
6823 uint32_t returned_size;
6824 union samr_DispInfo info;
6825
6826 int num_names = 0;
6827 const char **names = NULL;
6828
6829 bool builtin_domain = dom_sid_compare(domain_sid,
6830 &global_sid_Builtin) == 0;
6831
6832 torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6833
6834 q1.in.domain_handle = handle;
6835 q1.in.resume_handle = &resume_handle;
6836 q1.in.max_size = 5;
6837 q1.out.resume_handle = &resume_handle;
6838 q1.out.num_entries = &num_entries;
6839 q1.out.sam = &sam;
6840
6841 status = STATUS_MORE_ENTRIES;
6842 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6843 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6844 "EnumDomainGroups failed");
6845 status = q1.out.result;
6846
6847 if (!NT_STATUS_IS_OK(status) &&
6848 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6849 break;
6850
6851 for (i=0; i<*q1.out.num_entries; i++) {
6852 add_string_to_array(tctx,
6853 sam->entries[i].name.string,
6854 &names, &num_names);
6855 }
6856 }
6857
6858 torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6859
6860 torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6861
6862 if (builtin_domain) {
6863 torture_assert(tctx, num_names == 0,
6864 "EnumDomainGroups shouldn't return any group in the builtin domain!");
6865 }
6866
6867 q2.in.domain_handle = handle;
6868 q2.in.level = 5;
6869 q2.in.start_idx = 0;
6870 q2.in.max_entries = 5;
6871 q2.in.buf_size = (uint32_t)-1;
6872 q2.out.total_size = &total_size;
6873 q2.out.returned_size = &returned_size;
6874 q2.out.info = &info;
6875
6876 status = STATUS_MORE_ENTRIES;
6877 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6878 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6879 "QueryDisplayInfo failed");
6880 status = q2.out.result;
6881 if (!NT_STATUS_IS_OK(status) &&
6882 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6883 break;
6884
6885 for (i=0; i<q2.out.info->info5.count; i++) {
6886 int j;
6887 const char *name = q2.out.info->info5.entries[i].account_name.string;
6888 bool found = false;
6889 for (j=0; j<num_names; j++) {
6890 if (names[j] == NULL)
6891 continue;
6892 if (strequal(names[j], name)) {
6893 names[j] = NULL;
6894 found = true;
6895 break;
6896 }
6897 }
6898
6899 if ((!found) && (!builtin_domain)) {
6900 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
6901 name);
6902 ret = false;
6903 }
6904 }
6905 q2.in.start_idx += q2.out.info->info5.count;
6906 }
6907
6908 if (!NT_STATUS_IS_OK(status)) {
6909 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
6910 nt_errstr(status));
6911 ret = false;
6912 }
6913
6914 if (builtin_domain) {
6915 torture_assert(tctx, q2.in.start_idx != 0,
6916 "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
6917 }
6918
6919 for (i=0; i<num_names; i++) {
6920 if (names[i] != NULL) {
6921 torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
6922 names[i]);
6923 ret = false;
6924 }
6925 }
6926
6927 return ret;
6928}
6929
6930static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
6931 struct torture_context *tctx,
6932 struct policy_handle *group_handle)
6933{
6934 struct samr_DeleteDomainGroup d;
6935
6936 torture_comment(tctx, "Testing DeleteDomainGroup\n");
6937
6938 d.in.group_handle = group_handle;
6939 d.out.group_handle = group_handle;
6940
6941 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
6942 "DeleteDomainGroup failed");
6943 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
6944
6945 return true;
6946}
6947
6948static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
6949 struct torture_context *tctx,
6950 struct policy_handle *domain_handle)
6951{
6952 struct samr_TestPrivateFunctionsDomain r;
6953 bool ret = true;
6954
6955 torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
6956
6957 r.in.domain_handle = domain_handle;
6958
6959 torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
6960 "TestPrivateFunctionsDomain failed");
6961 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
6962
6963 return ret;
6964}
6965
6966static bool test_RidToSid(struct dcerpc_binding_handle *b,
6967 struct torture_context *tctx,
6968 struct dom_sid *domain_sid,
6969 struct policy_handle *domain_handle)
6970{
6971 struct samr_RidToSid r;
6972 bool ret = true;
6973 struct dom_sid *calc_sid, *out_sid;
6974 int rids[] = { 0, 42, 512, 10200 };
6975 int i;
6976
6977 for (i=0;i<ARRAY_SIZE(rids);i++) {
6978 torture_comment(tctx, "Testing RidToSid\n");
6979
6980 calc_sid = dom_sid_dup(tctx, domain_sid);
6981 r.in.domain_handle = domain_handle;
6982 r.in.rid = rids[i];
6983 r.out.sid = &out_sid;
6984
6985 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
6986 "RidToSid failed");
6987 if (!NT_STATUS_IS_OK(r.out.result)) {
6988 torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
6989 ret = false;
6990 } else {
6991 calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
6992
6993 if (!dom_sid_equal(calc_sid, out_sid)) {
6994 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
6995 dom_sid_string(tctx, out_sid),
6996 dom_sid_string(tctx, calc_sid));
6997 ret = false;
6998 }
6999 }
7000 }
7001
7002 return ret;
7003}
7004
7005static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7006 struct torture_context *tctx,
7007 struct policy_handle *domain_handle)
7008{
7009 struct samr_GetBootKeyInformation r;
7010 bool ret = true;
7011 uint32_t unknown = 0;
7012 NTSTATUS status;
7013
7014 torture_comment(tctx, "Testing GetBootKeyInformation\n");
7015
7016 r.in.domain_handle = domain_handle;
7017 r.out.unknown = &unknown;
7018
7019 status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7020 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7021 status = r.out.result;
7022 }
7023 if (!NT_STATUS_IS_OK(status)) {
7024 /* w2k3 seems to fail this sometimes and pass it sometimes */
7025 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7026 }
7027
7028 return ret;
7029}
7030
7031static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7032 struct torture_context *tctx,
7033 struct policy_handle *domain_handle,
7034 struct policy_handle *group_handle)
7035{
7036 NTSTATUS status;
7037 struct samr_AddGroupMember r;
7038 struct samr_DeleteGroupMember d;
7039 struct samr_QueryGroupMember q;
7040 struct samr_RidAttrArray *rids = NULL;
7041 struct samr_SetMemberAttributesOfGroup s;
7042 uint32_t rid;
7043 bool found_member = false;
7044 int i;
7045
7046 status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7047 torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7048
7049 r.in.group_handle = group_handle;
7050 r.in.rid = rid;
7051 r.in.flags = 0; /* ??? */
7052
7053 torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7054
7055 d.in.group_handle = group_handle;
7056 d.in.rid = rid;
7057
7058 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7059 "DeleteGroupMember failed");
7060 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7061
7062 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7063 "AddGroupMember failed");
7064 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7065
7066 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7067 "AddGroupMember failed");
7068 torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7069
7070 if (torture_setting_bool(tctx, "samba4", false) ||
7071 torture_setting_bool(tctx, "samba3", false)) {
7072 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7073 } else {
7074 /* this one is quite strange. I am using random inputs in the
7075 hope of triggering an error that might give us a clue */
7076
7077 s.in.group_handle = group_handle;
7078 s.in.unknown1 = random();
7079 s.in.unknown2 = random();
7080
7081 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7082 "SetMemberAttributesOfGroup failed");
7083 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7084 }
7085
7086 q.in.group_handle = group_handle;
7087 q.out.rids = &rids;
7088
7089 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7090 "QueryGroupMember failed");
7091 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7092 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7093
7094 for (i=0; i < rids->count; i++) {
7095 if (rids->rids[i] == rid) {
7096 found_member = true;
7097 }
7098 }
7099
7100 torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7101
7102 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7103 "DeleteGroupMember failed");
7104 torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7105
7106 rids = NULL;
7107 found_member = false;
7108
7109 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7110 "QueryGroupMember failed");
7111 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7112 torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7113
7114 for (i=0; i < rids->count; i++) {
7115 if (rids->rids[i] == rid) {
7116 found_member = true;
7117 }
7118 }
7119
7120 torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7121
7122 torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7123 "AddGroupMember failed");
7124 torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7125
7126 return true;
7127}
7128
7129
7130static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7131 struct torture_context *tctx,
7132 struct policy_handle *domain_handle,
7133 const char *group_name,
7134 struct policy_handle *group_handle,
7135 struct dom_sid *domain_sid,
7136 bool test_group)
7137{
7138 struct samr_CreateDomainGroup r;
7139 uint32_t rid;
7140 struct lsa_String name;
7141 bool ret = true;
7142
7143 init_lsa_String(&name, group_name);
7144
7145 r.in.domain_handle = domain_handle;
7146 r.in.name = &name;
7147 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7148 r.out.group_handle = group_handle;
7149 r.out.rid = &rid;
7150
7151 torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7152
7153 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7154 "CreateDomainGroup failed");
7155
7156 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7157 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7158 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7159 return true;
7160 } else {
7161 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7162 nt_errstr(r.out.result));
7163 return false;
7164 }
7165 }
7166
7167 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7168 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7169 torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7170 nt_errstr(r.out.result));
7171 return false;
7172 }
7173 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7174 "CreateDomainGroup failed");
7175 }
7176 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7177 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7178
7179 torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7180 nt_errstr(r.out.result));
7181 return false;
7182 }
7183 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7184 "CreateDomainGroup failed");
7185 }
7186 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7187
7188 if (!test_group) {
7189 return ret;
7190 }
7191
7192 if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7193 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7194 ret = false;
7195 }
7196
7197 if (!test_SetGroupInfo(b, tctx, group_handle)) {
7198 ret = false;
7199 }
7200
7201 return ret;
7202}
7203
7204
7205/*
7206 its not totally clear what this does. It seems to accept any sid you like.
7207*/
7208static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7209 struct torture_context *tctx,
7210 struct policy_handle *domain_handle)
7211{
7212 struct samr_RemoveMemberFromForeignDomain r;
7213
7214 r.in.domain_handle = domain_handle;
7215 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7216
7217 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7218 "RemoveMemberFromForeignDomain failed");
7219 torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7220
7221 return true;
7222}
7223
7224static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7225 struct torture_context *tctx,
7226 struct policy_handle *domain_handle,
7227 uint32_t *total_num_entries_p)
7228{
7229 NTSTATUS status;
7230 struct samr_EnumDomainUsers r;
7231 uint32_t resume_handle = 0;
7232 uint32_t num_entries = 0;
7233 uint32_t total_num_entries = 0;
7234 struct samr_SamArray *sam;
7235
7236 r.in.domain_handle = domain_handle;
7237 r.in.acct_flags = 0;
7238 r.in.max_size = (uint32_t)-1;
7239 r.in.resume_handle = &resume_handle;
7240
7241 r.out.sam = &sam;
7242 r.out.num_entries = &num_entries;
7243 r.out.resume_handle = &resume_handle;
7244
7245 torture_comment(tctx, "Testing EnumDomainUsers\n");
7246
7247 do {
7248 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7249 "EnumDomainUsers failed");
7250 if (NT_STATUS_IS_ERR(r.out.result)) {
7251 torture_assert_ntstatus_ok(tctx, r.out.result,
7252 "failed to enumerate users");
7253 }
7254 status = r.out.result;
7255
7256 total_num_entries += num_entries;
7257 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7258
7259 if (total_num_entries_p) {
7260 *total_num_entries_p = total_num_entries;
7261 }
7262
7263 return true;
7264}
7265
7266static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7267 struct torture_context *tctx,
7268 struct policy_handle *domain_handle,
7269 uint32_t *total_num_entries_p)
7270{
7271 NTSTATUS status;
7272 struct samr_EnumDomainGroups r;
7273 uint32_t resume_handle = 0;
7274 uint32_t num_entries = 0;
7275 uint32_t total_num_entries = 0;
7276 struct samr_SamArray *sam;
7277
7278 r.in.domain_handle = domain_handle;
7279 r.in.max_size = (uint32_t)-1;
7280 r.in.resume_handle = &resume_handle;
7281
7282 r.out.sam = &sam;
7283 r.out.num_entries = &num_entries;
7284 r.out.resume_handle = &resume_handle;
7285
7286 torture_comment(tctx, "Testing EnumDomainGroups\n");
7287
7288 do {
7289 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7290 "EnumDomainGroups failed");
7291 if (NT_STATUS_IS_ERR(r.out.result)) {
7292 torture_assert_ntstatus_ok(tctx, r.out.result,
7293 "failed to enumerate groups");
7294 }
7295 status = r.out.result;
7296
7297 total_num_entries += num_entries;
7298 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7299
7300 if (total_num_entries_p) {
7301 *total_num_entries_p = total_num_entries;
7302 }
7303
7304 return true;
7305}
7306
7307static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7308 struct torture_context *tctx,
7309 struct policy_handle *domain_handle,
7310 uint32_t *total_num_entries_p)
7311{
7312 NTSTATUS status;
7313 struct samr_EnumDomainAliases r;
7314 uint32_t resume_handle = 0;
7315 uint32_t num_entries = 0;
7316 uint32_t total_num_entries = 0;
7317 struct samr_SamArray *sam;
7318
7319 r.in.domain_handle = domain_handle;
7320 r.in.max_size = (uint32_t)-1;
7321 r.in.resume_handle = &resume_handle;
7322
7323 r.out.sam = &sam;
7324 r.out.num_entries = &num_entries;
7325 r.out.resume_handle = &resume_handle;
7326
7327 torture_comment(tctx, "Testing EnumDomainAliases\n");
7328
7329 do {
7330 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7331 "EnumDomainAliases failed");
7332 if (NT_STATUS_IS_ERR(r.out.result)) {
7333 torture_assert_ntstatus_ok(tctx, r.out.result,
7334 "failed to enumerate aliases");
7335 }
7336 status = r.out.result;
7337
7338 total_num_entries += num_entries;
7339 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7340
7341 if (total_num_entries_p) {
7342 *total_num_entries_p = total_num_entries;
7343 }
7344
7345 return true;
7346}
7347
7348static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7349 struct torture_context *tctx,
7350 struct policy_handle *handle,
7351 uint16_t level,
7352 uint32_t *total_num_entries_p)
7353{
7354 NTSTATUS status;
7355 struct samr_QueryDisplayInfo r;
7356 uint32_t total_num_entries = 0;
7357
7358 r.in.domain_handle = handle;
7359 r.in.level = level;
7360 r.in.start_idx = 0;
7361 r.in.max_entries = (uint32_t)-1;
7362 r.in.buf_size = (uint32_t)-1;
7363
7364 torture_comment(tctx, "Testing QueryDisplayInfo\n");
7365
7366 do {
7367 uint32_t total_size;
7368 uint32_t returned_size;
7369 union samr_DispInfo info;
7370
7371 r.out.total_size = &total_size;
7372 r.out.returned_size = &returned_size;
7373 r.out.info = &info;
7374
7375 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7376 "failed to query displayinfo");
7377 if (NT_STATUS_IS_ERR(r.out.result)) {
7378 torture_assert_ntstatus_ok(tctx, r.out.result,
7379 "failed to query displayinfo");
7380 }
7381 status = r.out.result;
7382
7383 if (*r.out.returned_size == 0) {
7384 break;
7385 }
7386
7387 switch (r.in.level) {
7388 case 1:
7389 total_num_entries += info.info1.count;
7390 r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7391 break;
7392 case 2:
7393 total_num_entries += info.info2.count;
7394 r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7395 break;
7396 case 3:
7397 total_num_entries += info.info3.count;
7398 r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7399 break;
7400 case 4:
7401 total_num_entries += info.info4.count;
7402 r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7403 break;
7404 case 5:
7405 total_num_entries += info.info5.count;
7406 r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7407 break;
7408 default:
7409 return false;
7410 }
7411
7412 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7413
7414 if (total_num_entries_p) {
7415 *total_num_entries_p = total_num_entries;
7416 }
7417
7418 return true;
7419}
7420
7421static bool test_ManyObjects(struct dcerpc_pipe *p,
7422 struct torture_context *tctx,
7423 struct policy_handle *domain_handle,
7424 struct dom_sid *domain_sid,
7425 struct torture_samr_context *ctx)
7426{
7427 uint32_t num_total = ctx->num_objects_large_dc;
7428 uint32_t num_enum = 0;
7429 uint32_t num_disp = 0;
7430 uint32_t num_created = 0;
7431 uint32_t num_anounced = 0;
7432 uint32_t i;
7433 struct dcerpc_binding_handle *b = p->binding_handle;
7434
7435 struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7436
7437 /* query */
7438
7439 {
7440 struct samr_QueryDomainInfo2 r;
7441 union samr_DomainInfo *info;
7442 r.in.domain_handle = domain_handle;
7443 r.in.level = 2;
7444 r.out.info = &info;
7445
7446 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7447 "QueryDomainInfo2 failed");
7448 torture_assert_ntstatus_ok(tctx, r.out.result,
7449 "failed to query domain info");
7450
7451 switch (ctx->choice) {
7452 case TORTURE_SAMR_MANY_ACCOUNTS:
7453 num_anounced = info->general.num_users;
7454 break;
7455 case TORTURE_SAMR_MANY_GROUPS:
7456 num_anounced = info->general.num_groups;
7457 break;
7458 case TORTURE_SAMR_MANY_ALIASES:
7459 num_anounced = info->general.num_aliases;
7460 break;
7461 default:
7462 return false;
7463 }
7464 }
7465
7466 /* create */
7467
7468 for (i=0; i < num_total; i++) {
7469
7470 const char *name = NULL;
7471
7472 switch (ctx->choice) {
7473 case TORTURE_SAMR_MANY_ACCOUNTS:
7474 name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7475 torture_assert(tctx,
7476 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7477 "failed to create user");
7478 break;
7479 case TORTURE_SAMR_MANY_GROUPS:
7480 name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7481 torture_assert(tctx,
7482 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7483 "failed to create group");
7484 break;
7485 case TORTURE_SAMR_MANY_ALIASES:
7486 name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7487 torture_assert(tctx,
7488 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7489 "failed to create alias");
7490 break;
7491 default:
7492 return false;
7493 }
7494 if (!policy_handle_empty(&handles[i])) {
7495 num_created++;
7496 }
7497 }
7498
7499 /* enum */
7500
7501 switch (ctx->choice) {
7502 case TORTURE_SAMR_MANY_ACCOUNTS:
7503 torture_assert(tctx,
7504 test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7505 "failed to enum users");
7506 break;
7507 case TORTURE_SAMR_MANY_GROUPS:
7508 torture_assert(tctx,
7509 test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7510 "failed to enum groups");
7511 break;
7512 case TORTURE_SAMR_MANY_ALIASES:
7513 torture_assert(tctx,
7514 test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7515 "failed to enum aliases");
7516 break;
7517 default:
7518 return false;
7519 }
7520
7521 /* dispinfo */
7522
7523 switch (ctx->choice) {
7524 case TORTURE_SAMR_MANY_ACCOUNTS:
7525 torture_assert(tctx,
7526 test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7527 "failed to query display info");
7528 break;
7529 case TORTURE_SAMR_MANY_GROUPS:
7530 torture_assert(tctx,
7531 test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7532 "failed to query display info");
7533 break;
7534 case TORTURE_SAMR_MANY_ALIASES:
7535 /* no aliases in dispinfo */
7536 break;
7537 default:
7538 return false;
7539 }
7540
7541 /* close or delete */
7542
7543 for (i=0; i < num_total; i++) {
7544
7545 if (policy_handle_empty(&handles[i])) {
7546 continue;
7547 }
7548
7549 if (torture_setting_bool(tctx, "samba3", false)) {
7550 torture_assert(tctx,
7551 test_samr_handle_Close(b, tctx, &handles[i]),
7552 "failed to close handle");
7553 } else {
7554 switch (ctx->choice) {
7555 case TORTURE_SAMR_MANY_ACCOUNTS:
7556 torture_assert(tctx,
7557 test_DeleteUser(b, tctx, &handles[i]),
7558 "failed to delete user");
7559 break;
7560 case TORTURE_SAMR_MANY_GROUPS:
7561 torture_assert(tctx,
7562 test_DeleteDomainGroup(b, tctx, &handles[i]),
7563 "failed to delete group");
7564 break;
7565 case TORTURE_SAMR_MANY_ALIASES:
7566 torture_assert(tctx,
7567 test_DeleteAlias(b, tctx, &handles[i]),
7568 "failed to delete alias");
7569 break;
7570 default:
7571 return false;
7572 }
7573 }
7574 }
7575
7576 talloc_free(handles);
7577
7578 if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7579 torture_comment(tctx,
7580 "unexpected number of results (%u) returned in enum call, expected %u\n",
7581 num_enum, num_anounced + num_created);
7582
7583 torture_comment(tctx,
7584 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7585 num_disp, num_anounced + num_created);
7586 }
7587
7588 return true;
7589}
7590
7591static bool test_Connect(struct dcerpc_binding_handle *b,
7592 struct torture_context *tctx,
7593 struct policy_handle *handle);
7594
7595static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7596 struct torture_samr_context *ctx, struct dom_sid *sid)
7597{
7598 struct samr_OpenDomain r;
7599 struct policy_handle domain_handle;
7600 struct policy_handle alias_handle;
7601 struct policy_handle user_handle;
7602 struct policy_handle group_handle;
7603 bool ret = true;
7604 struct dcerpc_binding_handle *b = p->binding_handle;
7605
7606 ZERO_STRUCT(alias_handle);
7607 ZERO_STRUCT(user_handle);
7608 ZERO_STRUCT(group_handle);
7609 ZERO_STRUCT(domain_handle);
7610
7611 torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7612
7613 r.in.connect_handle = &ctx->handle;
7614 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7615 r.in.sid = sid;
7616 r.out.domain_handle = &domain_handle;
7617
7618 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7619 "OpenDomain failed");
7620 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7621
7622 /* run the domain tests with the main handle closed - this tests
7623 the servers reference counting */
7624 torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7625
7626 switch (ctx->choice) {
7627 case TORTURE_SAMR_PASSWORDS:
7628 case TORTURE_SAMR_USER_PRIVILEGES:
7629 if (!torture_setting_bool(tctx, "samba3", false)) {
7630 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7631 }
7632 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7633 if (!ret) {
7634 torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7635 }
7636 break;
7637 case TORTURE_SAMR_USER_ATTRIBUTES:
7638 if (!torture_setting_bool(tctx, "samba3", false)) {
7639 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7640 }
7641 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7642 /* This test needs 'complex' users to validate */
7643 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7644 if (!ret) {
7645 torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7646 }
7647 break;
7648 case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7649 case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7650 case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7651 if (!torture_setting_bool(tctx, "samba3", false)) {
7652 ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7653 }
7654 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7655 if (!ret) {
7656 torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7657 }
7658 break;
7659 case TORTURE_SAMR_MANY_ACCOUNTS:
7660 case TORTURE_SAMR_MANY_GROUPS:
7661 case TORTURE_SAMR_MANY_ALIASES:
7662 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7663 if (!ret) {
7664 torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7665 }
7666 break;
7667 case TORTURE_SAMR_OTHER:
7668 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7669 if (!ret) {
7670 torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7671 }
7672 if (!torture_setting_bool(tctx, "samba3", false)) {
7673 ret &= test_QuerySecurity(b, tctx, &domain_handle);
7674 }
7675 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7676 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7677 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7678 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7679 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7680 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7681 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7682 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7683 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7684 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7685 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7686 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7687 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7688
7689 if (torture_setting_bool(tctx, "samba4", false)) {
7690 torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7691 } else {
7692 ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7693 ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7694 }
7695 ret &= test_GroupList(b, tctx, sid, &domain_handle);
7696 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7697 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7698 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7699 if (!ret) {
7700 torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7701 }
7702 break;
7703 }
7704
7705 if (!policy_handle_empty(&user_handle) &&
7706 !test_DeleteUser(b, tctx, &user_handle)) {
7707 ret = false;
7708 }
7709
7710 if (!policy_handle_empty(&alias_handle) &&
7711 !test_DeleteAlias(b, tctx, &alias_handle)) {
7712 ret = false;
7713 }
7714
7715 if (!policy_handle_empty(&group_handle) &&
7716 !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7717 ret = false;
7718 }
7719
7720 torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7721
7722 torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7723 /* reconnect the main handle */
7724
7725 if (!ret) {
7726 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7727 }
7728
7729 return ret;
7730}
7731
7732static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7733 struct torture_samr_context *ctx, const char *domain)
7734{
7735 struct samr_LookupDomain r;
7736 struct dom_sid2 *sid = NULL;
7737 struct lsa_String n1;
7738 struct lsa_String n2;
7739 bool ret = true;
7740 struct dcerpc_binding_handle *b = p->binding_handle;
7741
7742 torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7743
7744 /* check for correct error codes */
7745 r.in.connect_handle = &ctx->handle;
7746 r.in.domain_name = &n2;
7747 r.out.sid = &sid;
7748 n2.string = NULL;
7749
7750 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7751 "LookupDomain failed");
7752 torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7753
7754 init_lsa_String(&n2, "xxNODOMAINxx");
7755
7756 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7757 "LookupDomain failed");
7758 torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7759
7760 r.in.connect_handle = &ctx->handle;
7761
7762 init_lsa_String(&n1, domain);
7763 r.in.domain_name = &n1;
7764
7765 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7766 "LookupDomain failed");
7767 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7768
7769 if (!test_GetDomPwInfo(p, tctx, &n1)) {
7770 ret = false;
7771 }
7772
7773 if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7774 ret = false;
7775 }
7776
7777 return ret;
7778}
7779
7780
7781static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7782 struct torture_samr_context *ctx)
7783{
7784 struct samr_EnumDomains r;
7785 uint32_t resume_handle = 0;
7786 uint32_t num_entries = 0;
7787 struct samr_SamArray *sam = NULL;
7788 int i;
7789 bool ret = true;
7790 struct dcerpc_binding_handle *b = p->binding_handle;
7791
7792 r.in.connect_handle = &ctx->handle;
7793 r.in.resume_handle = &resume_handle;
7794 r.in.buf_size = (uint32_t)-1;
7795 r.out.resume_handle = &resume_handle;
7796 r.out.num_entries = &num_entries;
7797 r.out.sam = &sam;
7798
7799 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7800 "EnumDomains failed");
7801 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7802
7803 if (!*r.out.sam) {
7804 return false;
7805 }
7806
7807 for (i=0;i<sam->count;i++) {
7808 if (!test_LookupDomain(p, tctx, ctx,
7809 sam->entries[i].name.string)) {
7810 ret = false;
7811 }
7812 }
7813
7814 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7815 "EnumDomains failed");
7816 torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7817
7818 return ret;
7819}
7820
7821
7822static bool test_Connect(struct dcerpc_binding_handle *b,
7823 struct torture_context *tctx,
7824 struct policy_handle *handle)
7825{
7826 struct samr_Connect r;
7827 struct samr_Connect2 r2;
7828 struct samr_Connect3 r3;
7829 struct samr_Connect4 r4;
7830 struct samr_Connect5 r5;
7831 union samr_ConnectInfo info;
7832 struct policy_handle h;
7833 uint32_t level_out = 0;
7834 bool ret = true, got_handle = false;
7835
7836 torture_comment(tctx, "Testing samr_Connect\n");
7837
7838 r.in.system_name = 0;
7839 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7840 r.out.connect_handle = &h;
7841
7842 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7843 "Connect failed");
7844 if (!NT_STATUS_IS_OK(r.out.result)) {
7845 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7846 ret = false;
7847 } else {
7848 got_handle = true;
7849 *handle = h;
7850 }
7851
7852 torture_comment(tctx, "Testing samr_Connect2\n");
7853
7854 r2.in.system_name = NULL;
7855 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7856 r2.out.connect_handle = &h;
7857
7858 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7859 "Connect2 failed");
7860 if (!NT_STATUS_IS_OK(r2.out.result)) {
7861 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7862 ret = false;
7863 } else {
7864 if (got_handle) {
7865 test_samr_handle_Close(b, tctx, handle);
7866 }
7867 got_handle = true;
7868 *handle = h;
7869 }
7870
7871 torture_comment(tctx, "Testing samr_Connect3\n");
7872
7873 r3.in.system_name = NULL;
7874 r3.in.unknown = 0;
7875 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7876 r3.out.connect_handle = &h;
7877
7878 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7879 "Connect3 failed");
7880 if (!NT_STATUS_IS_OK(r3.out.result)) {
7881 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
7882 ret = false;
7883 } else {
7884 if (got_handle) {
7885 test_samr_handle_Close(b, tctx, handle);
7886 }
7887 got_handle = true;
7888 *handle = h;
7889 }
7890
7891 torture_comment(tctx, "Testing samr_Connect4\n");
7892
7893 r4.in.system_name = "";
7894 r4.in.client_version = 0;
7895 r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7896 r4.out.connect_handle = &h;
7897
7898 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
7899 "Connect4 failed");
7900 if (!NT_STATUS_IS_OK(r4.out.result)) {
7901 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
7902 ret = false;
7903 } else {
7904 if (got_handle) {
7905 test_samr_handle_Close(b, tctx, handle);
7906 }
7907 got_handle = true;
7908 *handle = h;
7909 }
7910
7911 torture_comment(tctx, "Testing samr_Connect5\n");
7912
7913 info.info1.client_version = 0;
7914 info.info1.unknown2 = 0;
7915
7916 r5.in.system_name = "";
7917 r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7918 r5.in.level_in = 1;
7919 r5.out.level_out = &level_out;
7920 r5.in.info_in = &info;
7921 r5.out.info_out = &info;
7922 r5.out.connect_handle = &h;
7923
7924 torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
7925 "Connect5 failed");
7926 if (!NT_STATUS_IS_OK(r5.out.result)) {
7927 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
7928 ret = false;
7929 } else {
7930 if (got_handle) {
7931 test_samr_handle_Close(b, tctx, handle);
7932 }
7933 got_handle = true;
7934 *handle = h;
7935 }
7936
7937 return ret;
7938}
7939
7940
7941static bool test_samr_ValidatePassword(struct torture_context *tctx,
7942 struct dcerpc_pipe *p)
7943{
7944 struct samr_ValidatePassword r;
7945 union samr_ValidatePasswordReq req;
7946 union samr_ValidatePasswordRep *repp = NULL;
7947 NTSTATUS status;
7948 const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
7949 int i;
7950 struct dcerpc_binding_handle *b = p->binding_handle;
7951
7952 torture_comment(tctx, "Testing samr_ValidatePassword\n");
7953
7954 if (p->conn->transport.transport != NCACN_IP_TCP) {
7955 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
7956 }
7957
7958 ZERO_STRUCT(r);
7959 r.in.level = NetValidatePasswordReset;
7960 r.in.req = &req;
7961 r.out.rep = &repp;
7962
7963 ZERO_STRUCT(req);
7964 req.req3.account.string = "non-existant-account-aklsdji";
7965
7966 for (i=0; passwords[i]; i++) {
7967 req.req3.password.string = passwords[i];
7968
7969 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
7970 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
7971 torture_skip(tctx, "ValidatePassword not supported by server\n");
7972 }
7973 torture_assert_ntstatus_ok(tctx, status,
7974 "samr_ValidatePassword failed");
7975 torture_assert_ntstatus_ok(tctx, r.out.result,
7976 "samr_ValidatePassword failed");
7977 torture_comment(tctx, "Server %s password '%s' with code %i\n",
7978 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
7979 req.req3.password.string, repp->ctr3.status);
7980 }
7981
7982 return true;
7983}
7984
7985bool torture_rpc_samr(struct torture_context *torture)
7986{
7987 NTSTATUS status;
7988 struct dcerpc_pipe *p;
7989 bool ret = true;
7990 struct torture_samr_context *ctx;
7991 struct dcerpc_binding_handle *b;
7992
7993 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7994 if (!NT_STATUS_IS_OK(status)) {
7995 return false;
7996 }
7997 b = p->binding_handle;
7998
7999 ctx = talloc_zero(torture, struct torture_samr_context);
8000
8001 ctx->choice = TORTURE_SAMR_OTHER;
8002
8003 ret &= test_Connect(b, torture, &ctx->handle);
8004
8005 if (!torture_setting_bool(torture, "samba3", false)) {
8006 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8007 }
8008
8009 ret &= test_EnumDomains(p, torture, ctx);
8010
8011 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8012
8013 ret &= test_Shutdown(b, torture, &ctx->handle);
8014
8015 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8016
8017 return ret;
8018}
8019
8020
8021bool torture_rpc_samr_users(struct torture_context *torture)
8022{
8023 NTSTATUS status;
8024 struct dcerpc_pipe *p;
8025 bool ret = true;
8026 struct torture_samr_context *ctx;
8027 struct dcerpc_binding_handle *b;
8028
8029 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8030 if (!NT_STATUS_IS_OK(status)) {
8031 return false;
8032 }
8033 b = p->binding_handle;
8034
8035 ctx = talloc_zero(torture, struct torture_samr_context);
8036
8037 ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8038
8039 ret &= test_Connect(b, torture, &ctx->handle);
8040
8041 if (!torture_setting_bool(torture, "samba3", false)) {
8042 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8043 }
8044
8045 ret &= test_EnumDomains(p, torture, ctx);
8046
8047 ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8048
8049 ret &= test_Shutdown(b, torture, &ctx->handle);
8050
8051 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8052
8053 return ret;
8054}
8055
8056
8057bool torture_rpc_samr_passwords(struct torture_context *torture)
8058{
8059 NTSTATUS status;
8060 struct dcerpc_pipe *p;
8061 bool ret = true;
8062 struct torture_samr_context *ctx;
8063 struct dcerpc_binding_handle *b;
8064
8065 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8066 if (!NT_STATUS_IS_OK(status)) {
8067 return false;
8068 }
8069 b = p->binding_handle;
8070
8071 ctx = talloc_zero(torture, struct torture_samr_context);
8072
8073 ctx->choice = TORTURE_SAMR_PASSWORDS;
8074
8075 ret &= test_Connect(b, torture, &ctx->handle);
8076
8077 ret &= test_EnumDomains(p, torture, ctx);
8078
8079 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8080
8081 return ret;
8082}
8083
8084static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8085 struct dcerpc_pipe *p2,
8086 struct cli_credentials *machine_credentials)
8087{
8088 NTSTATUS status;
8089 struct dcerpc_pipe *p;
8090 bool ret = true;
8091 struct torture_samr_context *ctx;
8092 struct dcerpc_binding_handle *b;
8093
8094 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8095 if (!NT_STATUS_IS_OK(status)) {
8096 return false;
8097 }
8098 b = p->binding_handle;
8099
8100 ctx = talloc_zero(torture, struct torture_samr_context);
8101
8102 ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8103 ctx->machine_credentials = machine_credentials;
8104
8105 ret &= test_Connect(b, torture, &ctx->handle);
8106
8107 ret &= test_EnumDomains(p, torture, ctx);
8108
8109 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8110
8111 return ret;
8112}
8113
8114struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8115{
8116 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8117 struct torture_rpc_tcase *tcase;
8118
8119 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8120 &ndr_table_samr,
8121 TEST_ACCOUNT_NAME_PWD);
8122
8123 torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8124 torture_rpc_samr_pwdlastset);
8125
8126 return suite;
8127}
8128
8129static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8130 struct dcerpc_pipe *p2,
8131 struct cli_credentials *machine_credentials)
8132{
8133 NTSTATUS status;
8134 struct dcerpc_pipe *p;
8135 bool ret = true;
8136 struct torture_samr_context *ctx;
8137 struct dcerpc_binding_handle *b;
8138
8139 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8140 if (!NT_STATUS_IS_OK(status)) {
8141 return false;
8142 }
8143 b = p->binding_handle;
8144
8145 ctx = talloc_zero(torture, struct torture_samr_context);
8146
8147 ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8148 ctx->machine_credentials = machine_credentials;
8149
8150 ret &= test_Connect(b, torture, &ctx->handle);
8151
8152 ret &= test_EnumDomains(p, torture, ctx);
8153
8154 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8155
8156 return ret;
8157}
8158
8159struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8160{
8161 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8162 struct torture_rpc_tcase *tcase;
8163
8164 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8165 &ndr_table_samr,
8166 TEST_ACCOUNT_NAME_PWD);
8167
8168 torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8169 torture_rpc_samr_users_privileges_delete_user);
8170
8171 return suite;
8172}
8173
8174static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8175 struct dcerpc_pipe *p2,
8176 void *data)
8177{
8178 NTSTATUS status;
8179 struct dcerpc_pipe *p;
8180 bool ret = true;
8181 struct torture_samr_context *ctx =
8182 talloc_get_type_abort(data, struct torture_samr_context);
8183 struct dcerpc_binding_handle *b;
8184
8185 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8186 if (!NT_STATUS_IS_OK(status)) {
8187 return false;
8188 }
8189 b = p->binding_handle;
8190
8191 ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8192 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8193 ctx->num_objects_large_dc);
8194
8195 ret &= test_Connect(b, torture, &ctx->handle);
8196
8197 ret &= test_EnumDomains(p, torture, ctx);
8198
8199 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8200
8201 return ret;
8202}
8203
8204static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8205 struct dcerpc_pipe *p2,
8206 void *data)
8207{
8208 NTSTATUS status;
8209 struct dcerpc_pipe *p;
8210 bool ret = true;
8211 struct torture_samr_context *ctx =
8212 talloc_get_type_abort(data, struct torture_samr_context);
8213 struct dcerpc_binding_handle *b;
8214
8215 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8216 if (!NT_STATUS_IS_OK(status)) {
8217 return false;
8218 }
8219 b = p->binding_handle;
8220
8221 ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8222 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8223 ctx->num_objects_large_dc);
8224
8225 ret &= test_Connect(b, torture, &ctx->handle);
8226
8227 ret &= test_EnumDomains(p, torture, ctx);
8228
8229 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8230
8231 return ret;
8232}
8233
8234static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8235 struct dcerpc_pipe *p2,
8236 void *data)
8237{
8238 NTSTATUS status;
8239 struct dcerpc_pipe *p;
8240 bool ret = true;
8241 struct torture_samr_context *ctx =
8242 talloc_get_type_abort(data, struct torture_samr_context);
8243 struct dcerpc_binding_handle *b;
8244
8245 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8246 if (!NT_STATUS_IS_OK(status)) {
8247 return false;
8248 }
8249 b = p->binding_handle;
8250
8251 ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8252 ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8253 ctx->num_objects_large_dc);
8254
8255 ret &= test_Connect(b, torture, &ctx->handle);
8256
8257 ret &= test_EnumDomains(p, torture, ctx);
8258
8259 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8260
8261 return ret;
8262}
8263
8264struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8265{
8266 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8267 struct torture_rpc_tcase *tcase;
8268 struct torture_samr_context *ctx;
8269
8270 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8271
8272 ctx = talloc_zero(suite, struct torture_samr_context);
8273 ctx->num_objects_large_dc = 150;
8274
8275 torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8276 torture_rpc_samr_many_aliases, ctx);
8277 torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8278 torture_rpc_samr_many_groups, ctx);
8279 torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8280 torture_rpc_samr_many_accounts, ctx);
8281
8282 return suite;
8283}
8284
8285static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8286 struct dcerpc_pipe *p2,
8287 struct cli_credentials *machine_credentials)
8288{
8289 NTSTATUS status;
8290 struct dcerpc_pipe *p;
8291 bool ret = true;
8292 struct torture_samr_context *ctx;
8293 struct dcerpc_binding_handle *b;
8294
8295 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8296 if (!NT_STATUS_IS_OK(status)) {
8297 return false;
8298 }
8299 b = p->binding_handle;
8300
8301 ctx = talloc_zero(torture, struct torture_samr_context);
8302
8303 ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8304 ctx->machine_credentials = machine_credentials;
8305
8306 ret &= test_Connect(b, torture, &ctx->handle);
8307
8308 ret &= test_EnumDomains(p, torture, ctx);
8309
8310 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8311
8312 return ret;
8313}
8314
8315struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8316{
8317 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8318 struct torture_rpc_tcase *tcase;
8319
8320 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8321 &ndr_table_samr,
8322 TEST_ACCOUNT_NAME_PWD);
8323
8324 torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8325 torture_rpc_samr_badpwdcount);
8326
8327 return suite;
8328}
8329
8330static bool torture_rpc_samr_lockout(struct torture_context *torture,
8331 struct dcerpc_pipe *p2,
8332 struct cli_credentials *machine_credentials)
8333{
8334 NTSTATUS status;
8335 struct dcerpc_pipe *p;
8336 bool ret = true;
8337 struct torture_samr_context *ctx;
8338 struct dcerpc_binding_handle *b;
8339
8340 status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8341 if (!NT_STATUS_IS_OK(status)) {
8342 return false;
8343 }
8344 b = p->binding_handle;
8345
8346 ctx = talloc_zero(torture, struct torture_samr_context);
8347
8348 ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8349 ctx->machine_credentials = machine_credentials;
8350
8351 ret &= test_Connect(b, torture, &ctx->handle);
8352
8353 ret &= test_EnumDomains(p, torture, ctx);
8354
8355 ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8356
8357 return ret;
8358}
8359
8360struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8361{
8362 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8363 struct torture_rpc_tcase *tcase;
8364
8365 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8366 &ndr_table_samr,
8367 TEST_ACCOUNT_NAME_PWD);
8368
8369 torture_rpc_tcase_add_test_creds(tcase, "lockout",
8370 torture_rpc_samr_lockout);
8371
8372 return suite;
8373}
8374
8375struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8376{
8377 struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8378 struct torture_rpc_tcase *tcase;
8379
8380 tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8381 &ndr_table_samr);
8382 torture_rpc_tcase_add_test(tcase, "validate",
8383 test_samr_ValidatePassword);
8384
8385 return suite;
8386}
Note: See TracBrowser for help on using the repository browser.