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