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